Aggregate the whole suite wiki onto the Institution page

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.
This commit is contained in:
flan
2026-07-15 20:30:38 +00:00
parent 25eb3a77db
commit 3530100ed5
31 changed files with 4574 additions and 6 deletions
+128
View File
@@ -0,0 +1,128 @@
# Compatibility
*Contraband ships zero Harmony patches. It adds defs, subclasses a work-giver, mutates two duty
trees at startup, and polls. That is why it composes instead of colliding.*
## Requires: Institution: Core
Contraband declares a hard `modDependency` on **`flan.institution.core`** and loads after it. This
is not optional — after the split, the entire substrate Contraband reads lives in Core:
| Core provides | Contraband uses it for |
|---|---|
| `SecuredContext` / `SecuredContexts` / `CanConceal` / `IsHeld` | who counts as a concealer; who can be intaken, whittle, or dig |
| `Propensity.Would(pawn, base, salt)` | every disposition roll — intake (0.6), improvise (0.10), dig (0.08), all seeded and scaled by nature × nurture |
| `CriminalRecord` + `GameComponent_CriminalRecords` | `timesSearched`, `timesCaught`, `escapeAttempts`, `contrabandMade` — written by search and acquisition, read by priority |
Install Contraband without Core and it will not run. Everything else on this page is optional
interplay that degrades gracefully when the other mod is absent.
## Zero Harmony patches
Post-split, the mod's one Harmony patch (the regime that forces Joy for prisoners) moved to
**Institution: Justice**, so Contraband is Harmony-free again. Instead of patching, it:
- **Adds a new `WorkGiver`** (`WorkGiver_Warden_Search`) rather than patching a vanilla one.
- **Subclasses `WorkGiver_Warden`**, inheriting its behaviour rather than overriding it.
- **Mutates two `DutyDef` think trees at startup** via `StaticConstructorOnStartup` (not Harmony) —
an XML patch on a duty think tree silently no-ops in 1.6, so it is done in C#, deterministically.
- **Polls** every held pawn from a `MapComponent` for intake, improvisation, and tunnels — no hook
on the capture event is needed because the tick already visits every held pawn.
The net effect: the surfaces other prison mods touch are mostly untouched here, so conflicts are the
exception, not the rule.
## Foul Play — the carboy bridge
**Foul Play** (the "Piss Nuke" mod) stays its own mod with its own front door, and yet its **carboy
is a first-class contraband item.** This is the flagship demonstration of Contraband's *"items are
defs, subsystems are classes, mods are audiences"* principle, and it works through two seams:
1. **Cross-assembly worker resolution.** `CompProperties_Contraband`'s `useWorker` / `escapeWorker`
fields are plain `Type`s, and RimWorld resolves def `Type` fields with
`GenTypes.GetTypeInAnyAssembly` — searching **every loaded assembly**. So the carboy declares
`CompProperties_Contraband` and points `useWorker` at a class that lives in *Foul Play's* assembly
(e.g. a throw-the-carboy worker). Contraband never has to know that class exists.
2. **The opaque content tag.** A carboy is not just "a jar" — it is a jar *of* a fermented blend, and
that blend has to survive being concealed. Foul Play sets Contraband's two delegates:
```csharp
ContrabandUtility.ContentTagOf = thing => /* serialise the carboy's blend */;
ContrabandUtility.ApplyContent = (thing, tag) => /* pour that blend back in on redeem */;
```
When a carboy is intaken or smuggled, Contraband captures the tag blind; on redemption it hands
the tag back to Foul Play to restore the contents. **Contraband knows nothing about substances or
fermentation** — that framework lives entirely in Foul Play. If Foul Play is absent, both delegates
are null, no content is captured, and nothing breaks: a jar is just a jar. See
[Concealment and Intake](Concealment-and-Intake.md).
The dependency runs one way only: Foul Play bridges *to* Contraband (and to Core) if they are
present; Contraband takes **no** dependency on Foul Play.
## Institution: Justice — the record is the shared bus
Contraband and **Justice** never call each other. They meet on Core's `CriminalRecord`:
```
Contraband writes ──▶ CriminalRecord ──▶ Justice reads
timesSearched (in Core) Classification (security grade)
timesCaught Deterrence (colony-wide signal)
escapeAttempts Discipline / Parole (reform)
contrabandMade
```
- **Catching contraband feeds classification.** A prisoner repeatedly caught with shivs or foiled
mid-tunnel accrues `timesCaught` and `escapeAttempts`, which Justice's classification weighs into a
higher security grade.
- **And it feeds back.** Justice's deterrence signal flows *back* through Core's propensity seam
(`Nurture`), nudging every future intake / improvise / dig roll a Contraband pawn makes. A prison
that catches and disciplines becomes a prison where fewer prisoners bother trying — without either
mod referencing the other. Run Contraband alone and the deterrence factor is a neutral 1.0; the
record fields still route the warden.
## Institution: Gangs — the contraband economy
**Gangs** depends on Core, **Contraband**, and Justice, because a gang *is* a contraband economy:
- Gang smuggling moves contraband through the same public `Conceal` door intake and corruption use.
- A gang's outside members are the natural caller for the **reach-in corruption** primitive
(`Corruption.Smuggle`) — paying a bent warden to make a delivery. That primitive is exposed in
Contraband but has no in-repo trigger; Gangs is what drives it. See [Corruption](Corruption.md).
- Gang fights route to Justice's crime record, which then raises search priority here. The loop
closes through Core again.
## Prison mods the suite is tested against
| Mod | Interaction | Verdict |
|---|---|---|
| **Prison Commons** | postfixes `WorkGiver_Warden.ShouldSkip` on the **base** class; Contraband's search subclasses it and does not override, so searches respect prison-commons/allowed areas **for free** | works by inheritance |
| **Custom Prisoner Interactions** | patches only the *named* vanilla warden givers (`_Chat`, `_Convert`, `_Enslave`, `_ReleasePrisoner`); it cannot see a brand-new giver | no conflict |
| **Prisoner Realism** | its escapes are for "mood prisoners" mid-break; a tunnel breakout hands off to vanilla `PrisonBreakUtility.StartPrisonBreak`, which Prisoner Realism layers on. Tunnels **complement** it — they let ward patients and slaves who would never mood-break still, patiently, dig out | complementary |
| **Prison Labor** | prisoners working outside the cell are still held pawns and still tracked; Contraband adds no patches to labor jobs. A work assignment is simply another place a disposed prisoner might come by materials | no conflict |
| **Prisoner Recreation** | overlaps the *regime* feature — which now lives in **Institution: Justice**, not here, and is written to be idempotent with Prisoner Recreation | not Contraband's concern post-split |
## Load order
```
Ludeon.RimWorld
flan.institution.core ← required, loads before Contraband
flan.institution.contraband ← this mod
(Foul Play / Justice / Gangs — any order after Core; each bridges if present)
```
## The general rule
If a mod adds prisoner behaviour by **patching vanilla warden givers or the escape duty tree by
name**, it will not see Contraband's additions, and Contraband will not see its — they pass each
other. If a mod adds a *new* `WorkGiver` or duty node of its own, it stacks. The one place to watch is
another mod that *also* rewrites the same two duty think trees (`PrisonerEscape`,
`PrisonerAssaultColony`) wholesale; Contraband inserts its nodes at a specific anchor and logs a
warning if that anchor is missing, so a load-order or conflict problem is visible in the log rather
than silent.
---
*Part of the **Institution** suite — Core · Contraband · Justice · Gangs, alongside Foul Play and
Ward. Each stands alone; together they interlock.*
*Developed with substantial assistance from Claude (Anthropic).*