Wiki/Home.md is the suite's front door; every layer's wiki now mirrors here under Wiki/<layer>/ (core, contraband, justice, gangs, ward), so the whole suite reads in one place with the index linking to the local pages. The layer repos stay canonical -- Tools/sync-wiki.sh refreshes the aggregated copy on demand. The README's main page points to it.
121 lines
6.4 KiB
Markdown
121 lines
6.4 KiB
Markdown
# Networks and smuggling
|
|
|
|
*The one thing nothing else models: contraband that flows **between** pawns. A gang is a supply chain.*
|
|
|
|
This is the core of the mod. Everything else — who joins, who fights, who is kept apart — exists to
|
|
serve or to break the network described here. A gang is not a mood aura; it is a **logistics graph**,
|
|
and its edges carry contraband.
|
|
|
|
## The move
|
|
|
|
The heart of it is one method, `MoveWithin(from, to)`: a gangmate who is holding a stash passes a piece
|
|
of it to a gangmate who has none. It returns `true` if something actually moved.
|
|
|
|
```
|
|
MoveWithin(from, to):
|
|
1. both non-null, and SameGang(from, to) -- else false
|
|
2. if both are Spawned: from must CanReach(to, -- the reach gate
|
|
PathEndMode.Touch, Danger.Deadly) -- else false
|
|
3. a Contraband tracker must exist on the map -- else false
|
|
4. 'from' must have at least one concealed item -- else false
|
|
5. take stash[0]:
|
|
tracker.Confiscate(from, item.def) -- leaves the supplier's hands
|
|
tracker.Conceal(to, item.def) -- arrives, hidden, in the customer's
|
|
return true
|
|
```
|
|
|
|
A few things worth reading carefully:
|
|
|
|
- **One item per move.** It takes `stash[0]` — the first concealed item on the supplier — and moves
|
|
exactly that. It is a redistribution, not a duplication: the item leaves `from` (`Confiscate`) and
|
|
arrives concealed on `to` (`Conceal`). The gang's total stash is unchanged; only *who holds it*
|
|
changes.
|
|
- **Same gang, always.** `SameGang` requires both pawns to hold the same non-zero gang id. There is no
|
|
smuggling to a stranger — the network only moves along membership.
|
|
- **The reach gate only applies to co-located pawns.** The `CanReach` check is guarded by
|
|
`from.Spawned && to.Spawned`. Two pawns both physically on the map must have a walkable path
|
|
(`Touch` range, willing to cross `Deadly` danger) between them. If a member is not spawned, the
|
|
reach check is skipped — which is what allows a gang to reach across the wall to a member who is off
|
|
the active map.
|
|
|
|
## Why this defeats a single search
|
|
|
|
Consider a wing of four gangmates and one shiv. You search Prisoner A and find nothing — clean. You
|
|
tick a box: *cell searched, no contraband.* But the shiv was on Prisoner C the whole time, and on the
|
|
next 5000-tick network pass it will move to whoever is out. Search C tomorrow and it may already be on
|
|
A again.
|
|
|
|
From the source comment, plainly:
|
|
|
|
> A gangmate holding a stash supplies one who has none, so a search that turns up nothing on one
|
|
> prisoner has not cleaned out the wing.
|
|
|
|
A single search is a snapshot of one node in a graph that reshuffles itself. This is the whole reason
|
|
contraband-as-a-network is worth modelling: **the unit of contraband is the wing, not the pawn.** To
|
|
clean it out you have to either search faster than it moves, or — far better — break the graph.
|
|
|
|
## The automatic resupply pass
|
|
|
|
You do not call `MoveWithin` by hand; the gang component does it on the 5000-tick check. After forming
|
|
gangs for the pass, it runs one resupply round **per gang**:
|
|
|
|
```
|
|
for each gang among the eligible crew:
|
|
holder = first member who IS hiding contraband
|
|
needy = first member who is NOT hiding contraband
|
|
if holder and needy both exist:
|
|
MoveWithin(holder, needy)
|
|
```
|
|
|
|
So on each interval, every gang that has both a haves-member and a have-not-member performs **one**
|
|
transfer, moving a single item from a holder to someone empty-handed. Over several ticks the effect is
|
|
that a gang tends to keep its members supplied and to spread a stash out — which is exactly what makes
|
|
a scattershot search miss it. (Only members who currently meet the join bar participate in this
|
|
automatic pass; the resupply loop draws from the same `crew` used for formation.)
|
|
|
|
## The cross-wall move
|
|
|
|
Because `WouldJoin` and `SameGang` care nothing about a pawn's secured status, a gang can have a
|
|
**free** member and a **held** member. If the free member is holding the stash, the network resupplies
|
|
*into* the prison — the outside man passes to the inside man. The mod's integration test builds exactly
|
|
this: a free psychopath colonist and a prisoner in one gang, the stash on the free member, and
|
|
`MoveWithin(free, prisoner)` succeeds — after which the prisoner is hiding contraband and the free
|
|
colonist is not. Your prison's contraband problem is not sealed inside your prison.
|
|
|
|
## Resupply from outside: the bent warden
|
|
|
|
`MoveWithin` only *redistributes* what a gang already has. So what happens when you finally search the
|
|
whole wing on the same day and strip every member clean — the graph has no more edges to carry? The
|
|
gang is starved. It stays starved until contraband **re-enters** from outside.
|
|
|
|
That external source is not part of Gangs; it is **Institution: Contraband's** corruption route. A
|
|
warden's honesty varies by personality (a Greedy warden has a price), and a bent warden can *smuggle
|
|
contraband in to a prisoner* — `Corruption.Smuggle(warden, prisoner, tracker)` plants a concealed item
|
|
directly. That single seeded item is then all the network needs: one holder, and the 5000-tick pass
|
|
spreads it back out across everyone who can reach.
|
|
|
|
So the two halves of the supply picture are:
|
|
|
|
| Mechanism | Owner | What it does |
|
|
|---|---|---|
|
|
| `MoveWithin` | **Gangs** | moves existing contraband *between* gangmates who can reach each other |
|
|
| `Corruption.Smuggle` | **Contraband** | injects *new* contraband from outside via a corruptible warden |
|
|
|
|
Cut both and a gang genuinely dries up. Cut only the redistribution and a bent warden re-seeds it; cut
|
|
only the warden and any stash you missed keeps circulating.
|
|
|
|
## How to break a network
|
|
|
|
- **Search the whole wing at once**, not one pawn at a time. A partial sweep is a snapshot the network
|
|
routes around.
|
|
- **Segregate rivals into different, unreachable wings** (Classification, in Institution: Justice). The
|
|
reach gate is the lever — a network whose members cannot walk to each other cannot pass anything.
|
|
This is the primary counter-play; see
|
|
[Affiliations and Segregation](Affiliations-and-Segregation.md).
|
|
- **Clean up your wardens.** If searches never seem to finish the job, you may have a Greedy warden
|
|
re-seeding the wing. Corruption is the resupply valve; personality is the fix.
|
|
|
|
---
|
|
*Part of the **Institution** suite — Core · Contraband · Justice · Gangs (this). Each mod stands alone; together they are one system.*
|
|
*AI disclosure: developed with substantial assistance from Claude (Anthropic).*
|