# The Period-Drama Cell

This is V5's narrative-anchor cell — the Mafia / L.A. Noire surface where the
moment-to-moment loop is **drive a period car through a hand-built city, climb a
crime-family ladder, work a crime scene, and read a lie off a witness's face**.
It is the genre that lives or dies on _texture_: whether a 1947 sedan with drum
brakes and a three-on-the-tree column shift feels like 1947 and not a re-skinned
modern coupe; whether the bebop on the AM dial belongs to the year; whether the
neon over a department store, the slang the newsboy shouts, and the cut of a
detective's suit all agree that you are standing in one specific decade. The
period cell's signature is not a combat verb at all — it is **time itself**. One
authored city wears three decades (1930s, 1947, 1968), and two
progression-driven campaigns are played over it from opposite sides of the law
in the same week.

The cell ships as one genuine mechanic module plus two campaign modules composed
over it: an era-and-authenticity engine (**`V5PeriodAuth`**), a Mafia-trilogy
crime drama (**`V5PeriodMadeMan`**), and an L.A.-Noire detective procedural
(**`V5PeriodViceSquad`**). The promise is **the same city, three decades, two
games — without re-authoring the world**: Made Man's 1947 chapter and Vice
Squad's entire campaign share the _same_ World-Partition tiles and the _same_
period-authenticity bundle, seen once as a rising mobster and once as the
homicide detective working the bodies that mobster leaves behind. This page
inventories what that stack actually does on the player's side of the screen,
and points at the exact Unreal C++ behind each feature. For the full mode
taxonomy, the roster, and the scope this slots into, start at the hub:
[../V5_features.md](../V5_features.md).

## What ships, honestly

**The cell's modules are real, compiled, and value-tested.** Each of
`V5PeriodAuth`, `V5PeriodMadeMan`, and `V5PeriodViceSquad` exists under
`V5/ue/Source/` with a `Public/`/`Private/` split, a `*.Build.cs`, and a
`Private/Tests/` automation spec, and the linker has been through them on this
box: `libUnrealEditor-V5PeriodAuth.so`, `-V5PeriodMadeMan.so`, and
`-V5PeriodViceSquad.so` all sit in `V5/ue/Binaries/Linux/` next to their
sources, built by the `ueagent` user. The signature logic is real
domain-specific code — a continuity-guarded World-Partition era flip, a two-axis
loyalty resolver, a four-grade desk-rating rollup, a fail-loud period-evidence
gate — and each is pinned by UE `IMPLEMENT_SIMPLE_AUTOMATION_TEST` assertions
that check _values_, not truthiness (the three specs carry **22 + 53 + 60**
assertions, e.g.
`TestEqual("78 missions are authored", Catalog.Missions.Num(), 78)` and
`TestEqual("Modern tool rejection is explicit", …RejectionReason, "period_tools.required")`).

**The data is C++/JSON catalogs; the art is not in-tree.** Consistent with the
rest of V5's 0-binary-`.uasset` accounting, the bundle that drives the era
machine ships as version-controlled JSON at
`V5/ue/Content/V5PeriodAuth/Data/period_auth_bundles.json`, and **84 period
vehicle-tuning descriptors** already live under
`Content/V5Vehicles/Tuning/Period/period_{30s,47,68}_*.vehicle-tuning.json`. So
the _logic and balance_ of every signature system is real, while the MetaHuman
witnesses, the era-correct meshes and signage, the MotionScan blendshape
captures, and the Sequencer interludes those catalogs reference by
`FName`/`FSoftObjectPath` are described, not cooked. Where a claim depends on
that art, this page says so.

**"Cell" here means one era engine plus two catalog-and-validation campaigns.**
Unlike the urban-crime cell's three-way variant split, the period cell's depth
is front-loaded into `V5PeriodAuth` — a genuine per-frame-adjacent mechanic —
while the two campaign modules are heavier on **catalog assembly and
`Require(...)` shape-gating over large authored datasets** than on novel
algorithms. The honest consequence is two real seams: **`V5PeriodViceSquad` is
the case-and-kit author, not the interrogation runtime** — its `Build.cs` pulls
in `V5Interrogation`, `V5Investigation`, and `V5FaceCapture`, and the
frame-critical verbs (the truth/doubt/lie call, the face tells, the Mind-Palace
deduction graph) live one layer down in those shared modules; and **the
data-layer flip computes a transition _plan_, not the streaming itself** — it
decides which World-Partition layers to enable and tear down, but the cooked
tiles and the actual stream-in are engine and art. Both facts are true at once,
and the sections below keep them distinct.

## The period-drama experience — what the cell plays like

Strip the two campaigns apart and you get one city seen twice. Made Man is a
linear, cinematic generational crime saga that walks the same family bloodline
through 1930s, 1947, and 1968; Vice Squad is a 1947 detective procedural — case
desks, crime scenes, interrogations, partner banter — set in the _exact same_
1947 streets as Made Man's middle chapter. Both lean entirely on the
period-authenticity engine to look and sound like their year.

### Made Man — three eras, one bloodline

`V5PeriodMadeMan` (which composes `V5PeriodAuth`, `V5Vehicles`, and `V5Audio`)
is the Mafia surface, and its `UV5_MadeMan_Catalog::BuildCampaignCatalog`
(`V5/ue/Source/V5PeriodMadeMan/Private/V5PeriodMadeManSystems.cpp`) is a
validator-enforced content spine. `ValidateCampaignCatalog` refuses anything but
**four protagonists, 78 missions (exactly 26 per era), six chapter endings, a
four-rung hierarchy, 84 period vehicles (28 per era), and six revenge/honor
arcs**. The bloodline is authored, not generic: Matteo Bellante is the 1930s
family-immigrant founder, Vincent the 1947 made-man son, Luca the 1968
disillusioned grandson, with Rosa stepping in as counselor for the late 1968
missions (`PrimaryProtagonist` switches to her at mission ≥ 19). Each chapter
runs the same 26-mission cadence, where `MissionKindForNumber` seeds revenge
beats at missions 6/13/20, honor beats at 8/15/22, and Sequencer cinematic
interludes at 5/10/16/21/26 — and every fourth mission (plus the chapter finale)
carries a `CinematicInterludeId`, which the validator refuses to leave empty.

The era texture is real data, not a label. `BuildVehicles` authors a per-era
fleet whose handling flags _are_ the decade: a 1930s car gets `bDrumBrakes` and
`bManualChoke` and tops out near **55 mph**; 1947 climbs to **80**; 1968 gets
`bPowerSteering` and **110 mph** — and only 1930s vehicles set
`bRadioCapable = false`, because the AM radio is one era younger than the
founder. `BuildRadios` matches that arc with six stations — big-band/swing and
news in the 1930s, bebop and blues in 1947, soul/Motown and psychedelic rock in
1968 — each carrying a real `FV5AudioPeriodRadioMetaSound` built by
`UV5_Audio_PeriodRadio::BuildPeriodRadioMetaSound`. The spec proves the
discipline directly: `TestTrue("1930s radio is AM-only", …)`,
`TestTrue("1968 radio supports FM", …)`, and a 1930s vehicle that must report
`bDrumBrakes` and a top speed `>= 55.0f`.

### Vice Squad — the other side of the 1947 street

`V5PeriodViceSquad` is the L.A. Noire surface, and its `Build.cs` is a who's-who
of the shared narrative spine (`V5FaceCapture`, `V5Interrogation`,
`V5Investigation`, `V5PeriodAuth`). The campaign is **25 cases across five
desks** in canonical period order — Patrol → Traffic → Homicide → Vice → Arson —
each desk fronted by a named captain and a different partner whose drive-time
banter (`BuildPartnerBanter` seeds 12 drive lines and 5 clue-drops per desk)
fills the space between scenes. Crucially, `BuildCityDefinition` pins the city
to `period.city.1947.shared` on data layer `DL_Period_1947` with the
`shared.made_man.1947` World-Partition tag and eight districts (Central,
Hollywood, Wilshire, Westlake, Harbor, Valley, Chinatown, Industrial) — the same
tiles Made Man's 1947 chapter occupies. The validator demands that shared-city
shape outright
(`Catalog.City.CityId == "period.city.1947.shared" && … && DistrictIds.Num() >= 8`).

The defining Vice Squad verbs are diegetic and period-bound. Every one of the 25
cases pushes notebook clues into the cross-cell Mind Palace (each case authors
four `FV5InvestigationEvidenceNodeEvent` rows, the fourth flagged `bFalseClue`
with `bNoPenalty`), and the validator enforces
`Case.MindPalaceEvents.Num() >= 1` for _every_ case. The marquee inheritance —
MotionScan interrogation — is authored as **50 interrogation scenes** (two per
case), each with three questions in a fixed truth gradient (Withholding → Lying
→ Truthful) where the _Lying_ question binds a `RequiredEvidenceId` and a face
`TellId` drawn from a twelve-tell library; the kit manifest pins
`TellCount == 12` and a face-capture calibration script of
`TotalHours >= 16.0f`. The interrogation _runtime_ lives in the shared
`V5Interrogation`/`V5FaceCapture` modules; Vice Squad authors the scenes and
asserts the kit's shape.

## The period systems — the era machine, loyalty, and the case desk

Three clusters carry the cell: the era-and-authenticity engine every period mode
sits on, Made Man's rank-and-loyalty progression, and Vice Squad's
desk-rating-and-evidence loop. The first is a genuine mechanic; the other two
are legible reputation/grading engines wrapped in validated catalogs.

```mermaid
flowchart TB
    subgraph ERA["V5PeriodAuth — the era machine"]
        Bundle["3 era bundles<br/><sub>1930s · 1947 · 1968</sub>"]
        Flip["BuildDataLayerFlip<br/><sub>enable target · disable others · bContinuitySafe ≥2</sub>"]
        Lint["AssetLinter<br/><sub>DeclaredEra == BundleEra + membership</sub>"]
        Bundle --> Flip & Lint
    end
    MM["V5PeriodMadeMan<br/><sub>78 missions · soldier→boss · loyalty FamilyStanding/BetrayalRisk</sub>"]
    VS["V5PeriodViceSquad<br/><sub>5 desks · 25 cases · 50 interrogations · period evidence</sub>"]
    ERA --> MM & VS
    VS --> Shared["V5Interrogation · V5Investigation · V5FaceCapture"]
    VS -->|every case| MP["V5MindPalace<br/><sub>shared deduction graph</sub>"]
    MM & VS -->|FamilyRep · OutsiderRep · case rating| Honor["V5Honor<br/><sub>MoralCompass — period ×2 weight</sub>"]
    Honor --> Ledger["FV5BureauXPLedger<br/><sub>tier = TotalXP/2500 + 1</sub>"]
    Wanted["V5Wanted<br/><sub>Period1930s/47/68 era response</sub>"] -.-> MM & VS
```

### Period-Authenticity — a data-layer era machine with a linter

`V5PeriodAuth` is the abstraction that makes "the same city, three decades"
cheap, and it is the cell's real mechanic. An `FV5PeriodAuthBundle` for each era
(`EV5PeriodAuthEra`: `Era1930s`/`Era1947`/`Era1968`) bundles vehicles, fashion,
signage, fonts, slang, music, food, a radio-station set, lighting overrides, a
`DataLayerName`, a body-language library id, and a full UI font/palette/accent
set — the 1947 bundle, for instance, declares `neon_red` as its accent, the
value the spec checks. The load-bearing verb is
`UV5_PeriodAuth_DataLayerFlip::BuildDataLayerFlip`: it computes the
World-Partition transition by enabling the _target_ era's layer and disabling
every _other_ era's layer, and it only reports `bContinuitySafe` when the source
and target differ, the active layer is named, **and at least two other layers
are being torn down** — a real guard against shipping a half-swapped world where
1947 neon hangs over a 1968 muscle car. The flip also carries a short
`CameraFadeSeconds = 0.25f` to mask the swap, exactly as the spec pins it.

The loader is genuinely defensive. `ValidatePeriodAuthJson` requires
`schemaVersion == 1`, _exactly three_ era bundles
(`BundleCount != 3 || Eras.Num() != 3` is an error), a non-empty tagged-asset
set, and a passing asset linter. That linter,
`UV5_PeriodAuth_AssetLinter::LintPeriodTaggedAssets`, is the piece that keeps a
1968 prop out of a 1947 street: it flags any tagged asset whose
`DeclaredEra != BundleEra`, whose bundle is missing, or that isn't actually a
member of its bundle's category array (`AssetBelongsToBundle` special-cases the
radio set and body-language id, then checks the named `TArray<FName>` for
everything else). Around the flip sit two more real transforms — `BuildNPCSwap`
selects an era's body-language library, lead fashion set, and a
`barks.period.<eraId>` vocabulary; `BuildUIFlavor` projects the bundle's
font/palette/accent into the HUD — so the crowd's posture, the extras' clothes,
and the menu chrome all change with the decade. The bundle JSON is in-tree; the
meshes and montages it names are not.

### Made Man's ladder and its two-axis loyalty model

Two reputation systems drive the Mafia campaign. The first is the **made-man
hierarchy**: `BuildHierarchy` authors four rungs — Soldier (unlocks mission 1),
Caporegime (mission 8), Underboss (mission 17), Boss (mission 26) — each
carrying a `RequiredFamilyStanding` floor (0/25/55/80) and unlock tags (the
underboss gets `safehouse.mansion` and the union mission line).
`ResolveRankForMission` walks that ladder to gate mission availability, and the
spec verifies each promotion boundary by value (mission 8 → Caporegime, mission
17 → Underboss, mission 26 → Boss).

The signature runtime is `UV5_MadeMan_Loyalty::ApplyEvent`, a **two-axis loyalty
model** where every story beat moves `FamilyStanding` and `BetrayalRisk` in
opposition. `ProtectFamily` is **+18 standing / −6 risk**, `PayHonorDebt`
+14/−4, `SpareCivilian` +8/−10; but `BetrayCapo` is **−30 standing / +35 risk**
and `CauseCollateral` −16/+18, with `FinishRevenge` the morally mixed +10/+6.
Both axes clamp to `[0,100]`, and the resulting `EV5MMLoyaltyStage` resolves by
a strict threshold cascade: **`BetrayalRisk >= 70` overrides everything to
`Betrayed`**, else `FamilyStanding >= 75` is `Loyal`, ≥ 50 `Tested`, ≥ 25
`Trusted`, else `Outsider`. The six chapter endings fall straight out of this:
`ResolveEnding` matches the chapter's loyalty stage to one of its two authored
endings (family-intact vs. family-betrayal), and the spec proves the full loop —
a family-protecting event chain lands `Loyal` and resolves the loyal ending,
while a betrayal-heavy chain trips the risk override and resolves the betrayal
ending. The campaign also carries a Year-1 DLC catalog — a 1980s/1984 "Chapter
4" with 22 missions, eight named companions (Gina Caruso the driver, Eddie
Rinaldi the safecracker, …), and an FM/cassette-era authenticity bundle gated on
a `bPeriodResearchApproved` flag — all `ValidateChapter4Catalog`-shape-checked
with id-drift guards.

### Vice Squad's desk rollup, and the period-correct evidence gate

The detective campaign's progression is a clean grading engine.
`UV5_ViceSquad_Progression::RollUpDeskRating` scores each closed case on a
four-grade scale (`Brilliant`/`Good`/`Average`/`Poor` = 4/3/2/1), averages the
desk's cases, and maps the average back through `RatingFromAverage` (≥ 3.5 →
Brilliant, ≥ 2.75 → Good, ≥ 2.0 → Average, else Poor); `CanAdvanceDesk` then
gates the next desk behind that desk's minimum. The period's "branch-on-fail"
promise is real and load-bearing: `UV5_ViceSquad_CaseClosure::CloseCase`
_always_ sets `bGameOver = false` — a bungled case closes "with questions,"
downgrades the rating, and shifts partner/captain reactions rather than ending
the run — and it generates an in-fiction `CITY EDITION: … BY <DESK> DESK`
newspaper headline the player can pick up the next in-game day. The spec checks
all of it: a poor wrong- suspect closure still closes, never game-overs, isn't
marked solved, and still prints a headline.

The period _flavour_ is in the **evidence-retrieval methods**, and the cell's
sharpest fail-loud seam lives in the cold-case expansion. There are no databases
in 1947, so evidence comes from an `EV5VSEvidenceRetrievalMethod` of eight
period-correct sources — `EvidenceLocker`, `CoronerLedger`, `SwitchboardLog`,
`NewspaperMorgue`, `PropertyArchive`, `RadioDispatchTape`, `TrafficCitation`,
`SceneRevisit` — and `UV5_ViceSquad_ColdCases::EvaluateEvidenceRetrieval`
refuses to fabricate a success: it returns a typed `RejectionReason` for a
case-binding mismatch, a wrong retrieval method (`retrieval.method_mismatch`), a
request that reaches for modern tools (`period_tools.required`), or a missing
chain of custody (`chain_of_custody.required`), and only mints a Mind-Palace
node when every gate passes. The Year-1 cold-case catalog authors eight unsolved
1947 cases with 32 evidence rows covering all eight methods, each
`ValidateColdCaseCatalog`-checked down to the `source.1947.archive.*` and
`location.1947.cold_case.*` id prefixes.

### The full-vision Egyptian Detective sub-cell

`V5PeriodViceSquad` also hosts a self-contained, content-locked **1920s Egyptian
cold-case sub-campaign** — `BuildFullVisionEgyptianDetectiveCatalog` authors
**14 cases across three acts, five districts (Cairo Museum Quarter, Giza
Plateau, Luxor West Bank, Alexandria Docks, Saqqara Step Complex), 12
museum-cataloged artifacts, and seven suspects**, summing to a validated **840
campaign minutes and 18.5 km²** of playable area
(`FMath::IsNearlyEqual(PlayableAreaKm2, 18.5f, 0.01f)`). What makes it more than
a re-skin is the ethics built into the validator: every artifact must score
`AuthenticityScore >= 75` and be `bMuseumCataloged`, and every case is gated on
`bArchaeologyPermitRequired`, `bMindPalaceReconstruction`,
`bCulturalReviewRequired`, and — pointedly — `bNonLootingResolution`. It is a
fully shape-checked authored catalog; the dig sites and dynasty props it
references are descriptors, not cooked assets.

### Where the period cell meets the Bureau spine

The period cell spends the same cross-cell currency every V5 cell shares, just
on 1947 noir instead of a modern crime sandbox. Its law response is era-scaled:
`EV5WantedResponseEra` carries dedicated `Period1930s`, `Period1947`, and
`Period1968` variants, so the shared `V5Wanted` heat→stars curve spawns a
1930s/47/68 LAPD-equivalent response instead of the modern SWAT-and-helo
escalation. And the cell feeds the cross-cell moral compass with weight:
`UV5_Honor_KarmaParagonBridge::ComputeMoralCompass`
(`V5/ue/Source/V5Honor/Private/V5HonorSystems.cpp`) takes the period inputs
`FamilyRep`, `OutsiderRep`, and a `CaseRatingAverage` clamped to `[1,4]`, and
the normalizer **double-weights the period contribution** (`UrbanWeight +
PeriodWeight

- 2.0f +
  …`) — the made man's standing and the detective's case grades count twice as hard toward the single `MoralCompass`that drives the`FV5BureauXPLedger`(tier =`TotalXP/2500 +
  1`, in `V5/ue/Source/V5Core/Public/`). Being cleanly loyal or cleanly ruthless
  across the bloodline is mechanically rewarded — the same Bureau spine the
  urban cell rides, detailed in the architecture companion.

## Where this connects

The period-drama cell is one face of a single game, and it hands off at
well-defined seams:

- **The other narrative city.** The Urban-Crime cell shares the wanted curve,
  the honor bridge, and the Bureau ledger but spends them on a modern GTA
  sandbox and a Sleeping-Dogs undercover beat-'em-up — see
  [./urban-crime-cell.md](./urban-crime-cell.md).
- **The open frontier.** The Frontier cell reuses the same era-scaled wanted
  response and honor substrate for an 1899 western and its perfect-pelt hunting
  economy — see [./frontier-cell.md](./frontier-cell.md).
- **Architecture companion.** The `V5PeriodAuth` data-layer flip and linter, the
  made-man loyalty resolver, and the vice-squad desk rollup — in prose with line
  citations, alongside the Wanted/Honor/Bureau-ledger spine — live in
  [../architecture/hunter-period-systems-and-bureau-spine.md](../architecture/hunter-period-systems-and-bureau-spine.md).
- The feature hub: [../V5_features.md](../V5_features.md).
