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.
7.7 KiB
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
DutyDefthink trees at startup viaStaticConstructorOnStartup(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
MapComponentfor 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:
-
Cross-assembly worker resolution.
CompProperties_Contraband'suseWorker/escapeWorkerfields are plainTypes, and RimWorld resolves defTypefields withGenTypes.GetTypeInAnyAssembly— searching every loaded assembly. So the carboy declaresCompProperties_Contrabandand pointsuseWorkerat a class that lives in Foul Play's assembly (e.g. a throw-the-carboy worker). Contraband never has to know that class exists. -
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:
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.
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
timesCaughtandescapeAttempts, 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
Concealdoor 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. - 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).