Open-World Narrative · Features

Platform, Performance & Tech

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

5sections13 minread1diagram1table

On this page

V5 is one Unreal Engine 5 open-world narrative universe — five playable ruleset cells stitched together by a cross-cell Mind Palace — and it promises to run that ambition across nine launch platforms, from a PS5 Pro pushing 4K/120 down to an iPad Pro running a touch-only Mind Palace. This page is the cluster that turns that promise into something a platform holder can certify, an ops team can profile, and a player can drive on whatever silicon they own. It is also where V5's central honesty convention bites hardest. The repository is logic-and-manifest only: V5 ships zero binary .uasset files, and the game's modular content lives as 29 .uplugin manifests over 74 C++ modules. A repo with no cooked content cannot boot, cannot capture a GPU trace, and cannot stand in a cert lab — so a manifest that declares a 4K/60 frame budget or a passed TRC is declaration, not measurement, and this page says which is which on every line.

The boundary runs cleanly. Some of this surface is real, tested Unreal C++ — the World Partition streaming subsystem and the triple-redundant save-generation subsystem are substantive engine code with automation behind them, and the build targets (dedicated server, arcade cabinet, listen server) are real .Target.cs rules. Some is machine-checked policy over JSON — the per-platform performance budgets and the crossplay/cross-progression policy are each enforced by a Python validator and an independent reader, and both pass green today. The rest — cert checklists, the asset-size budget, VR/AR variants, peripheral curves, store mappings, the companion app, and the persistent-world economy — is authored intent in data, labeled as such wherever it appears. The section hub is ../V5_features.md.

What ships, honestly#

It is worth stating the boundary up front so nothing below is oversold.

  • Open-world streaming is real, validated C++. UV5_Open_StreamingSubsystem (V5/ue/Source/V5Open/Private/V5OpenStreamingSubsystem.cpp, 238 lines + an 82-line header) is a UWorldSubsystem that implements Unreal's IWorldPartitionStreamingSourceProvider, registers the player / companions / mission markers as prioritized streaming sources, and computes the mission-start pre-warm grid — real engine integration, not a description of one.
  • Save redundancy and crash recovery are real C++. UV5_SaveGameSubsystem (V5/ue/Source/V5Core/Private/V5SaveGameSubsystem.cpp) rotates three save generations (CurrentPreviousFallback), validates decrypt and JSON import on each, and recovers from a corrupt slot by rotating the first good generation back to current.
  • Performance budgets are a cross-validating gate, not decoration. V5/tools/performance/validate-performance-budgets.py (223 lines) checks the 11-profile catalog against exact budget tuples and re-parses each platform's .ini; the UE test V5.Tests.PerformanceBudgets independently asserts the same catalog in-engine. Both pass today.
  • Crossplay and cross-progression are machine-checked policy. V5/crossplay/crossplay-progression-policy.json is enforced by V5/tools/crossplay/validate-crossplay.py with a pytest harness that also runs a negative case. It passes today.
  • Build targets are real. V5DedicatedServer.Target.cs is a lean TargetType.Server that strips ~28 client-only plugins; V5ArcadeCabinet.Target.cs is a kiosk SKU with coin-op economy compiled out; V5ListenServer.Target.cs is the host-migration path.
  • Cert, store, VR/AR, peripherals, companion app, and the world economy are declared intent. They are honest checklist and entitlement data. A real TRC / Lotcheck / XR pass needs a cooked, bootable build the stand-in repo cannot produce — the same caveat the architecture companion ../architecture/observability-performance-testing-content-pipeline.md states in full.

Platform support, fidelity & certification#

Nine platforms, one catalogue — and the arcade cabinet SKU#

V5 targets PS5, PS5 Pro, Xbox Series X, Xbox Series S, Switch 2, Windows, macOS (Apple Silicon), Steam Deck / Linux, and iPad Pro M3+. The parity rule is that no cell, mode, or campaign is withheld behind a platform; the only principled reductions are hardware reality, and they are encoded rather than promised. The performance catalog marks the Switch 2 profile with hardVacuumCookExcluded: true — the Expanse-style spaceship cell is the heaviest load in the game (dynamic gravity plus crew sim), and the handheld drops it — and the iPad Pro M3+ profile carries Nanite "Disabled outside Mind Palace" and a TouchOnlyMindPalace restriction, so the tablet ships the cross-cell deduction surface rather than the full open world.

Beyond the nine consumer platforms, V5 cooks a distinct location-based SKU. V5ArcadeCabinet.Target.cs is a real game target that adds the compile definitions V5_ARCADE_CABINET=1, V5_LOCAL_COOP_CABINET=1, V5_CABINET_ONLINE_SERVICES=0, and V5_CABINET_COIN_OP_ECONOMY=0 — a four-player local-co-op cabinet that compiles online services and any coin-op economy out of the binary, packaged through its own Platforms/ArcadeCabinet/Config/ArcadeCabinetEngine.ini and profiled at 4K60. It cooks only a curated roster (Spec Ops Co-op, Horde Defense, Fleet Co-op, Hunter Card Game, Training Range) and hides open online/PvP rulesets behind the build-target gate.

Per-platform fidelity targets#

The fidelity story is per-platform and explicit, because a Switch 2 and a Windows-ultra rig do not share a frame-time reality. The launch-locked catalog at V5/ue/Content/V5Performance/Data/performance_platform_profiles.json (schemaVersion: 1, contentLock: "launch-v5") carries 11 budget profiles across 9 platform groups, each declaring its upscaler, GI and Nanite strategy, per-mode targets, and scalability knobs:

Platform group Modes (target / frame budget) Upscaler GI / Nanite
PS5 quality 30/33.3 ms · perf 60/16.6 ms TSR Full Lumen · Nanite
PS5 Pro quality 60/16.6 ms · perf 120/8.3 ms TSR Full Lumen · Nanite
Xbox Series X quality 30/33.3 ms · perf 60/16.6 ms TSR Full Lumen · Nanite
Xbox Series S quality 30/33.3 ms · perf 60/16.6 ms TSR Reduced Lumen · LOD-bias Nanite
Switch 2 quality 30/33.3 ms · perf 60/16.6 ms TSR mobile Reduced Lumen + SDF GI · Aggressive LOD
Windows (low / rec / ultra) 60/16.6 ms · 60/16.6 ms · 120/8.3 ms TSR · DLSS/FSR/TSR Reduced→Full Lumen
macOS Apple Silicon standard 60/16.6 ms MetalFX Full Lumen where supported
Steam Deck deck 30/33.3 ms FSR/TSR Reduced Lumen · LOD-biased
iPad Pro M3+ touch 60/16.6 ms MetalFX mobile Mobile GI · Nanite off outside Mind Palace

Memory budgets scale with the silicon — 8 GB on Series S, Switch 2, and the Windows-low tier; 12 GB on PS5 and Series X; 13 GB on PS5 Pro; 16 GB on macOS, Steam Deck, iPad, and Windows-recommended; and 32 GB on Windows-ultra. The per-mode rows are not round numbers picked for marketing: the Switch 2 quality mode is given a fatter 28 ms GPU slice (against PS5's 22 ms) because the handheld is GPU-bound and CPU-light, while its CPU budget drops to 5 ms.

Certification itself is the honest weak point: a real Sony TRC, Microsoft XR, Nintendo Lotcheck, or Steam Deck Verified pass requires a cooked build to boot, and this repo ships none. Cert status in V5 is therefore checklist intent, and the launch-readiness gate refuses to count a platform cert-passed without on-disk evidence behind it.

Performance budgets#

The cross-validating gate#

The catalog is enforced by two independent readers that must agree with the data and with each other — which is how a budget gets enforced rather than merely documented. validate-performance-budgets.py is the CI reader, and it does domain-specific verification a renamed-variable stub could not pass:

  • It checks the profile inventory against an explicit EXPECTED_PROFILE_IDS set and the exact (targetFps, frameBudgetMs, gpuBudgetMs, cpuBudgetMs) tuple for every profile/mode against an EXPECTED_BUDGETS table.
  • It asserts the special-platform flags — switch-2 reduced-Lumen + SDF GI and Hard-Vacuum cook excluded, macos-apple-silicon MetalFX, steam-deck Proton-verified, ipad-pro-m3 touch-only Mind Palace.
  • It requires profiledFrameP95Ms ≤ frameBudgetMs for every mode.
  • It then re-parses each platform's .ini (e.g. V5/ue/Platforms/PS5/Config/PS5Engine.ini) and confirms the [V5Performance.PS5] section's profileId, memory budget, upscaler, GI/Nanite strategy, regression suite, and every per-mode FPS / budget / resolution match the JSON. The PS5 .ini block carries quality.frameBudgetMs=33.3, performance.gpuBudgetMs=11.0, and so on — the engine config and the budget catalog are kept in lockstep by the gate.

The matching UE automation test, FV5PerformanceBudgetCatalogTest (V5.Tests.PerformanceBudgets, in V5/ue/Source/V5Tests/Private/Tests/V5TestsAutomation.cpp), independently loads the same catalog from the cooked content dir and asserts the 9 / 11 / 11 counts, that every profile's profiled p95 stays within its frame budget, that each profile blocks release through a regression suite, and that the four special-platform flags are set. Eleven regressionSuites mirror the eleven profiles, each blocksRelease: true and each bound to the Automation RunTests V5.Tests.PerformanceBudgets; Quit command.

What "profiled" honestly means here#

The honest caveat is precise. Each profile carries a profilingEvidence block that asserts status: "profiled-and-tuned", scenarioCount: 6, captureMinutes: 10, and a traceArtifact such as Saved/Profiling/V5/ps5.utrace. No such .utrace exists — it cannot, in a text repo with zero cooked content — and the validator does not claim it does: it checks the artifact path ends in .utrace and that the capture-minutes and scenario counts clear a floor. So the gate enforces the internal consistency and the budget math (every declared p95 sits under its declared budget; config and catalog agree), not a real GPU capture on real hardware. That is the correct shape for V5 today: the budgets are real engineering targets with real teeth against drift, and the profiling evidence is declared intent awaiting a cooked build.

Asset budgets and the zero-.uasset reality#

The features source publishes a per-cell asset budget — Urban Crime at 240 GB geometry / 1.6 TB 4K textures / 38 GB audio, Sci-Fi the heaviest at 280 GB / 1.8 TB / 42 GB — as the uncompressed authoring footprint, before Oodle compression and platform texture formats. These are planning estimates: with zero .uasset authored, there is no measured footprint behind them, and they are honest scope targets rather than a manifest of real bytes. The streaming and install mechanics they imply, by contrast, are concrete — World Partition cells, per-cell content roots so a reduced SKU ships without an omitted cell's budget, and chunked installs where a player can boot a cell's minimum-playable chunk before the rest downloads.

Technical features#

Open-world streaming: the real subsystem#

This is the load-bearing real code of the cluster. UV5_Open_StreamingSubsystem registers itself with the engine's UWorldPartitionSubsystem as a streaming source provider on Initialize and OnWorldBeginPlay, and unregisters cleanly on teardown. Gameplay code registers sources through RegisterStreamingActor (a source that follows an actor) or RegisterStreamingLocation (a fixed point), tagging each with a cell and an EV5OpenStreamingSourceKind of Player, Companion, or MissionMarker — exactly the "streaming sources are the player, companions, and active mission markers" the features doc names.

The priorities are real logic, not a constant. ResolvePriority returns Highest for the player, Normal for companions, and High for a mission marker — except in the Sci-Fi cell, where a mission marker is promoted to Highest because a hard-vacuum approach must stream the target before the player arrives at burn speed. GetSortedStreamingSourceDescriptors orders sources by priority, then kind, then name (a stable, deterministic sort), and GetStreamingSources hands the engine real FWorldPartitionStreamingSource objects with a radius converted from meters to centimeters, a debug color per kind, and the activated target state. The class also exposes GetPrewarmCellsForMissionStart(MissionCenter, CellRadius = 1), which floor-divides the mission center by the PartitionCellSizeMeters = 256.0f grid and returns the (2r+1)² block of FIntPoint cells around it — the implementation behind the "critical 3×3 cell area is pre-warmed at mission start" claim — and IsStreamingCompletedForV5Sources, which delegates to the engine's IsStreamingCompleted to gate a mission start on streaming readiness.

Save redundancy, crash recovery, quick-resume & patching#

Crash recovery is grounded in UV5_SaveGameSubsystem. A save is written across three generations — EV5SaveGeneration::Current, Previous, and Fallback — and the load path walks them in order: it reads each generation's envelope bytes, rejects a generation that fails decrypt or whose JSON fails UV5_SaveGame::ImportFromJsonString, logs the rejection, and on the first good non-current generation rotates it back to Current so the next launch is clean. That is the "triple-redundant (current, previous, fallback), corrupt save falls back to the previous generation" behavior, implemented rather than asserted, and because Mind Palace state is part of the save envelope, a deduction graph survives a crash. The same ImportFromJsonString seam backs the Save-Slot Archaeology flow that re-imports an older save into a New Game+ run.

The remaining recovery and update surface is documented process mirroring V4's pipeline: a single binary day-one patch, then chunked UnrealPak iterative delivery so a player downloads only changed chunks; CDN-served hot-fix data (balance values, UI strings, live-service data) fetched at session start with no binary patch; Xbox Series X|S Quick-Resume that revalidates session and online state on wake; and a DRM posture of signed-execution checks only, no Denuvo-equivalent, recorded in the decision log at V5/docs/decisions/0007-no-denuvo.md.

Server topology: dedicated, listen, and cabinet build targets#

V5 makes dedicated-server client-server netcode the default for open-world PvP and co-op, and the build targets make that real. V5DedicatedServer.Target.cs is a TargetType.Server that defines V5_DEDICATED_SERVER=1 and disables ~28 client-only plugins — Niagara, Metasound, the Chaos cloth/flesh modules, CommonUI, EnhancedInput, MetaHumanRuntime, PCG, the geometry and IK toolsets, and more — so the authoritative host compiles without rendering, audio, or input weight. V5ListenServer.Target.cs (V5_LISTEN_SERVER=1) is the peer-hosted path for the sub-2-second host-migration promise, and V5ArcadeCabinet.Target.cs is the offline kiosk. The deeper netcode authority and determinism design is owned by the architecture companion ../architecture/observability-performance-testing-content-pipeline.md and its netcode sibling.

Crossplay & cross-progression#

Cross-progression is machine-checked policy data today, not a running merge service. crossplay-progression-policy.json declares one canonical v5acct account with a single required account id, 9 platform credentials (Steam OAuth on Windows/Linux, Apple on Mac, Sign-in-with-Apple on iOS, PSN entitlement subjects, Xbox xuid, and a Nintendo Account), and four progression domains each with a named merge policy and offline reconcile: profile (last-verified-write-wins), cosmetics (entitlement union), bureauXp (monotonic ledger sum), and mindPalace (node last-writer-wins with accusations append-only). Default crossplay is on for all nine platforms with exactly one principled per-cell opt-out — Sci-Fi mode.scifi.spaceship-pvp, on high-precision-input parity grounds. A signed, encrypted companion save-transfer bundle carries those scopes plus saveGames between devices.

validate-crossplay.py enforces all of it — the nine required platforms, the four required domains each with a service owner and offline reconcile, the Sci-Fi opt-out targeting spaceship PvP, the signed-archive requirement, the save scopes, and the QA-scenario coverage set — and test_validate_crossplay.py runs it green against the live repo and asserts it fails when the Mind Palace domain is removed (a negative test that proves the validator has teeth). The honest framing: this is a contract with named service owners (auth, companion-app-bridge, mindpalace-cloud-sync), validated for shape and policy correctness, not an exercised cross-device merge.

flowchart TB subgraph real["Real, tested C++"] STREAM["UV5_Open_StreamingSubsystem<br/>World Partition source provider<br/>256 m cells · prewarm grid · priority"] SAVE["UV5_SaveGameSubsystem<br/>Current → Previous → Fallback<br/>decrypt + JSON validate + recover"] TGT["Build targets<br/>DedicatedServer (−28 plugins)<br/>ArcadeCabinet · ListenServer"] end subgraph gated["Machine-checked policy over JSON"] PERF["performance_platform_profiles.json<br/>11 profiles · 9 groups · 11 suites"] XP["crossplay-progression-policy.json<br/>9 creds · 4 domains · opt-out"] end subgraph declared["Authored intent (no cooked build)"] CERT["cert · store · region pricing"] XR["VR/AR variants · peripherals"] APP["companion app · world economy"] end PERF -->|validate-performance-budgets.py<br/>+ V5.Tests.PerformanceBudgets| GATE["build / launch gate"] XP -->|validate-crossplay.py + pytest| GATE STREAM --> CLIENT["V5 client"] SAVE --> CLIENT TGT --> CLIENT CERT --> GATE

Adaptive difficulty, VR/AR, peripherals & live surfaces (declared intent)#

The remaining technical surfaces are authored design rather than backing C++, and are labeled so. The per-cell AI Director reads a rolling performance signal (deaths, damage taken, objective time, accuracy) to keep each cell inside its difficulty band — disabled in ranked PvP, Trials, and Speedrun so those stay deterministic, and fully player-toggleable. VR/AR is curated to each headset's strength: a seated PSVR2 cockpit for Hard Vacuum, a Quest 3 spectator theater, a Vision Pro volumetric Mind Palace viewer, and a Hunter VR full-cell manifest. Peripherals route through Enhanced Input and are fully remappable — HOTAS, force-feedback wheels, PS5 Access / Xbox Adaptive controllers, and DualSense weapon-specific triggers. The store / region-pricing surface is PPP-adjusted per region with no campaign-gating editions; the companion app is, by the features source's own admission, design-token mockups only (V5/companion/ holds one static .swift and one static .kt file, no buildable project); and the persistent-world economy is deterministic-given-seed save state, simulated coarsely while a cell is inactive. None of these has a cooked build behind it, and the launch-readiness gate keeps the cluster red until one exists.

Where this connects#