# The Ruleset Cells: Overview

V5 makes a promise that sounds impossible the moment you say it out loud: one
Unreal Engine 5.5 open-world game that has to feel like _six different games_. A
Hong Kong triad brawl in a fish-market corridor, a 1947 noir interrogation where
a witness's eyes betray the lie, a 1899 outlaw chase across open frontier, a
Witcher-style contract hunt that starts at a posted notice and ends with the
right oil on the right blade, a Mass-Effect squad firefight resolved by a
dialogue-wheel interrupt, and a Newtonian two-ship duel that flips under thrust
to bring its torpedoes to bear — all in one executable, sharing one roster, one
perception model, and one cross-cell deduction graph. The unit that makes that
shippable instead of a marketing fantasy is the **ruleset cell**: a
self-contained gameplay framework with its own pacing, control scheme, camera
discipline, AI personality, HUD vocabulary, and audio identity, standing on a
shared engine spine it _specializes_ rather than forks. This page is the
orientation door to that model — what a cell is, how the six are built, how they
share the foundation, and exactly where the real code stops and the production
art begins. For the full per-cell feature catalogue it summarizes, start at the
hub: [../V5_features.md](../V5_features.md).

## What ships, honestly

**The cell skeleton is real, in-tree C++, and tested — the dressing is not.**
The engine's join key is one tiny enum, `EV5Cell`
(`V5/ue/Source/V5Core/Public/V5Types.h`), carrying seven values:
`Urban, Period, Frontier, Hunter, SciFi, Steampunk, MindPalace`. Every cell is
realized as a family of statically compiled `Source/` modules: the campaign
module (`V5UrbanHeistCity`, `V5PeriodMadeMan`, `V5FrontierOutlawTrail`,
`V5HunterWitchersPath`, `V5SciFiGalacticSquad`, `V5SciFiHardVacuum`, and a dozen
more) plus the shared per-cell systems it leans on. Each campaign module is a
**catalog-builder + validator** pair — a real, domain-specific pattern, not CRUD
— and each ships its own colocated `Private/Tests/` spec that asserts the
catalog's exact invariants.

Two honest qualifications run through everything below. **First**, the
architecture prose frames each cell as a hot-swappable `GameFeatures` _plugin_;
on disk the cell _code_ is a compiled Source module instead, and the matching
`Plugins/V5Mode_*` directories are content/manifest shells — all **29** carry
**zero `.cpp`**, declare `"EnabledByDefault": false`, and there are **zero
`GameFeatureData.uasset`** binaries in the tree. The cells are modular _by
source module_, not yet by _runtime feature_. **Second**, V5 is a
**logic-and-manifest skeleton**: `V5/ue/Content/` holds **0 `.uasset` and 1
`.umap`** against **393 JSON** authoring sidecars. So a cell's missions,
districts, ships, and monsters exist as validated _data_ and the systems that
consume them are real C++ — but the meshes, MetaHumans, mocap, VO, and
cinematics that would dress them are production-gated and absent. The honest
posture, traced in full by the architecture companion
[../architecture/promise-and-glossary.md](../architecture/promise-and-glossary.md),
is: the _systems_ are real; the _content_ is described, not baked.

## The ruleset-cell model

### One enum is the join key

The whole architecture turns on `EV5Cell`. It is the value that the save
document, the progression ledger, the perception tuning table, the mode
registry, and the deduction graph all carry, so that "which game am I in right
now" is a single typed answer the entire engine agrees on. `V5Core` exposes
`GetAllV5Cells()` (returning all **seven** values from `V5Types.cpp`),
`LexToString(EV5Cell)`, and `TryParseV5Cell` — and the seven-count matters,
because a per-cell dataset that sizes against a literal 5 or 6 desynchronizes
from the enum (the 2026-05-31 audit traced four automation failures to exactly
that mismatch). The save spine is cell-tagged at the seam: `FV5SaveDocument`
carries an `ActiveCell` field and a `CellSlots` map keyed per cell, and
`FV5BureauXPLedger` holds a `PerCellXP` map fed by `AddXP(EV5Cell, int32)`. Cell
identity is not a label on a menu — it is the primary key threaded through
persistence and progression.

### A cell is a catalog plus a validator

Open any campaign module and you find the same disciplined shape, not a renamed
shell. `V5UrbanHeistCity` exposes `UV5_UrbanHeistCity_Catalog`
(`Public/V5UrbanHeistCitySystems.h`), a `UBlueprintFunctionLibrary` whose
`Build*` methods author the cell as structured data — `BuildProtagonists`,
`BuildMainStoryMissions`, `BuildMainHeists`, `BuildDistricts`,
`BuildRadioStations`, `BuildAmbientEncounters` — and whose
`ValidateCampaignCatalog` enforces the cell's contract. That validator
(`Private/V5UrbanHeistCitySystems.cpp`) is where "real" lives: it _fails_ unless
there are exactly **3** protagonists, **32** main-story missions, **12** main
heists each with **4–6** setup missions and **3** ending bands, **90** rep-gated
side missions, **16** districts whose `PlayableAreaKm2` sums to **140.0**,
**18** radio stations, **140** TV channels, **240** ambient encounters, **1200**
talk-radio lines, a **5**-tier wanted escalation, and a switch cinematic of
**1.5 s**. The colocated `V5UrbanHeistCityTests.cpp` asserts every one of those
numbers with `TestEqual` — a spec that would collapse instantly against a
placeholder list. This is the pattern in every cell: real catalogs, real
invariants, real per-module automation. Honestly labelled: the campaign modules
are intentionally **thin** — six files each (catalog, systems, types, two
headers, one spec) — because the _verbs_ live one tier down in the shared
systems they depend on.

### How a cell specializes the engine

A cell does not re-implement gunplay or AI; it _composes_ shared modules and
contributes its narrow slice. The dependency edges are declared explicitly in
each `*.Build.cs` and they are real and one-way:

- `V5UrbanHeistCity → V5Core, V5Wanted`
- `V5PeriodMadeMan → V5Core, V5Audio, V5PeriodAuth, V5Vehicles`
- `V5FrontierOutlawTrail → V5Core, V5DeadEye, V5Honor, V5HorseAI, V5Hunting, V5Squad`
- `V5HunterWitchersPath → V5Core, V5Alchemy, V5Melee, V5MonsterHunt, V5Signs, V5Squad`
- `V5SciFiGalacticSquad → V5Core, V5Dialogue, V5Spaceship, V5Squad, V5StarMap`
- `V5SciFiHardVacuum → V5Spaceship`

Which cell's ruleset and HUD are actually live is the job of `V5Modes`:
`UV5_Mode_RulesetGate::EvaluateModeForTarget(ModePlugin, Target)` gates a mode
against the build target, `BuildHUDRoute(EV5Cell, ActiveModePlugin)` routes the
right HUD vocabulary, and `FV5ModeDefinition` carries an `EV5Cell Cell` so the
registry always knows which cell a mode belongs to. To stand up a cell you
supply: one `EV5Cell` value, one campaign catalog + validator, the cell's shared
system dependencies, one mode entry, and a feel test — and inherit the spine.

## A tour of the six cells

The prompt frames V5 as **six ruleset cells** — urban crime, period drama,
frontier, monster hunter, and **two** sci-fi flavours — and the disk bears that
out. Each is a distinct experience with its own inspiration, camera, and pacing,
yet all six descend from the same enum and the same shared modules.

| Cell                     | Campaign module         | Inspiration           | Distinctive shared systems              |
| ------------------------ | ----------------------- | --------------------- | --------------------------------------- |
| **Urban Crime**          | `V5UrbanHeistCity`      | GTA / Sleeping Dogs   | `V5Wanted`, `V5Heist`, `V5Parkour`      |
| **Period Drama**         | `V5PeriodMadeMan`       | Mafia / LA Noire 1947 | `V5PeriodAuth`, `V5Interrogation`       |
| **Frontier**             | `V5FrontierOutlawTrail` | Red Dead 1899         | `V5HorseAI`, `V5DeadEye`, `V5Honor`     |
| **Monster Hunter**       | `V5HunterWitchersPath`  | The Witcher           | `V5Alchemy`, `V5Signs`, `V5MonsterHunt` |
| **Sci-Fi (Squad RPG)**   | `V5SciFiGalacticSquad`  | Mass Effect           | `V5Dialogue`, `V5Squad`, `V5StarMap`    |
| **Sci-Fi (Hard Vacuum)** | `V5SciFiHardVacuum`     | The Expanse           | `V5Spaceship`                           |

**Urban Crime** carries the largest authored-content footprint of any cell — its
validator alone pins a 140 km² playable surface across 16 districts, three
switchable protagonists with simulated downtime, and an 18-station radio dial.
Its campaign module even encodes its roadmap as validated data:
`BuildYear1NewDistrictExpansionCatalog` and a forward-looking
`BuildFullVisionCyberpunkSubCellCatalog` are real catalog builders with their
own validators, honestly labelled as future-content definitions, not shipped
levels. For the deep dive, see [./urban-crime-cell.md](./urban-crime-cell.md).

**Period Drama** trades open chaos for paced authenticity: it depends on
`V5PeriodAuth` (per-era vehicle, font, prop, and slang bundles) and `V5Vehicles`
for period-correct driving, and its sister module `V5PeriodViceSquad` rides
`V5Interrogation` and `V5FaceCapture` for the LA-Noire truth/doubt/lie tells.

**Frontier** is the widest shared-system fan-out on the open-world side — its
`Build.cs` pulls in `V5HorseAI` (gait library, bonding, saddle inventory),
`V5DeadEye` (painted-shot slow-mo), `V5Honor` (persistent reputation/bounty),
and `V5Hunting` (the perfect-pelt skinning economy) — a frontier cell assembled
almost entirely from reusable parts.

**Monster Hunter** is the densest _systems_ composition: `V5HunterWitchersPath`
depends on five shared modules at once — `V5Alchemy`, `V5Melee`,
`V5MonsterHunt`, `V5Signs`, and `V5Squad`. `V5Alchemy` is itself a real 13-file
module (`UV5_Alchemy_ToxicitySystem::ApplyConsumableToxicity` and
`DecayToxicity`, `AV5_Alchemy_BrewingStation::BrewRecipe`), so the Witcher
contract loop — read the notice, investigate, brew the oil, fight the monster —
is wired through real toxicity and brewing math, not a façade.

**Sci-Fi (Squad RPG)** is `V5SciFiGalacticSquad`, leaning on `V5Dialogue`
(paragon/renegade wheel), `V5Squad` (companions and loyalty), and `V5StarMap`
(galaxy navigation). **Sci-Fi (Hard Vacuum)** is the standout for _systems_
depth: `V5SciFiHardVacuum` depends only on `V5Spaceship`, a 20-file module that
ships a real `AV5_Ship_NewtonianPawn : APawn` with `ConfigureShip` and
`SetNewtonianState`, an `FV5ShipClassDefinition` whose `RCSTorqueDegPerSecond`
defaults to `18.0f`, and `UV5_Ship_FlipAndBurn::StepFlipAndBurn` — genuine
Newtonian flight, not a renamed CRUD shell.

```mermaid
flowchart TB
    Enum["EV5Cell (V5Core) — the join key<br/><sub>Urban · Period · Frontier · Hunter · SciFi · Steampunk · MindPalace</sub>"]
    subgraph SHARED["Shared engine spine (write once)"]
        Core["V5Core<br/><sub>enum · save · BureauXP ledger</sub>"]
        Perc["V5Perception → V5Crowd → V5Schedules<br/><sub>suspicion 20/55/90 · panic · routines</sub>"]
        Modes["V5Modes<br/><sub>ruleset gate · HUD route</sub>"]
        Palace["V5MindPalace<br/><sub>cross-cell deduction graph</sub>"]
    end
    Enum --> SHARED
    SHARED --> U["Urban Crime<br/><sub>V5UrbanHeistCity → V5Wanted</sub>"]
    SHARED --> P["Period Drama<br/><sub>V5PeriodMadeMan → V5PeriodAuth</sub>"]
    SHARED --> F["Frontier<br/><sub>V5FrontierOutlawTrail → V5HorseAI · V5DeadEye</sub>"]
    SHARED --> H["Monster Hunter<br/><sub>V5HunterWitchersPath → V5Alchemy · V5Signs</sub>"]
    SHARED --> S1["Sci-Fi Squad<br/><sub>V5SciFiGalacticSquad → V5Squad · V5StarMap</sub>"]
    SHARED --> S2["Sci-Fi Hard Vacuum<br/><sub>V5SciFiHardVacuum → V5Spaceship</sub>"]
```

## Three honest cell counts

The "how many cells" question has three answers that are all correct in their
own frame, and the architecture companion is careful about this:

- **Five** is the marketing/promise count: Urban, Period, Frontier, Hunter,
  Sci-Fi.
- **Six** is what you get counting the two distinct sci-fi gameplay modules as
  separate experiences — `V5SciFiGalacticSquad` (squad RPG) and
  `V5SciFiHardVacuum` (Newtonian sim) — which is the framing this tour uses.
- **Seven** is the canonical engine count baked into `EV5Cell`: the five launch
  cells plus the **Steampunk** Brave New World Detective DLC cell
  (`V5SteampunkDetective`, [P3]) and the cross-cell **MindPalace** meta-layer.

The seventh enum value, `MindPalace`, is the important subtlety: it is _not_ a
sixth playable cell but a **meta-layer every cell feeds**. `V5MindPalace` (the
deepest module in the tree at 36 files) exposes `AddEvidenceNode`,
`AttemptDeduction(Graph, NodeA, NodeB, FV5BureauXPLedger)`,
`BuildHypothesisChain`, `MakeAccusation`, and a `CrossEraGate` — and the fact
that `AttemptDeduction` takes the shared `FV5BureauXPLedger` is the cross-cell
link made literal: evidence picked up by an outlaw in 1899 and a witness in 1947
can pair into one deduction, credited against the same roster's progression.
That cross-cell plumbing, plus the unified roster, perception, crowd, and
animation, is the subject of its own page:
[./shared-cross-cell-systems.md](./shared-cross-cell-systems.md).

## Sharing the engine, honestly

The reason six genres can cohabit one build is that the expensive,
correctness-critical machinery is written once and _tuned_ per cell rather than
duplicated. The clearest example is perception. A triad goon, a noir witness, an
outlaw, a drowner, and a station guard all read stimuli through the _same_
`V5Perception` state machine: `EV5PerceptionState` runs
`Idle → Curious → Alert → Hostile`, and a single `FV5PerceptionTuning` carries
the thresholds (`CuriousThreshold = 20.0`, `AlertThreshold = 55.0`,
`HostileThreshold = 90.0`, in `V5PerceptionTypes.h`). What differs per cell is
_tuning_, not the model:
`UV5_Perception_*::FindTuning(EV5Cell, EV5PerceptionNPCClass, ...)` resolves a
cell-and-class-specific tuning over the one shared brain, so a 1947 beat cop and
a frontier marshal escalate on the same curve with different sensitivities. The
same write-once-tune-per-cell discipline governs the roster, the crowd and
schedule subsystems, the animation rig, and the save spine — each detailed in
the [shared cross-cell systems](./shared-cross-cell-systems.md) page.

What the engine does **not** yet do is hot-activate a cell at runtime. The 29
`V5Mode_*` plugins that the architecture imagined as toggleable GameFeatures are
manifest shells today; the cell code compiles into the monolith and is gated by
`V5Modes` logic, but the binary `GameFeatureData.uasset` that would let a cell
be DLC-dropped or platform-stripped without a rebuild is unauthored. That gap is
named, not hidden — it is the single biggest honest correction the architecture
companion makes.

## Cell feel tests

Each cell ships a **feel test** — a curated in-game scenario that confirms the
cell hits its inspiration's hallmark — and these exist on disk as structured
fixtures, not prose. Under `V5/ue/Source/V5Tests/FeelTests/` are six cell
folders (`urban`, `period`, `frontier`, `hunter`, `scifi`, `mindpalace`), each
holding `*.feeltest.json` files with a `cell`, a `plugin`, a `runtimePath`, a
`sourceFeature`, and a list of `successCriteria`. The urban
`urban-heist-chase-swap.feeltest.json`, for instance, requires that a
two-protagonist control swap completes mid-chase "without visible streamed-world
hitch," that the wanted response escalates through its five bands, and that
passenger lean-out shooting holds aim across the swap. The feature catalogue
wires these into the nightly Gauntlet run so a failing feel test blocks the
affected cell's release — the per-cell quality gate, expressed as data the same
way the cells themselves are.

## Related

- The feature hub: [../V5_features.md](../V5_features.md)
- [The Urban Crime cell](./urban-crime-cell.md) — the deepest authored-content
  cell, Heist City + Street Triad over the shared open-world spine
- [Shared cross-cell systems](./shared-cross-cell-systems.md) — the roster,
  perception, crowd/schedule, and Mind Palace plumbing every cell rides
- Architecture companion:
  [../architecture/promise-and-glossary.md](../architecture/promise-and-glossary.md)
  — the 74-module split, the `EV5Cell` enum, the three cell counts, and the
  GameFeatures gap in full
