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
+148
View File
@@ -0,0 +1,148 @@
# Classification
*The intelligence layer over the wings you already build by hand.*
You already build a minimum wing and a max block. You already put the psychopath behind steel and the
teenage pickpocket behind a wooden door. Classification does not replace those walls, cells and locks —
it answers the question vanilla never does: **who belongs where.** It reads the one shared
`CriminalRecord` every module writes to and turns it into a single verdict, so the crime system, the
search, the escape and the classifier all agree on how dangerous a pawn is, because they read the same
number.
Grade drives everything downstream: search frequency, privileges, escape risk, and — critically —
parole eligibility ([Parole](Parole.md) gates on grade).
> The isolation *toll* of a max/solitary placement is Prisoner Realism's (good) sim. Justice only
> decides the placement.
---
## The tiers
`SecurityGrade` is four bands, low to high — the tiers players already build, named:
| Grade | Risk score | Reading |
|---|---|---|
| **Minimum** | `< 0.35` | Barely a disposition, clean record. Open dorm, light watch. |
| **Medium** | `0.35 – 0.79` | A real record or a real nature. Proper cell, routine search. The parole ceiling. |
| **Maximum** | `0.80 – 1.49` | Repeat offender or proven flight risk. Steel, solitary door, frequent search. |
| **Supermax** | `≥ 1.5` | The headline cases. Escapes plus crimes plus a dark nature. Never let them near a wall. |
Note the ceiling at **Medium**: [Parole](Parole.md) will only consider a pawn graded Medium or below.
Grade is therefore not just a placement hint — it is the gate a pawn has to fall back through before
they can be released.
---
## The risk score
Risk is a `0..~3` number: baseline disposition plus everything on the record, minus reform earned.
```
risk = Nature(pawn) * 0.5 // who they are, before they have done anything
+ escapeAttempts * 0.35 // a proven flight risk is the headline
+ crimesCommitted * 0.20
+ timesCaught * 0.15
+ contrabandMade * 0.10
- max(0, reform) * 0.4 // genuine reform earns a downgrade
risk = max(0, risk) // never negative
```
| Term | Weight | Why this weight |
|---|---|---|
| `Nature` (0..1) | `× 0.5` | Disposition alone can carry a pawn to Medium (Nature 0.7+), but never past it on its own. Character is a suspicion, not a conviction. |
| `escapeAttempts` | `× 0.35` | The heaviest per-event term. A pawn who *runs* is the one who ends up armed in your base. One attempt is worth nearly two crimes. |
| `crimesCommitted` | `× 0.20` | The staple. Steady, cumulative. |
| `timesCaught` | `× 0.15` | Caught contraband is worse than merely suspected. |
| `contrabandMade` | `× 0.10` | The lightest term — making a shiv is common; escaping with one is not. |
| `reform` (if > 0) | `− 0.4` | The only term that can *lower* the grade. At most −0.4 (reform capped at 1.0). |
Two facts fall out of the numbers, and both matter for how you play:
- **`timesSearched` is not in the formula.** Searching a pawn does not make them more dangerous —
only *finding* something (`timesCaught`) does. Search freely; it costs the prisoner no grade.
- **Reform can shift at most 0.4 of risk.** At `reform = 1.0`, the downgrade is `−0.4`. So a pawn
whose record *without reform* already totals `≥ 1.2` can never fall to Medium (`< 0.8`) no matter
how thoroughly they reform — and therefore can **never be paroled**. A prolific offender is a
life sentence. You will hold them, work them, or execute them; you will not release them. This is a
deliberate property of the weights, not an accident.
---
## Worked example — grading a record
**Bram**, an Abrasive raider. Nature = `0.05 + 0.15 = 0.20`. He has three crimes, one escape attempt,
was caught twice, made two shivs, and has not been reformed (`reform = 0`).
```
risk = 0.20 * 0.5 = 0.100 (nature)
+ 1 * 0.35 = 0.350 (escape — the headline)
+ 3 * 0.20 = 0.600 (crimes)
+ 2 * 0.15 = 0.300 (caught)
+ 2 * 0.10 = 0.200 (contraband)
- 0 * 0.4 = 0.000 (no reform)
─────────
total = 1.550 → ≥ 1.5 → SUPERMAX
```
Now treat him. Say patient handling and good conduct lift him to `reform = 0.40`:
```
risk = 1.550 - (0.40 * 0.4) = 1.550 - 0.160 = 1.390 → MAXIMUM
```
He drops a band. But notice: his reform-less risk is `1.55`, well above `1.2`. Even at perfect
`reform = 1.0` he lands at `1.55 − 0.40 = 1.15` — still Maximum. **Bram is beyond parole for the rest
of his life.** His record decided that, not his disposition.
Contrast **Cass**, a Kind pickpocket. Nature = `clamp01(0.05 − 0.30) = 0`. One crime, caught once, no
escape, no contraband, `reform = 0`.
```
risk = 0 + 0 + (1*0.20) + (1*0.15) + 0 - 0 = 0.350 → MEDIUM (exactly on the line)
```
Give Cass the standard treatment to `reform = 0.30`:
```
risk = 0.350 - (0.30 * 0.4) = 0.350 - 0.120 = 0.230 → MINIMUM
```
Cass is now Minimum, and — being Medium-or-below with `reform ≥ 0.30` — **paroleable**. Same
institution, two futures, and the record told you which was which before you had to guess.
---
## How to play with grades
- **Segregate by grade, not by vibe.** Sort your cells to the four bands and put a pawn where their
score, not your hunch, says. The whole suite reads the record; you can too.
- **Escapes are the alarm.** One escape attempt (`+0.35`) will jump a middling pawn a band. If a pawn
crosses into Maximum after a break attempt, believe it — treat them as the flight risk the number
says they are.
- **A clean nature is not a clean record.** A Kind pawn who has escaped twice still grades Maximum;
disposition is only half the score.
- **Watch the parole ceiling.** If you intend to release someone, keep their reform-less risk under
`1.2` — mostly that means limiting how deep their record gets *before* you start treating them. A
pawn you let rack up escapes and catches has sentenced themselves.
- **Reform is the only lever that lowers a grade.** See [Discipline & Reform](Discipline-and-Reform.md)
for how to move it, and [Parole](Parole.md) for where the grade gate lands.
---
## For modders
```csharp
SecurityGrade grade = Classification.Grade(pawn); // the verdict
float score = Classification.Risk(pawn); // the raw 0..~3 number
```
Both are pure reads — `Risk` uses `GameComponent_CriminalRecords.PeekFor` and never creates a record.
`SecurityGrade` is an ordered enum (`Minimum < Medium < Maximum < Supermax`), so `grade <= Medium`
comparisons work as written. The type lives in the `Contraband` namespace (Justice was extracted from
Institution: Contraband and kept the shared namespace).
---
*Part of the **Institution** suite for RimWorld 1.6: Core · Contraband · Justice · Gangs. Developed
with substantial assistance from Claude (Anthropic).*
+168
View File
@@ -0,0 +1,168 @@
# Deterrence — the feedback loop
*The connection that turns the pipeline into a cycle.*
This is the module that makes policing **govern** rather than merely clean up. Everything else in
Justice reacts to one pawn: this reactor's *state* is the whole colony, and it feeds **back** into
every pawn's disposition. Crime that goes unanswered emboldens everyone a little; visible justice
deters everyone a little. The reason to punish is not just this prisoner — it is the message it sends
the rest, and here that message is a number they all read.
---
## The climate of order
Every map carries a `MapComponent_Deterrence` holding one value:
| | |
|---|---|
| **Range** | `0.0` (lawless) … `1.0` (iron) |
| **Baseline** | `0.5` — an ordinary colony |
| **Below baseline** | crime pays; dispositions run **hot** |
| **Above baseline** | order holds; dispositions run **cool** |
It is nudged by two events and, left alone, forgets.
### The nudges
| Event | Source | Nudge | Written by |
|---|---|---|---|
| A crime, unanswered | `Justice.RecordCrime(perp)` | **−0.08** | Justice, Gangs (fights) |
| Visible justice done | `Justice.RecordPunishment(map)` | **+0.12** | Justice (`Discipline.Punish`) |
Both clamp the result to `[0, 1]`. Note the asymmetry: **punishment (+0.12) outweighs crime (−0.08)
by 1.5×.** A colony that answers every offence does not merely break even — it ratchets *above*
baseline into "order holds" territory. This is the deterrence dividend, and it is deliberate: justice
seen to be done buys more order than the crime cost.
`RecordCrime` also writes the record — it increments `crimesCommitted` and stamps `lastCrimeTick` on
the perpetrator — so the same event that moves the climate is the event classification and parole
later see. `RecordPunishment` moves only the climate; the *record* side of punishment (the reform
shift) is [Discipline](Discipline-and-Reform.md)'s job.
### The drift
```
every 2500 ticks: level = MoveTowards(level, 0.5, 0.0015)
```
Memory fades. With nothing happening, the climate creeps back toward ordinary at **0.0015 per step,
one step every 2500 ticks** — which works out to:
```
drift per in-game day = (60000 / 2500) * 0.0015 = 24 * 0.0015 = 0.036 / day
```
So a single unanswered crime (`−0.08`) takes roughly `0.08 / 0.036 ≈ 2.2 days` to heal on its own —
or one punishment (`+0.12`) to over-answer instantly. An iron colony you stop maintaining slides back
to baseline over about two weeks; it does not stay stern for free.
---
## The feedback — how it reaches every pawn
This is the loop. The climate is read back into `Propensity.Nurture` (in Core) as a multiplier:
```
DeterrenceFactor(pawn) = Lerp(1.3, 0.7, level) // = 1.3 - 0.6 * level
Nurture(pawn) = ... * DeterrenceFactor(pawn)
```
| `level` | Factor | Effect on every pawn's disposition |
|---|---|---|
| 0.00 (lawless) | **1.300** | +30% hotter — crime pays, everyone feels it |
| 0.30 | 1.120 | +12% |
| **0.50 (baseline)** | **1.000** | **neutral — a default colony sits exactly here** |
| 0.70 | 0.880 | −12% |
| 0.90 | 0.760 | −24% |
| 1.00 (iron) | **0.700** | −30% cooler — order holds, everyone calms |
Two things to notice:
- **Baseline is the neutral point, by design.** A default colony sits at `0.5`, which is a factor of
exactly `1.0` — ordinary order neither inflames nor calms. That symmetry is deliberate. If baseline
ran hot (as an earlier tuning did), ordinary order would nudge propensity up, breed a little more
crime, drop order, and feed a slow runaway. Neutral-at-baseline means only a colony that lets order
*slide below* ordinary earns the hot multiplier, and only one that pushes *above* it earns the calm.
- **The swing is `0.7×` to `1.3×`, symmetric around `1.0`** — a `±30%` spread applied to *everyone's*
nurture at once. This is the multiplier that makes catching one pawn matter to the disposition of
the rest.
### JusticeBootstrap — reconnecting the loop across the mod boundary
Core keeps `Propensity.DeterrenceFactor` as a neutral seam — a `Func<Pawn,float>` that returns `1f`
until something fills it. Core alone never has to know Justice exists; that one seam is what lets Core
stay a dependency-free leaf while the deterrence loop runs *through* it.
At startup, `JusticeBootstrap` fills the seam:
```csharp
Propensity.DeterrenceFactor = pawn => {
var d = pawn?.Map?.GetComponent<MapComponent_Deterrence>();
return d != null ? Mathf.Lerp(1.3f, 0.7f, d.Level) : 1f; // neutral (1.0) at baseline 0.5
};
```
So **only when Justice is installed** does the climate bend disposition; without it, Core reads a flat
`1.0` and pawns are indifferent to order. This is the deterrence feedback loop, reconnected across the
mod boundary without Core ever depending on the justice layer. (If the pawn is off-map — caravan, in
transit — there is no map component, and the factor falls back to a neutral `1.0`.)
---
## Worked example — a day at the institution
The colony starts at baseline `0.5` (factor `1.05`). Over one day:
| Step | Event | `level` | Factor |
|---|---|---|---|
| start | — | 0.50 | 1.050 |
| 1 | Prisoner A shanks a guard (crime, unanswered) | 0.42 | 1.106 |
| 2 | Prisoner B foments trouble (crime, unanswered) | 0.34 | 1.162 |
| 3 | Warden punishes A (`RecordPunishment`) | 0.46 | 1.078 |
| 4 | Warden punishes B (`RecordPunishment`) | 0.58 | 0.994 |
| overnight | nothing happens, drift ≈ −0.036 toward 0.5 | 0.544 | 1.019 |
Two crimes cost `−0.16`; two punishments returned `+0.24`. The colony ends the day at `0.58` —
**above** where it started — because punishment out-answers crime. Every pawn's disposition dipped
hotter as the crimes landed (`1.05 → 1.16`) and then cooled below neutral once order was reasserted
(`0.994`). By morning the drift has begun erasing the gain, and if nothing keeps the pressure on, the
colony sinks back to its slightly-hot baseline over the next couple of weeks.
That arc — hot when crime pays, cool when justice is seen, forgetful when neither happens — is the
whole reason discipline is not inert. You are not punishing a pawn; you are setting the temperature of
the room.
---
## How to play with deterrence
- **Answer crime, visibly and promptly.** Each punishment is worth 1.5 crimes of order. A colony that
reliably punishes climbs *above* baseline and cools everyone; a colony that lets offences slide
sinks below and heats everyone — a spiral, because hotter pawns commit more crime.
- **Don't coast on a past crackdown.** The climate drifts back to baseline at `0.036/day`. Order is a
maintenance cost, not a one-time purchase.
- **Push past baseline if you want calm.** Neutral disposition needs `level ≈ 0.571`; ordinary
(`0.5`) still runs 5% hot. A steady rhythm of caught-and-punished offences is what holds you there.
- **A lawless spell is self-feeding.** At `level 0.3` every pawn is `1.19×` more disposed; more crime
follows, driving the level lower still. Break the cycle with punishments, not patience.
---
## For modders
```csharp
Justice.RecordCrime(perpetrator); // -0.08 climate, +1 crime, stamps lastCrimeTick
Justice.RecordPunishment(map); // +0.12 climate
float level = map.GetComponent<MapComponent_Deterrence>().Level; // raw 0..1
```
`RecordCrime` is the writer any module calls when a pawn does something the colony would police —
Institution: Gangs calls it on rival fights, for instance. `RecordPunishment` is called by
`Discipline.Punish`. The component and statics live in the `Contraband` namespace (shared across the
suite since Justice's extraction from Contraband).
---
*Part of the **Institution** suite for RimWorld 1.6: Core · Contraband · Justice · Gangs. Developed
with substantial assistance from Claude (Anthropic).*
+142
View File
@@ -0,0 +1,142 @@
# Discipline & Reform
*Punishment as an action, with a self-complete payoff — and the seat of institutionalization.*
Punishment in Justice does two things at once, on two different axes:
1. **It deters the colony.** Order seen to be done raises the climate of order for everyone —
`RecordPunishment`, `+0.12`. See [Deterrence](Deterrence.md).
2. **It reshapes the punished.** A harsh hand *prisonizes* — the pawn hardens, `reform` falls, their
disposition climbs for good. A corrective hand *rehabilitates* — `reform` rises, their disposition
cools for good.
Both effects are Justice's own, so discipline is never inert. Prisoner Realism owns the passive *toll*
of isolation (a good sim of how solitary *feels*); Justice owns the *order* it produces and the
persistent *shift* it leaves on the pawn. When both mods are present, PR's solitary deterioration
deepens the felt experience on top — it does not replace this.
---
## The two hands
```
Discipline.Punish(pawn, harsh):
Justice.RecordPunishment(pawn.Map) // +0.12 colony climate (Deterrence)
reform = Clamp(reform + (harsh ? -0.15 : +0.10), -1, +1) // the persistent shift
```
| Call | Reform delta | Meaning |
|---|---|---|
| `Punish(pawn, harsh: true)` | **−0.15** | Beatings, deprivation, the hard hand. Hardens — "prisonization." |
| `Punish(pawn, harsh: false)` | **+0.10** | Correction, structure, rewarded good conduct. Rehabilitates. |
`reform` lives on the shared record, clamped to `[−1, +1]`:
| `reform` | Reading |
|---|---|
| `+1.0` | Fully rehabilitated |
| `0.0` | Untouched — as they came in |
| `−1.0` | Fully hardened, institutionalized |
Note the asymmetry the other way from Deterrence: **harsh (−0.15) moves faster than gentle (+0.10).**
It takes three corrective acts to build `+0.30` of reform; two harsh acts to tear down `−0.30`. Damage
is quicker than repair — as it should be.
---
## How reform becomes disposition
Reform is not a status effect or a mood buff. It is read straight back into `Propensity.Nurture` (in
Core), where it multiplies a pawn's whole disposition:
```
if reform != 0:
Nurture *= Clamp(1 - reform * 0.5, 0.4, 2)
```
| `reform` | Nurture factor | Effect |
|---|---|---|
| −1.00 (hardened) | **1.500** | +50% more disposed — permanently |
| −0.30 | 1.150 | +15% |
| −0.15 (one harsh act) | 1.075 | +7.5% |
| 0.00 | 1.000 | untouched |
| +0.10 (one gentle act) | 0.950 | −5% |
| +0.30 (parole threshold) | 0.850 | −15% |
| +1.00 (rehabilitated) | **0.500** | −50% less disposed — permanently |
Given reform is clamped to `[−1, +1]`, the factor spans `0.5×` to `1.5×`; the `0.4`/`2` clamp is a
safety rail that reform alone never reaches. **This is the whole trick.** Institutionalization and
recidivism are not a parallel mechanic bolted on the side — they are *one number the propensity engine
already reads*. A hardened pawn is not flagged "recidivist"; they simply carry a `−reform` that makes
every "would they?" roll for the rest of their life come up hot. Discipline and Parole are what *move*
reform; Nurture only *reads* it — which is how institutionalization becomes Justice's without a second
system.
---
## Worked example — two sentences
Take a fresh prisoner, `reform = 0`, badly kept: mood `0.30`, held. From Core, before reform, their
Nurture is already `1 × 1.6 (mood) × 1.4 (held & unhappy) = 2.24`, and say the colony sits at baseline
so `DeterrenceFactor = 1.05`, giving Nurture `≈ 2.35`.
**The hard hand.** You beat them into line — three harsh punishments:
```
reform: 0 → -0.15 → -0.30 → -0.45
Nurture factor at reform -0.45 = 1 - (-0.45 * 0.5) = 1.225
```
Their disposition is now `2.35 × 1.225 ≈ 2.88` — **+22% hotter than when they arrived**, forever,
independent of mood. You have made them more criminal, not less. This is prisonization: the sentence
itself became the cause. (You did buy `+0.36` of colony climate along the way — order today, at the
cost of the pawn's tomorrow.)
**The corrective hand.** Instead you structure and reward — three gentle punishments *and* you fix
their conditions (recreation, decent cell) so mood recovers to `0.55`:
```
reform: 0 → +0.10 → +0.20 → +0.30
mood 0.55 → no mood multiplier, not held-&-unhappy → those factors drop out
Nurture factor at reform +0.30 = 1 - (0.30 * 0.5) = 0.85
```
Now Nurture is roughly `1 × 0.85 × 1.05 (deterrence) ≈ 0.89` — **below neutral.** The same pawn who
would have been `2.88` disposed is now `0.89`. And at `reform = 0.30` with a low enough grade they
have crossed the [Parole](Parole.md) threshold. Same institution, opposite outcomes — decided by which
hand you used.
---
## How to play with discipline
- **Harsh is a lever, not a punishment button.** It buys colony order *now* (`+0.12` climate) at the
price of the pawn's disposition *forever* (`−0.15` reform → hotter Nurture). Use it when you need the
deterrence and never intend to release the pawn — a Supermax lifer you are only ever going to hold.
- **Gentle is how anyone gets out.** Parole needs `reform ≥ 0.30`; only the corrective hand builds it.
Three gentle acts is the floor.
- **Damage compounds; repair is slow.** `−0.15` vs `+0.10` means a pawn you brutalize early is
expensive to bring back — and a hardened pawn commits more crime, which sinks the climate, which
makes *everyone* worse. Don't harden pawns you might want later.
- **Conditions and discipline stack.** Reform shifts disposition permanently; mood, neglect and
deterrence shift it live (see [Regime](Regime.md) and [Deterrence](Deterrence.md)). A reformed pawn
in a well-run wing is calm on two axes at once.
---
## For modders
```csharp
Discipline.Punish(pawn, harsh: true); // -0.15 reform, +0.12 climate
Discipline.Punish(pawn, harsh: false); // +0.10 reform, +0.12 climate
```
`Punish` uses `GameComponent_CriminalRecords.For` (creates the record if absent) and clamps `reform`
to `[−1, +1]`. It always fires `RecordPunishment` on the pawn's map, so *any* act of discipline moves
the colony climate regardless of which hand you use — the colony sees order done, whoever it was done
to. The class lives in the `Contraband` namespace (shared since the extraction from Contraband).
---
*Part of the **Institution** suite for RimWorld 1.6: Core · Contraband · Justice · Gangs. Developed
with substantial assistance from Claude (Anthropic).*
+96
View File
@@ -0,0 +1,96 @@
# Institution: Justice
*What the institution **does** about crime — the corrections and policing layer of the **Institution**
suite of RimWorld 1.6 mods.*
Vanilla RimWorld keeps a rap sheet no one reads. You capture a raider, warden them, and the game
promptly forgets they ever tried to knife a guard. Prisoners are interchangeable mood-boxes; a
"maximum security" wing is a decoration you build by hand and the sim never acknowledges. There is a
record, and there are no consequences.
**Justice turns the record into consequences, and closes the loop.** It grades every held pawn from
what they have actually done, gives the colony a *climate of order* that crime and punishment move,
feeds that climate back into every pawn's disposition, moves a *reform* score that decides whether a
sentence hardens or heals, gates release on it, and gives prisoners the recreation need vanilla flatly
denies them. The through-line is one sentence:
> **Catching and punishing one pawn changes the disposition of the rest.**
That is the difference between policing that *cleans up* and policing that **governs**. The reason to
punish an offender is not only this offender — it is the message it sends everyone else who is quietly
deciding, on a seeded roll, whether crime pays here.
---
## The one shared record
Justice never keeps its own per-pawn crime state. It reads and writes the single `CriminalRecord` that
**Institution: Core** holds for every pawn — the same record the search, the escape, the brewing, and
the gang systems write to. That is the whole point of the substrate: classification, deterrence,
discipline and parole all agree on how dangerous a pawn is, because they all read the same numbers.
| Field | What it counts | Written by |
|---|---|---|
| `crimesCommitted` | offences on the record | Justice (`RecordCrime`), Gangs (fights) |
| `escapeAttempts` | proven flight risk | Contraband (escape/tunnel) |
| `contrabandMade` | shivs, brews, tools made | Contraband |
| `timesSearched` | searches endured | Contraband (warden search) |
| `timesCaught` | searches that found something | Contraband |
| `lastCrimeTick` | when they last offended | Justice (`RecordCrime`) |
| `reform` | −1 hardened … +1 rehabilitated | Justice (`Discipline`, `Parole`) |
| `pardoned` | released after genuine reform | Justice (`Parole`) |
Justice authors the **crime / punishment / reform / pardon** columns; the counters of *what physically
happened* are fed by its siblings. It grades and gates over all of them.
---
## The five modules
| Module | What it does | Page |
|---|---|---|
| **Classification** | Grades held pawns `Minimum`..`Supermax` from a risk score over the record. | [Classification](Classification.md) |
| **Deterrence** | The colony's climate of order, moved by crime and punishment, drifting to baseline, read back into propensity. | [Deterrence](Deterrence.md) |
| **Discipline & Reform** | Punishment moves the reform score — harden vs. rehabilitate. The seat of institutionalization and recidivism. | [Discipline & Reform](Discipline-and-Reform.md) |
| **Parole** | Release when reform, grade, and pardon status line up. | [Parole](Parole.md) |
| **Regime** | Enables the prisoner recreation (Joy) need via a Harmony postfix, idempotent with Prisoner Recreation. | [Regime](Regime.md) |
Threaded through all five is one small piece of glue, **`JusticeBootstrap`**, which at load fills the
neutral deterrence seam Core leaves open — reconnecting the feedback loop across the mod boundary
without Core ever depending on Justice. See [Deterrence](Deterrence.md).
---
## Policing — the pre-arrest half (shipped)
Everything above is the **post-arrest** side — corrections. The **pre-arrest** side now ships too:
colonists commit crimes on the propensity spectrum, witnesses and a constable's work name the culprit,
and a weighed arrest can end in a cell or a resisted breakout — plus prison riots and a recidivism
alert. Deterrence models *the consequence of visible justice*; policing is the machinery that produces
crime to answer. It has its own settings toggle (on by default). Full detail in **[Policing](Policing.md)**.
---
## Requirements & load order
- **RimWorld 1.6**
- **Institution: Core** — required. The propensity/record engine Justice grades against.
- **Harmony** — required. Regime's prisoner-recreation patch is the suite's only Harmony-using code.
- Load **after** Core and Harmony.
Each mod in the suite stands alone as an install; together they form one system. Justice is useful
with Core alone, and richer with **Institution: Contraband** (which feeds the escape/search/contraband
counters) and **Institution: Gangs** (whose fights record crimes).
---
## The suite
Part of the **Institution** suite: **Core** (the propensity + record engine) · **Contraband**
(concealment, search, escape) · **Justice** (this mod) · **Gangs** (contraband economies). The
standalone **Foul Play** framework bridges into Core and Contraband when present.
---
*Part of the **Institution** suite for RimWorld 1.6: Core · Contraband · Justice · Gangs. Developed
with substantial assistance from Claude (Anthropic).*
+150
View File
@@ -0,0 +1,150 @@
# Parole
*Release, driven by what the pawn has become.*
Parole is the end of the arc, and it is deliberately a *decision*, not a mechanic that rebuilds the
game's release flow. It asks one question — **is this pawn ready?** — and answers it from two things
already on the record: the reform the sentence earned (or failed to earn), and the grade the record
warrants. Both are self-complete reads; nothing here re-simulates a pawn's future.
> The *return* outcome — a grateful ally, a vengeful raider — is Prisoner Realism's Recidivism, a good
> sim Justice does not rebuild. Justice's mirror is the parolee who **stays** and may reoffend,
> carrying their record into the colony (a Justice follow-up).
---
## The gate
```
CanRelease(pawn):
rec = record for pawn (peek, no create)
if rec == null: return true // nothing on record to hold them
if rec.pardoned: return false // already released
return rec.reform >= 0.30
&& Classification.Grade(pawn) <= SecurityGrade.Medium
```
Three conditions, all of which must hold:
| Condition | Threshold | Why |
|---|---|---|
| Not already pardoned | `pardoned == false` | Release is a one-way flag; you can't re-parole. |
| Genuinely reformed | `reform ≥ 0.30` | Proof the sentence *healed* rather than hardened. Three corrective acts minimum. |
| Low enough grade | `Grade ≤ Medium` (risk `< 0.8`) | Reform of attitude is not enough — the *record* must have cooled to something you'd let out. |
A pawn with **no record at all** is releasable trivially (there is nothing to hold them). Everyone
else has to earn all three.
The grade gate and the reform gate interact in a way worth internalizing. Because reform subtracts at
most `0.4` from risk ([Classification](Classification.md)), a pawn whose reform-*less* risk is `≥ 1.2`
can never reach Medium — so **no amount of reform will ever parole a prolific offender.** Parole is for
pawns whose record stayed shallow enough that treatment can pull them back under the ceiling. Let a
pawn rack up escapes and catches and you have quietly converted them into a lifer, whatever their
attitude.
---
## Release
```
Release(pawn):
record.pardoned = true
```
`Release` sets one flag: `pardoned`. Vanilla does the actual freeing; the flag is Justice's memory
that this pawn was let out after genuine reform, so reintegration can grant a clean slate and
`CanRelease` won't offer them twice. A modest faction-goodwill / relationship nudge for a well-handled
release is the immediate payoff, wired when the release job lands.
---
## The whole arc
The pawn moves through every Justice module in turn, and each one writes the record the next one reads:
| Stage | Module | What moves | Record touched |
|---|---|---|---|
| 1. Crime | [Deterrence](Deterrence.md) | Climate `−0.08`; the colony runs hot | `crimesCommitted++`, `lastCrimeTick` |
| 2. Caught & held | [Classification](Classification.md) | A grade is assigned from the record | reads all counters |
| 3. Discipline | [Discipline](Discipline-and-Reform.md) | `reform` moves ±; climate `+0.12` | `reform` |
| 4. Reform | [Discipline](Discipline-and-Reform.md) → Core | Disposition cools as reform rises | `reform` (read by Nurture) |
| 5. Regrade | [Classification](Classification.md) | Reform subtracts risk; grade falls | reads `reform` |
| 6. **Parole** | this page | Gate opens when reform ≥ 0.30 **and** grade ≤ Medium | reads `reform`, `pardoned`; sets `pardoned` |
It is a loop, not a line: the crime that opens stage 1 also cools the colony's climate, which the *next*
pawn's disposition reads — so one pawn's whole sentence is faintly present in every other pawn's odds.
---
## Worked example — a sentence that ends in release
**Cass**, a Kind pickpocket. Nature `= clamp01(0.05 − 0.30) = 0`. She arrives with one crime, caught
once, no escapes, no contraband, `reform = 0`.
```
Grade at intake:
risk = 0 + 0 + (1*0.20) + (1*0.15) + 0 - 0 = 0.35 → MEDIUM
CanRelease? reform 0 < 0.30 → NO
```
She is already Medium-or-below, so the *grade* gate is met — but her `reform` is `0`. You give her the
corrective hand three times (structure, rewarded conduct), and fix her cell so she isn't stewing:
```
reform: 0 → +0.10 → +0.20 → +0.30
Grade now: risk = 0.35 - (0.30 * 0.4) = 0.23 → MINIMUM
CanRelease? reform 0.30 ≥ 0.30 AND Minimum ≤ Medium AND not pardoned → YES
```
`Release(Cass)` sets `pardoned = true`. She walks. Contrast **Bram** from the Classification page,
whose reform-less risk of `1.55` keeps him at Maximum even at `reform = 1.0` — `CanRelease` returns
`false` for Bram forever, because the grade gate never opens. Two prisoners, the same treatment, and
the record decides which one you can ever let go.
---
## A note on record cleanup
A pawn whose record is `IsBlank` — no crimes, no escapes, no contraband, no catches, `reform == 0`,
not pardoned — is dropped on save/load (Core prunes blank and dead-pawn records). A *pardoned* pawn is
therefore **not** blank and their record persists: the pardon is remembered. This is why a released
parolee who stays and reoffends still carries their history — Justice does not forget that they were
once let out.
---
## Ideology-flavoured thresholds
Precepts layer on top of this baseline, not under it: an execution-favouring ideoligion paroles
rarely, a lenient one readily. `CanRelease` is the substrate-native baseline those precepts modulate —
the floor beneath the flavour, so the decision is coherent whether or not Ideology is installed.
---
## How to play with parole
- **Parole is earned, not granted.** You cannot release your way out of a deep record. Decide early
whether a pawn is a keep-or-release case and treat (gently) the ones you mean to free.
- **`reform ≥ 0.30` is three gentle acts, minimum.** Nothing faster reaches it. Start early.
- **Keep the record shallow if you want the option.** Every escape (`+0.35`) and catch (`+0.15`) you
let accumulate pushes a pawn toward the unparoleable side of the `1.2` line.
- **A parolee who stays is a Justice case, not a farewell.** They carry their record; if conditions
sour, their disposition (still reading their history) can put them back on it.
---
## For modders
```csharp
if (Parole.CanRelease(pawn)) // pure read: reform, grade, pardon
Parole.Release(pawn); // sets pardoned = true
```
`CanRelease` peeks (never creates a record) and treats a missing record as releasable. `Release` uses
`For` (creates if absent) and is idempotent — a second call is a no-op once `pardoned` is set. Both
live in the `Contraband` namespace (shared since Justice's extraction from Contraband).
---
*Part of the **Institution** suite for RimWorld 1.6: Core · Contraband · Justice · Gangs. Developed
with substantial assistance from Claude (Anthropic).*
+120
View File
@@ -0,0 +1,120 @@
# Policing — the pre-arrest half
*The other half of the loop. Where the rest of Justice deals with people the colony has already
caught, **policing** is what happens before the cell door: your own colonists commit crimes on the
propensity spectrum, the colony investigates, and — sometimes — arrests.*
It is a big behavioural change (your colonists become potential criminals), so it has **its own
toggle** in the mod settings, on by default. Turn it off to run the rest of Justice — classification,
deterrence, discipline, parole, regime — without colony crime.
---
## The loop
```
[crime] → [witnessed / investigated] → [weighed arrest (resist?)] → prison → … → parole → [recidivism]
```
Every stage reads the shared engine (`Propensity`, the `CriminalRecord`, the deterrence meter), so
policing is not a bolt-on — it feeds the same record classification grades on and discipline reforms.
## Crime — and why small colonies stay honest
Every ~40 seconds, each free colonist gets a seeded roll to offend. The base rate is low (`0.06`) and
multiplied hard by nature × nurture — almost nobody with an ordinary disposition ever does anything.
But it is *also* multiplied by **crime cover**:
| Free colonists | Crime cover |
|---|---|
| ≤ 3 | 0.15 |
| ~8 | ~0.6 |
| ≥ 13 | 1.0 |
In a tight 2–3 pawn colony everyone knows everyone and retribution is certain even without a jail, so
crime is **rare**; a larger, more anonymous colony offers cover. This is a deliberate inversion of the
naive "no enforcement → more crime": a small colony is kept honest by its own closeness, not by a
constable.
A crime is one of **theft**, **vandalism**, or **assault** — leaning on who the culprit is (a
kleptomaniac steals, a bloodlusty pawn assaults, a pyromaniac vandalizes).
## Consequences — the stakes
A crime leaves a mark the colony can *see* (all wrapped defensively — a consequence that finds no
target never breaks anything):
- **Theft** lifts a small stack of the colony's goods and the thief **pockets it**. RimWorld has no
per-person property (stockpiles are communal), so theft is theft from the common store — but the
culprit now physically carries what they took, a natural evidence trail a search can pick up.
- **Vandalism** damages a nearby colony building.
- **Assault** gives a nearby colonist a light, down-safe knock — and the culprit chooses their mark
**wisely**: someone they resent (motive), who is weak (little retribution), and unwatched (few
witnesses).
- **Relationships fray.** An assault victim thinks much worse of their attacker immediately (they saw
who did it); and when investigation *names* a culprit, the whole colony's opinion of them drops.
- The colony is **notified** a crime happened — culprit unknown.
## Witnesses and investigation
A crime is not equally solvable. Colonists who were near enough to **see** it are witnesses, and each
is a partial lead — a witnessed crime starts up to `0.8` of the way to solved before anyone lifts a
finger; an unseen one is a **cold case** worked from nothing.
Investigation then accrues evidence toward `1.0` (naming the culprit) two ways:
- **Ambient**, scaled by how many colonists the colony can spare (`~0.34` per check per unit of
effort — a few investigated windows).
- **The police work type.** Assign a colonist to *policing* and they walk to open **crime scenes** and
work them, adding a chunk of evidence scaled by their Intellectual + Social skill. A sharp constable
cracks cases fast; a colony that spares no one lets them go cold.
## The weighed arrest
A solved case does **not** mean an automatic arrest. Fellow-colonist cops will not gut the colony to
jail someone over a petty crime — the arrest is a cost/benefit (`ShouldArrest`):
```
arrest ⇔ colony can afford a prison AND severity ≥ 1.5 + value × 3
```
- **Severity** — the crime's kind (theft 1 · vandalism 1.5 · assault 2.5), escalated by the culprit's
record (a rap sheet and prior escapes compound).
- **Value** — 0..1 from the culprit's best skills. A star colonist raises the bar to ~4.5; an
expendable one leaves it at ~1.5.
- **Capacity** — **below ~5 colonists, or with no prison bed, the colony arrests no one.** A prisoner
plus a warden would cripple a small colony. Capacity ramps up as the colony grows.
So a petty crime by your only doctor → they walk. A murder → arrested regardless. And a crime that
paid, unanswered, erodes the climate of order a little more (crime emboldens).
## Resisting arrest
The disposed do not go quietly (`WouldResist`, seeded nature × nurture):
- **Comply** → taken in cleanly (they become a prisoner of the colony — imprisonment is direct, and it
survives guest-management mods like Hospitality).
- **Resist** → the violent turn **berserk**, the rest **flee**. A botched arrest becomes a crisis the
colony must handle the hard way, and openly defying arrest emboldens the lawless.
- **Subdued** → a resister the colony beats down is then **imprisoned** (auto-capture) — the resist
path resolves to a cell once the colony wins the confrontation. One who flees the map gets away.
## Prison riots
When the climate of order **collapses** (deterrence at the floor) in a colony holding prisoners, a
neglected prison boils over into a **riot**: disposed prisoners turn violent together, and the unrest
shatters order further. A well-run colony (high deterrence) never sees one — a riot is the thing a
badly-run institution *earns*. It ties the deterrence meter, the propensity engine, and the prison
population into one emergent event.
## Recidivism, made visible
The loop closes on itself: a pawn hardened in prison (negative reform) runs a higher propensity and
reoffends. When investigation names a culprit the colony had **paroled**, it says so out loud — the
recidivism loop turning in the open, the payoff for everything classification, discipline, and parole
did upstream.
---
Part of **Institution: Justice**, in the Institution suite. AI disclosure: developed with substantial
assistance from Claude (Anthropic).
+131
View File
@@ -0,0 +1,131 @@
# Regime
*The daily life of the held — and the one lever vanilla withholds.*
Most of what a prison regime needs, vanilla already gives you. The schedule is the Restrict tab. The
mood-driven disposition already flows through `Propensity.Nurture` — a neglected prisoner runs hotter
with no new machinery. So Regime does not rebuild any of that. It adds the single thing vanilla flatly
refuses to model: **recreation.**
---
## What vanilla does, and what Regime flips
Vanilla denies prisoners the **Joy** (recreation) need outright — the need is flagged `colonistsOnly`
and `neverOnPrisoner`, so it simply never appears on a prisoner. A caged pawn has no recreation bar,
cannot take joy from anything, and never suffers for its absence.
Regime flips exactly that one bit on, via a small Harmony postfix — the same approach the good, popular
**Prisoner Recreation** mod takes:
```csharp
[HarmonyPatch(typeof(Pawn_NeedsTracker), "ShouldHaveNeed")]
static class Patch_PrisonerRecreation
{
static void Postfix(NeedDef nd, Pawn ___pawn, ref bool __result)
{
if (__result || nd?.defName != "Joy") return; // only touch Joy, only when vanilla said no
if (___pawn?.RaceProps?.Humanlike == true
&& ___pawn.IsPrisonerOfColony)
__result = true; // humanlike prisoners get the need
}
}
```
Three guards, in order:
1. **`__result` already true** — vanilla or another patch already granted the need. Do nothing. This
is what makes the patch *additive*: it only ever turns a `false` into `true`, never the reverse.
2. **`nd.defName != "Joy"`** — this patch is about recreation and nothing else. Every other need is
left exactly as vanilla decided.
3. **humanlike prisoner-of-colony** — animals, guests, slaves and colonists are untouched; only a
humanlike prisoner of *your* colony gains the need.
That is the entire mechanism. Enabling recreation is trivial — once the need exists, vanilla does all
the rest (joy sources, the recreation bar, the mood effects of a full or empty one). The *value* is
not the plumbing; it is what an empty bar now costs.
---
## Why a need you can neglect is the point
Giving prisoners recreation is not a mercy toggle — it is a **lever with two ends**, and the down end
is the one that matters to the suite. Once a prisoner *has* the Joy need, they can be **starved** of
it, and vanilla's own machinery then does the work:
```
no recreation → Joy falls → mood falls → Propensity.Nurture rises → higher propensity
```
Every one of those arrows already exists. Regime only opens the first door; mood is wired to
disposition in Core, so a prisoner who gets no yard time stews, their mood sinks, and their Nurture —
and with it their odds on every "would they?" roll — climbs. From [Deterrence](Deterrence.md) and
[Discipline & Reform](Discipline-and-Reform.md) you already know Nurture is the multiplier the whole
system keys off; Regime is what lets *neglect* feed it.
Concretely, in Core's `Nurture`:
| Prisoner condition | Nurture contribution |
|---|---|
| Mood `< 0.20` (recreation-starved, at the floor of despair) | `× 2.5` |
| Mood `< 0.35` (badly kept) | `× 1.6` |
| Held **and** mood `< 0.40` (a badly run cell) | additional `× 1.4` |
A prisoner you give no recreation is a prisoner you are pushing up those brackets. Regime turns "I
didn't bother building a rec room" from a non-event into a disposition cost you pay on every roll.
---
## Idempotent with Prisoner Recreation
If you also run the **Prisoner Recreation** mod, nothing breaks. Both mods do the same thing — force
`ShouldHaveNeed` to return `true` for prisoner Joy — and because Regime's postfix only acts when
`__result` is still `false`, the two are simply *two postfixes that force the same `true`*. Whichever
runs first grants the need; the second sees it already granted and returns immediately. Running both is
harmless. Running either alone is sufficient. There is no double-need, no conflict, no load-order
sensitivity between them.
Regime announces itself at startup so you can confirm it loaded:
```
[Institution: Justice] Regime: prisoner recreation enabled.
```
---
## Content on top
Yard time, safety needs, and visitation are *content* on this foundation, not new machinery. Each of
them is just another thing that moves a prisoner's mood — and mood is already wired to disposition — so
they need only defs and jobs, not new systems. When they land, they will make a well-run regime feel
richer; the mechanical spine is already here in this one postfix.
---
## How to play with Regime
- **Build the rec room.** A prisoner with recreation settles; the mood brackets above stay off, and
their disposition sits near baseline. A cheap horseshoe pin or chess table earns its keep in crimes
that don't happen.
- **Neglect is a choice with a number.** Leaving prisoners with nothing to do isn't neutral — it drives
mood into the `×1.6` and `×2.5` Nurture brackets, and a hotter prisoner reoffends, which cools your
colony's climate of order, which heats *everyone*. The rec room is deterrence you build once.
- **Recreation and reform stack.** Regime cools disposition *live* (through mood); reform cools it
*permanently* (through [Discipline & Reform](Discipline-and-Reform.md)). A reformed prisoner in a
well-run wing is calm on both axes — which is exactly the pawn you can eventually [parole](Parole.md).
- **You don't need Prisoner Recreation too** — but if you have it, keep it. They coexist.
---
## For modders
Harmony ID `flan.institution.justice`, a single postfix on `Pawn_NeedsTracker.ShouldHaveNeed`. It is
the suite's *only* Harmony-using code — Contraband dropped its Harmony dependency after Justice was
split out. The patch class lives in the `Contraband` namespace (shared across the suite since the
extraction). The postfix is strictly additive (`false → true` only), so it is safe to stack with any
other mod that grants prisoner needs.
---
*Part of the **Institution** suite for RimWorld 1.6: Core · Contraband · Justice · Gangs. Developed
with substantial assistance from Claude (Anthropic).*