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.
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.
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 singleMoralCompassthat drives theFV5BureauXPLedger(tier =TotalXP/2500 + 1, inV5/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.
- 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.
- Architecture companion. The
V5PeriodAuthdata-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. - The feature hub: ../V5_features.md.