Open-World Narrative · Features

Production, Progression, World & Launch

A focused page within the Open-World Narrative Features documentation. The full map and every sibling page live in the Features hub.

6sections11 minread1diagram

On this page

Five ruleset cells on one Unreal Engine 5 spine is an engineering achievement; making a player invest in a Bureau operator across all five is a progression problem; building a 1947 noir city, a frontier of five biomes, and 32 star systems that each feel inhabited is a world problem; and capturing the faces, voices, and scores that dress all of it is a production problem the size of a studio. This page is the production-and-platform leg of V5's "Platform, Compliance & Production" group: the studio-ops capacity behind the content, the two-track progression that carries a player across cells, the open-world systems that make the maps live, and the single machine-checked gate that decides whether the result is allowed to ship. The honest distinction that governs every line below is the one the rest of the V5 catalogue carries — V5 ships zero cooked .uasset binaries; the tree is 74 C++ Source modules, 29 .uplugin manifests, and content-as-data. So the production capacity here is real logic and authored intent in machine-readable form, backed by real verification and real C++ systems, while the scanned faces, recorded VO, composed score, and cooked maps that would fill it are production-gated and not in-tree. And where some V-products carry a green launch aggregate, V5's is deliberately, honestly red — 17 of 17 blocking gates pending, releaseBlocked: true — because a prior revision once fabricated the green and the remediation tore it out. Each claim below is pinned to the C++ surface, the JSON manifest, or the Python gate that backs it, or labelled plainly where it is declared-but-uncooked. The orientation door and stand-in conventions every path here rides on are ./product-promise.md. The feature hub this page belongs to is ../V5_features.md.

What ships, honestly#

The progression, world, and production systems are real C++, not contract scaffolds. V5Persistence (V5/ue/Source/V5Persistence/) implements the cross-cell save router, the per-cell currency ledger, the New Game+ economy, and Save-Slot Archaeology as deterministic Blueprint function libraries with a backing test suite. V5Open implements weather, era-swap data layers, time-of-day, World Partition streaming, population, and HLOD rules against the real UDataLayerManager. V5FaceCapture implements the MotionScan-equivalent facial pipeline — blendshape stacks, MetaHuman binding, take linting, and FACS calibration — with domain-specific quality math. V5Audio carries the score, VO, and broadcast production budget as real routing and manifest logic. These are domain-specific systems a renamed-variable stub could not reproduce.

Three honest qualifications carry through the page. First, every authored artifact those systems describe — a scanned principal's 52-blendshape face, ~90 minutes of frontier score, a 140 km² Heist City — is declared by data and code and cooked by nothing; there are 0 .uasset files, so any claim that needs authored content is forward-looking by construction and labelled as such. Second, a few builder functions set production-completion booleans (bRecordingComplete, bCastingTeamAssigned) to true as manifest defaults — those record planned production capacity, not recorded audio, and the 0-.uasset reality is the cap on them. Third, the launch-readiness gate is red on purpose, and the machinery is built so the red cannot be forged: the validator fails closed, and the only verified quality signal to date is a single on-box automation run (298/298), not a green nightly pipeline.

Production: studio ops, mocap, VO, and composer#

V5's content scale is documented as real studio capacity — 4 body-mocap stages (LA, London, Vancouver, Tokyo), a 12-camera MetaHuman face stage at LA, 28 bespoke-scanned principals, 3 composers one per cell-cluster, and 12 voiced + 4 text-only language SKUs (the Sci-Fi player character fully voiced for both genders, ~38 000 lines each). The in-tree code is the pipeline that capacity would run through.

The facial-capture pipeline#

V5FaceCapture (V5/ue/Source/V5FaceCapture/Private/V5FaceCaptureSystems.cpp) is the MotionScan-equivalent interrogation rig in code, and its constants are domain-correct: RequiredMetaHumanBlendshapes = 52 and RequiredFACSUnits = 16. UV5_FaceCapture_USDLoader::BuildBlendshapeStack ingests a .usd take at a frame rate, frame count, blendshape-name set, and FACS-unit set; UV5_FaceCapture_MetaHumanBind::BuildMetaHumanBind then binds it to a MetaHuman rig and computes a BlendshapeCoverage as the min of blendshape and FACS coverage, marking the bind bCompatible only when coverage ≥ 0.95 and the stack runs at 60 fps (IsNearlyEqual(FrameRate, 60.0f, 0.1f)) — exactly the "60 fps .usd blendshape stacks" the features text promises. The UV5_FaceCapture_CalibrationTool::BuildCalibrationScript enumerates 8 facial action units (AU01_BrowInnerUpAU15_LipCornerDepress) at 120 minutes each, summing to the 16-hour FACS calibration session the production scope names. UV5_FaceCapture_RetakePipeline and …_TellTakeLinter score each take by a weighted rubric (frame-rate 0.25, blendshape coverage 0.35, FACS coverage 0.30, trim 0.10) and fail any take below the gate, and UV5_FaceCapture_VOSyncSubsystem::BuildVOSyncPlan only sets bFullLipsync when the facial/voice offset is within ±0.25 s — the seam between the 4 full-lipsync SKUs and the 8 lipsync-light ones.

The audio production budget#

V5Audio (V5/ue/Source/V5Audio/Private/V5AudioSystems.cpp) carries the score, VO, and broadcast capacity as routing and budget logic. MakeScoreBudget pins 8 hours of original score per cell with a score.<cell>.8h stem-pack id; MakeComposerEngagement records the per-cell-cluster composer contracts; MakePeriodBroadcastBudget declares the period broadcast inventory (18 radio stations, 140 TV channels); and BuildVoiceRoute emits per-cell MetaSound voice graphs with cell-tuned attenuation (40 m Sci-Fi, 28 m elsewhere) and priority (Mind Palace dialogue at 90). The honest seam is MakeVoLanguageCoverage, which sets bRecordingComplete and bCastingTeamAssigned to true — those are manifest defaults describing planned coverage, not proof of recorded sessions; no VO .uasset exists, and the localization lock is a separate launch gate (it lives with ./accessibility-localization-and-compliance.md). NIL and IP clearance gate any real-person likeness, trademark, and licensed music — documented as obligations, enforced at the clearance manifest, not yet exercised against cooked assets.

Progression: two tracks, account and character#

V5 progression runs on two tracks — per-character inside a cell, and per-account across cells — and V5Persistence plus the Bureau ledger in V5Core implement both as real save state, stored per account in Profile_<accountId>.json.

Bureau XP and the tier ladder#

The Cross-Continuum Bureau XP ledger is the account spine. FV5BureauXPLedger::RecalculateTier (V5/ue/Source/V5Core/Private/V5Types.cpp:42) computes CurrentTier = max(1, TotalXP / 2500 + 1) — a tier every 2 500 XP — and grants idempotent cross-cell unlocks at the exact thresholds the features text advertises: Tier 1 PhotoMode.AllCells, Tier 5 MindPalace.CrossEraPairs, Tier 10 CompanionApp.FullSync, Tier 20 NewGamePlus, Tier 30 Cosmetic.BureauGear.AllCells. The save router (UV5_Persist_SaveGameRouter::BuildManifest) enforces cross-cell consistency on every route: each cell slot must carry the current save version and point at the right profile slot, a Mind Palace slot must exist, and the Bureau ledger's account id must match the profile's — the manifest is only bCrossCellConsistent when all of that holds.

Per-cell currency, fail-closed#

UV5_Persist_CurrencyLedger::BuildStartingLedger seeds the cross-cell economy with cell-correct currencies — Urban 250 Cash, Period 125 Cash, Frontier 2 Gold, Hunter 80 Crowns, Sci-Fi 500 Credits, plus Bureau scrip in the Mind Palace — and ApplyTransaction is an append-only journal that rejects any debit that would drive a balance negative (recording the rejection rather than silently clamping), tracking LifetimeEarned/LifetimeSpent per balance. The public side of balance is the balance-ledger service (apps/v5/balance-ledger/contract.json): an append-only, designer-note-linked, telemetry-evidenced ledger on Postgres/Redis with a public-export capability — real contract surface whose publicBalanceLedgerLive flag is honestly false until the service is deployed, and which is itself a launch gate.

New Game+ and Save-Slot Archaeology#

The deepest progression code is the Year-1 New Game+ plan. UV5_Persist_NewGamePlus::BuildYear1Plan requires Bureau tier 20 and a completed campaign, covers all five launch cells, and is validated by ValidateYear1Plan against hard domain invariants: ≥2 authored story branches per cell (≥10 total), ≥3 difficulty modifiers per cell (≥15 total), every modifier scalar ≥ 1.0 so NG+ can only raise challenge, and bNoPaidPowerCarryover true. Carry-over domains are explicit (bureauXp, cosmetics, photoMode, mindPalaceOutcomesArchive, codex, workshopEntitlements); reset domains are equally explicit (criticalPathMissionState, cellEconomyBalances, wantedHeat, bountyDebt, factionMissionLocks) — so a second run keeps your identity and loses your shortcuts. On top sits Save-Slot Archaeology (UV5_Persist_SaveSlotArchaeology): 10 authored scenarios (two per cell) that read a prior save's ending flags (ending.urban.low-collateral, ending.scifi.alliance.independent, …) and, when matched, trigger the matching NG+ branch — your first ending literally reseeds your second beginning. Imports must be migrated to the current save version before they validate. Underneath it all, crash recovery (UV5_Persist_CrashRecovery::BuildPolicy) holds a 90-second autosave interval, an atomic temp-write, write-before-map-travel, and three save generations (Current/Previous/Fallback); replay packets carry an exact binary SHA-256 payload digest plus an externally keyed HMAC-SHA256 signature, expiry, and single-use nonce over every frame and security-relevant field.

The open world: weather, eras, and streaming that bite#

The maps themselves are content-gated (no cooked geometry exists), but the systems that make them live are real V5Open code over UE5 World Partition. The signature maps are declared in the features text — Urban's 16 districts across ~140 km² Heist City plus the ~22 km² Street Triad world, Period's one 1947 city seen across three eras, Frontier's 5 biomes, Sci-Fi's 32 systems with ~120 bodies (PCG planetary detail), Hunter's 4 regions — and the runtime that would drive them is implemented now.

Weather is gameplay, not cosmetic#

UV5_Open_Weather (V5/ue/Source/V5Open/Private/V5OpenWeather.cpp) models seven states — Dry, LightRain, HeavyRain, Snow, Fog, DustStorm, SolarFlare — each binding to a World Partition data layer activated through UDataLayerManager::SetDataLayerRuntimeState. Crucially, every state carries four gameplay modifiers: VisibilityScalar, TractionScalar, CrowdDensityScalar, and ClueLegibilityScalar. A DustStorm drops visibility to 0.24 and crowds to 0.35; Fog cuts clue legibility to 0.62; HeavyRain thins crowds to 0.48 and traction to 0.62 — and GetCurrentGameplayModifiers lerps between source and target during a transition, so a clearing storm hands visibility back gradually. This is the "weather affects visibility, traction, NPC behavior, and sense-mode clue legibility — not purely cosmetic" promise, implemented as numbers a feel test can assert.

Eras, day-cycle, and streaming#

UV5_Open_DataLayer_Era swaps the Period cell's 1930s/1947/1968 eras by activating the matching era data layer and unloading the rest — the same World-Partition mechanism, applied to time instead of weather, so Made Man and Vice Squad can share one city's geometry. UV5_Open_TimeOfDay pins a DayLengthRealSeconds = 48.0f * 60.0f constant — the 48-minute in-game day that drives NPC schedules and shop hours. And UV5_Open_StreamingSubsystem registers World Partition streaming sources (actor- and location-anchored, sorted by priority into FWorldPartitionStreamingSources) so a seamless open-world cell streams around the player; population and HLOD-rule modules sit beside it. The persistent-world economy that layers over the maps is deterministic-given-seed save state, simulated coarsely while a cell is inactive.

Launch readiness and exit criteria (honestly red)#

§90 aggregates the entire product — cells, modes, localization, cert, compliance, quality, online, and live-service — into one go/no-go, and it is the page's load-bearing example of fail-loud honesty. V5/release/launch-readiness-manifest.json (schemaVersion: 2) tracks 17 blocking gates, and today every one reads pending: passedGates: 0, cellsComplete: 0, languagePacksLocked: 0, platformsCertPassed: 0, releaseBlocked: true, greenBuildId: null. Its correctionNote is blunt about why — a prior revision fabricated a shippable game (17/17 gates passed, a 99.72% crash-free rate over 125 000 PS5 sessions, nine cert passes, a completed accessibility audit) with no build, hardware, sessions, or external engagements behind any of it. V5/REMEDIATION_2026-06-12.md reset it, moving the backlog from 905 [x] to 875 [x] and promoting zero marks to done; it records that "the only verified quality signal to date is the one-off 2026-05-31 on-box automation run (298/298 after remediation); no green nightly pipeline exists."

The gate cannot be hand-edited green#

V5/tools/release/validate-launch-readiness.py (399 lines) fails closed, and its core is a require_gate_not_passed helper that refuses a passed status without backing evidence. releaseBlocked: false requires every gate passed and a real greenBuildId; a cert-passed platform needs memoryWithinBudget plus an existing certEvidencePath on disk; a "complete" accessibility audit needs a real named consultant ("TBD" is rejected); the crash-free gate needs a cohort ≥ 100 000 with a rate above 99.5%; and a regex stub-scan walks the runtime tree (V5/ue/Source, V5/ue/Content, apps/v5/web/src, apps/v5) for coming soon|not implemented|lorem ipsum|todo|fixme|tbd. It also composes the cell, performance-budget, and live-service validators, so a regression in any of them blocks launch. FV5LaunchReadinessManifestTest (V5.Tests.LaunchReadiness) mirrors the fail-closed logic in C++ — its own comment records that it once hardcoded the fabricated 17/17 and now validates internal consistency instead.

flowchart TB subgraph prod["Production & content systems"] face["V5FaceCapture<br/>52 blendshapes · 16 FACS · 60fps"] audio["V5Audio<br/>8h score/cell · 18 radio · 140 TV"] world["V5Open<br/>7 weather states · era swap · 48-min day"] end subgraph prog["Progression"] bureau["Bureau XP · tier = XP/2500+1<br/>unlocks @ 1·5·10·20·30"] ngplus["NG+ @ tier 20<br/>10 branches · 15 modifiers · no paid power"] ledger["balance-ledger service<br/>publicBalanceLedgerLive: false"] end prod --> AGG prog --> AGG manifest["launch-readiness-manifest.json<br/>17 gates · all pending"] --> AGG AGG{"validate-launch-readiness.py<br/>(399 lines · fail-closed)"} comp["composes validate-cells ·<br/>perf-budgets · live-service"] --> AGG AGG -->|"0 / 17 passed · no greenBuildId"| red["releaseBlocked: true (today)"] AGG -.->|"only with on-disk evidence<br/>+ real build id"| green["green = ship"] zerouasset["0 .uasset · 29 .uplugin<br/>caps every cooked claim"] -.-> red

Exit criteria vs. the point-in-time gate#

The §"V5 Exit Criteria" list is the standing bar for "done": every § in V5_TODOS.md checked against real source, a zero-hit adversarial stub-scan across all modules, the nightly Gauntlet green for 7 consecutive days, all 9 platforms cert-passed, all 16 language packs through localization QA, and the cross-cell Mind Palace deduction graph validated end-to-end with the cross-era arc playable to all endings. Launch readiness is the point-in-time gate for "ready to ship to the public." A build may meet exit criteria before every operational launch item (event scheduling, marketing) is complete — but it may not launch before both are satisfied. The day-one event is already authored (event.s01.day-one.continuum-signal, 30 days, scheduled) and the cross-validating C++/Python checks are real; what is honestly absent is the seven-day green nightly, the cooked content, and the external evidence — and the gate is built to keep saying so.

Where this connects#

  • ./accessibility-localization-and-compliance.md — the WCAG audit, the 16 language-pack lock and per-language QA, the parental/age-gating and ratings reviews, and the DSAR/privacy flows that several of this page's launch gates (localization.*, accessibility.audit.pass, compliance.*) cross-check.
  • ./product-promise.md — the orientation door, the 74-module / 0-.uasset / 29-.uplugin convention, and the spec-vs-disk discipline behind the declared-but-uncooked caveats above.
  • ../architecture/observability-performance-testing-content-pipeline.md — the architecture companion: the performance-budget gate, the Gauntlet driver and feel-test catalog, the content-as-data accounting, and the same fail-closed launch-readiness validator read in engineering depth.
  • The feature hub: ../V5_features.md.