Wiki: player-facing rewrite of every layer + add a scenario FAQ, linked from Home

This commit is contained in:
flan
2026-07-16 02:18:25 +00:00
parent ff703271ba
commit 8250dcb369
32 changed files with 1654 additions and 2510 deletions
+31 -49
View File
@@ -9,27 +9,22 @@ suite can *see* and *police*.
## Who is a rival
```
AreRivals(a, b):
ga = GangOf(a); gb = GangOf(b)
return ga != 0 && gb != 0 && ga != gb
```
The definition is exactly as blunt as it reads: **two pawns in two different gangs are rivals.** Both
must actually be in a gang (a non-zero id), and the ids must differ. From the source:
The rule is exactly as blunt as it sounds: **two pawns in two different gangs are rivals.** Both must
actually be in a gang, and it must be a *different* gang for each. As the design puts it:
> Two pawns of DIFFERENT gangs are rivals — inside the wire or out on the street.
Note what is *not* required. There is no separate "hostility" flag, no rival-declaration event, no
threshold to cross. The moment two crews exist, their members are rivals of one another. Rivalry is a
structural fact about the membership map, not a mood or a relationship value.
structural fact about who is in which gang, not a mood or a relationship value.
Two consequences fall straight out of that:
- **Non-members are nobody's rival.** A pawn with gang id `0` — everyone in a healthy colony — is never
a rival to anyone, because `AreRivals` requires both ids non-zero. No gangs, no rivalry.
- **Same gang, never rivals.** Members of one crew fail the `ga != gb` test. Within a gang there is no
rivalry to book; there is the network (see [Networks and Smuggling](Networks-and-Smuggling.md)).
- **Non-members are nobody's rival.** A pawn in no gang — everyone in a healthy colony — is never a
rival to anyone, because rivalry needs *both* pawns to be in a gang. No gangs, no rivalry.
- **Same gang, never rivals.** Members of one crew are in the *same* gang, so they are not rivals.
Within a gang there is no rivalry to book; there is the network (see
[Networks and Smuggling](Networks-and-Smuggling.md)).
Where do two *different* gangs come from in the first place? From the affiliations pawns already have —
rival factions and rival ideoligions form into separate crews. That is the subject of
@@ -38,44 +33,33 @@ with the colony's existing social fault lines, so **rival factions run as rival
## A fight is a crime
The payoff of tracking rivalry is `RecordFight`. When a rival-gang attack happens, it is not treated as
generic brawling — it is booked as a crime through the same Justice pipeline as any other offence.
The payoff of tracking rivalry is what happens when rivals fight. When a rival-gang attack happens, it
is not treated as generic brawling — it is booked as a crime through the same Justice pipeline as any
other offence.
```
RecordFight(attacker, victim):
if attacker == null || victim == null: return
if !AreRivals(attacker, victim): return -- only rival-gang violence counts
Justice.RecordCrime(attacker)
```
Only rival-gang violence counts: the two pawns must be in different gangs for anything to be recorded.
A scuffle between gangmates, or between two non-members, is not a *gang* fight and is not booked. When
it *is* rival-gang violence, the whole event is recorded as a crime against the **attacker**, and that
does three things at once (they live in Institution: Justice, but this is what Gangs is leaning on):
So the guard is precise: the two pawns must be **rivals** (different gangs) for anything to be recorded.
A scuffle between gangmates, or between two non-members, is not a *gang* fight and is not booked here.
When it *is* rival-gang violence, the whole event routes through one call — `Justice.RecordCrime`,
against the **attacker** — and that single call does three things at once (it lives in Institution:
Justice, but this is what Gangs is leaning on):
| Effect of `Justice.RecordCrime(attacker)` | Owner |
| Effect of booking a gang fight | Where it lands |
|---|---|
| `crimesCommitted` on the attacker's record goes up | Core's `CriminalRecord` |
| `lastCrimeTick` is stamped to now | Core's `CriminalRecord` |
| the colony's **deterrence** nudges **down** (a crime happened; order slipped) | Justice's `MapComponent_Deterrence` |
The mod's integration test confirms the loop end to end: it builds two rival gangs, records a fight,
and asserts both that the attacker and victim *are* rivals and that the attacker's `crimesCommitted`
went up as a result.
| the attacker's crime count goes up | their criminal record (Core) |
| the time of the crime is stamped to now | their criminal record (Core) |
| the colony's **deterrence** nudges **down** (a crime happened; order slipped) | Justice's deterrence system |
## Inside the wire and out on the street are the same offence
This is the design point the source is emphatic about:
This is the design point the mod is emphatic about:
> A gang fight is a CRIME — it goes on the attacker's record and moves the colony's climate through
> the same Justice loop as any other, so it can be investigated, attributed and policed. Rival-gang
> violence inside a prison and out on the street are the same offence.
There is no separate code path for a prison-yard shanking versus a colonists' brawl in the dining
room. `RecordFight` reads only `AreRivals` and calls `Justice.RecordCrime`. A free colonist who is a
gang member attacking a rival is booked identically to a prisoner doing the same in a cell block. The
gang system does not care which side of the wall the violence is on — only that it was between rivals.
There is no separate rule for a prison-yard shanking versus a colonists' brawl in the dining room. A
fight is booked purely on whether the two pawns are rivals. A free colonist who is a gang member
attacking a rival is booked identically to a prisoner doing the same in a cell block. The gang system
does not care which side of the wall the violence is on — only that it was between rivals.
This is what makes gang violence *legible* to the rest of the suite. A fight is not a one-off flavour
event that scrolls past in the log; it is a record entry with an attributed perpetrator and a timestamp,
@@ -85,19 +69,18 @@ which means it can be investigated, blamed on a specific pawn, and answered.
Here is the loop that closes the whole suite:
1. A rival-gang fight fires `RecordFight` → `Justice.RecordCrime(attacker)`.
1. A rival-gang fight is booked as a crime against the attacker.
2. That nudges the colony's **deterrence down**. Order has visibly slipped.
3. Lower deterrence *raises* the nurture multiplier for **every** disposed pawn on the map
(deterrence scales nurture via `×Lerp(1.3, 0.7, deterrence)` — less deterrence, bigger multiplier).
4. Higher nurture pushes more pawns over the `Nature × Nurture ≥ 0.9` join bar (see
3. Lower deterrence *raises* the nurture multiplier for **every** disposed pawn on the map (less
deterrence means a bigger multiplier).
4. Higher nurture pushes more pawns over the Nature × Nurture ≥ 0.9 join bar (see
[Joining](Joining.md)).
5. More members → more rivals → more fights available to be booked.
Left unanswered, gang violence is self-reinforcing: each booked fight makes the next one likelier. The
brake is the other half of Justice — **punishment raises deterrence back up** (`RecordPunishment`
nudges it up), which lowers nurture, which drops borderline pawns back under the bar. The integration
test checks exactly this seesaw: a punishment raises the deterrence level, and a subsequent crime
lowers it again.
brake is the other half of Justice — **punishment raises deterrence back up**, which lowers nurture,
which drops borderline pawns back under the bar. The seesaw works both ways: punishing a pawn raises the
deterrence level, and a fresh crime lowers it again.
## How to play it
@@ -113,4 +96,3 @@ lowers it again.
---
*Part of the **Institution** suite — Core · Contraband · Justice · Gangs (this). Each mod stands alone; together they are one system.*
**