# 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. ### PolicingBootstrap — reconnecting the loop across the mod boundary Core keeps `Propensity.DeterrenceFactor` as a neutral seam — a `Func` 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, `PolicingBootstrap` fills the seam: ```csharp Propensity.DeterrenceFactor = pawn => { var d = pawn?.Map?.GetComponent(); 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().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 · Policing · Corrections · Gangs · Ward.*