Open-World Narrative · Architecture

Netcode, Authority & Determinism

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

8sections12 minread1diagram1table

On this page

V5 is one UE5 open-world universe split into six ruleset cells — a 1947-noir Urban cell, a Prohibition-era Period cell, an 1899 Frontier, a Witcher-flavoured Hunter cell, a hard-SF Sci-Fi cell, and the cross-cell Mind Palace — and like its V4 sibling it refuses to pick one netcode for all of them. A 30-player Urban free-roam is server-authoritative with lag-compensated hit validation; a Period mission is single-player and never opens a socket; a Sci-Fi capital-ship raid wants a 60 Hz server tick and 12 km of relevancy; a Sci-Fi ship duel or Urban deathmatch wants 8-frame rollback prediction so your own ship answers the stick without waiting a round-trip. The single most consequential networking decision in V5 is therefore the same one V4 made: each cell picks the netcode posture that fits its loop.

All of those postures are expressed in one Unreal C++ module — V5Netcode (V5/ue/Source/V5Netcode/, three .cpp / three .h plus V5Netcode.Build.cs) — but, and this is the load-bearing honesty of the page, they are expressed as deterministic library functions, not a running net stack. The module compiles on the on-box engine: the build tree carries seven V5Netcode/*.o objects under V5/ue/Intermediate/Build/Linux/x64/UnrealEditor/Development/V5Netcode/, and the dedicated-server and arcade-cabinet targets carry their own copies. The one place V5 genuinely touches Unreal's net path is elsewhere — the replicated Gameplay-Ability-System attribute sets in V5Gameplay, covered below. This page is the architecture-side companion for V5's per-cell netcode, server authority, lag compensation, rollback prediction and determinism, part of the Multiplayer, Modes & World Simulation group; the orientation hub is ../V5_ARCHITECTURE.md.

What ships, honestly#

Five plain claims, so the rest of the page reads at face value.

  • The netcode logic is real, deterministic-by-construction, and tested. V5Netcode is a set of thirteen UBlueprintFunctionLibrary classes (config builders, an actor-priority classifier, a lag-comp rewind selector, a host-election scorer, a rollback-span evaluator, a seeded PRNG, a bandwidth grader, a soak grader). Two automation specs — V5.Netcode.SystemsAndTargets and V5.Netcode.SoakSimulation (V5NetcodeTests.cpp) — drive these statics and assert computed values, and both reported Result={Success} in the on-box run logged at Saved/Logs/AutomationFull.log (2026-06-13), inside a 304-test V5 suite.
  • This is a deterministic library, not a wired net driver. There is no FSocket, ISocketSubsystem, no UReplicationGraph, no UFUNCTION(Server/ Client/NetMulticast) RPC, and no Iris API symbols anywhere in the module. V5Netcode.Build.cs declares only Core, CoreUObject, Engine and V5Core (:9–17) — it does not even depend on Iris, OnlineSubsystem, ReplicationGraph or NetworkPrediction. When BuildIrisConfig sets NetDriverName = FName("IrisNetDriverV2") (V5NetcodeSystems.cpp:42), that is the name of the driver V5 intends to bind, carried in a plain config struct — not a call into a live Iris runtime.
  • The real engine-networking integration is the replicated GAS attribute sets. V5Gameplay declares 44 server-authoritative FGameplayAttributeData fields across four UAttributeSet subclasses, each ReplicatedUsing = OnRep_* with REPNOTIFY_Always and server-side clamping in PostGameplayEffectExecute (V5AttributeSets.cpp). That is genuine replication metadata — but no actor, pawn or PlayerState in the tree mounts a replicated AbilitySystemComponent that owns these sets, and nothing sets bReplicates (outside the gameplay-effect tests, the only AbilitySystemComponent reference in V5/ue/Source is the #include in V5AttributeSets.h:3; V5GameplayEffectTests.cpp is the other). The attributes are replication-ready, not replicating.
  • No build target enforces strict floating-point or a determinism flag. V5.Target.cs, V5DedicatedServer.Target.cs and V5ListenServer.Target.cs set none of /fp:strict, DETERMINISM, or a V5_STRICT_FP define — unlike V2 (V2_STRICT_FP=1). The monolith's "fp-strict in deterministic paths" is not realized in build config. V5's determinism instead rests on a seeded integer PRNG and integer frame arithmetic, described honestly below.
  • RunSoakSimulation is a closed-form grader, not a packet simulation. It maps a (packet-loss, RTT, duration) tuple to a quality grade and recovery/validation counts by deterministic arithmetic (V5NetcodeSystems.cpp:287) — there is no datagram-level loss model behind the name. It is honest about its own arithmetic and tested as such.

These are honest altitude statements, not disparagement: every line cited compiles, is UHT-processed, and is exercised by a passing spec. V5's netcode simply sits one rung lower than V2's full rollback engine or V4's lockstep subsystem — it is the policy and math layer, with the wire binding deferred.

The per-cell netcode model#

The architecture monolith's promise — "combat authority is per-cell" — resolves to four concrete postures, selected by cell and mode:

Cell / mode Strategy Authority Determinism posture
Urban / Frontier / Hunter (open) Iris client-server + AOI Server (lag-comp hit-reg) Server-authoritative, float OK
Sci-Fi capital raid Iris client-server, 60 Hz tick Server Server-authoritative, float OK
Sci-Fi ship duel / Urban deathmatch 8-frame rollback prediction Predict-and-confirm Seeded xoshiro256+, integer frames
Period (single-player) Local, no session Client-local Seeded, opt-in replay
Mind Palace Client-authoritative + sync Client-local, cloud-merged n/a (deduction graph)

The selector is BuildIrisConfig(Cell, bCapitalRaid) (V5NetcodeSystems.cpp:39): Iris is enabled for every cell except Period and Mind Palace (bUseIris = Cell != Period && Cell != MindPalace, :43), the client input rate is pinned at 60 Hz, and the server tick is 60 Hz for a capital raid or any Sci-Fi session, else 30 Hz (:45). Server-authoritative damage rides on the same flag (bServerAuthoritativeDamage = bUseIris, :46), so a single-player Period mission is bUseIris=false and never claims server authority it has no server to enforce.

flowchart TD M[Session opens: which cell + mode?] --> Q{BuildIrisConfig} Q -->|Period / Mind Palace| LO[bUseIris=false · local, no socket] Q -->|Urban / Frontier / Hunter| CS[Iris client-server · 30 Hz tick] Q -->|Sci-Fi capital raid| HF[Iris client-server · 60 Hz tick] Q -->|Sci-Fi duel / Urban deathmatch| RB[8-frame rollback prediction] CS --> AOI[AOI relevancy + priority tiers] HF --> AOI AOI --> AUTH[Server authority: replicated GAS attrs + PostGE clamp] AUTH --> LC[Lag-comp rewind: half-RTT, 200 ms window] RB --> EV[EvaluateRollback: span = current - max(confirmed, mismatch)] EV --> W{span within 8 frames?} W -->|yes| OK[resimulate predicted frames] W -->|no| DROP[flagged out-of-window] LO --> PR[seeded xoshiro256+ drives all gameplay RNG] OK --> PR

Iris replication, AOI streaming and priority tiers#

For the open-world cells V5 partitions relevancy by an area-of-interest profile and a three-tier priority scheme — both pure functions over plain data.

BuildAOIProfile(Cell) (V5NetcodeSystems.cpp:50) returns the per-cell radius, player cap and tick: Urban 300 m / 30 players / 30 Hz (the default arm, :77), Frontier 500 m / 7 / 30 Hz (:56), Sci-Fi 12 000 m / 10 / 60 Hz (:61 — the 12 km the monolith promises for void combat), Hunter 400 m / 4 / 30 Hz (:66), and Period / Mind Palace 0 m / 1 player / 0 Hz (:71, i.e. offline). The V5.Netcode.SystemsAndTargets spec pins three of these exactly (Urban 300, Frontier 500, Sci-Fi 12 000).

ClassifyActor(Input) (:86) is the relevancy band budgeter. A player-or-owned pawn, a mission-critical actor, or anything within 40 m is Critical at 30 Hz; a vehicle-in-encounter or anything within 180 m is Important at 12 Hz; everything else is Background, at 2 Hz or 0.5 Hz for a schedule-only NPC (:99–103). A schedule-only NPC beyond 600 m stops replicating entirely (bReplicate, :104) — the monolith's "distant schedule-only NPC" tier made concrete. The bandwidth side is EvaluateBudget(Input) (:212), which sums the three tiers, checks them against the 64 kbps average / 256 kbps burst budget (constants :7–8) the monolith states, and on overflow throttles Background first, then Important (:218– 228) — never Critical. The spec drives a 70 kbps over-budget input and asserts Background lands in ThrottledTiers first.

Server authority: the replicated GAS attribute sets#

This is where V5 actually meets Unreal's replication system, and it lives in V5Gameplay, not V5Netcode. Four UAttributeSet subclasses — UV5_AttributeSet_Combat (14 attrs), _Honor (9), _Ship (11) and _Vehicle (10) — declare every replicated stat via the V5_REPLICATE_ATTRIBUTE macro, which expands to DOREPLIFETIME_CONDITION_NOTIFY(..., COND_None, REPNOTIFY_Always) (V5AttributeSets.cpp:12), and register them in GetLifetimeReplicatedProps (Combat at :57). Authority is enforced server-side after every gameplay effect: PostGameplayEffectExecute clamps Health to MaxHealth, Stamina to MaxStamina, Toxicity, Mana, ship Hull/Reactor and vehicle Fuel into range (:94–103, :229–234, :287–290), so a client cannot drive an attribute out of bounds — the server re-clamps on its own copy before the OnRep_* notify fans the value back out. V5Gameplay.Build.cs declares the real GameplayAbilities and GameplayTags modules, and these attribute sets and their V5.Gameplay.GE.ReplicationMetadata spec are documented in detail in ./gas-animation-input.md. The honest caveat from the top still holds: the metadata is correct and compiled, but no replicated ASC mounts it in-tree, so nothing pushes these bytes at runtime yet — the binding sits behind the same boundary as the V5Netcode library.

Lag-compensated hit validation#

RewindForHitValidation(History, CurrentServerTime, RoundTripMs) (V5NetcodeSystems.cpp:108) is the server's "rewind the target to where the shooter saw it" guard. It clamps the RTT into the 200 ms history window (constant V5LagCompWindowMs, :5; exposed via GetHistoryWindowMs, :133), rewinds to CurrentServerTime − RTT × 0.0005 — i.e. half the round-trip, the one-way latency, in seconds (:112) — and floors that at the oldest retained sample (:113–117). It then scans the sample ring for the entry nearest the rewind time by absolute delta and reports bCanRewind only when history is non-empty and the best match is inside the 200 ms window (:119–129). Worth labeling precisely: this is nearest-sample selection, not interpolation between two bracketing samples (V4's lag-comp interpolates; V5's snaps to the closest recorded pose). The spec builds a ten-sample 33 ms history and confirms a 200 ms RTT shot rewinds inside the window.

Rollback-emulated prediction (the Sci-Fi duel cell)#

For tight twitch PvP — the Sci-Fi ship duel and Urban deathmatch — V5 predicts forward and rolls back on a remote-input mismatch. The decision logic is EvaluateRollback(CurrentFrame, LastConfirmedFrame, MismatchFrame, bRemoteInputMismatch) (V5NetcodeSystems.cpp:160). When the prediction held (!bRemoteInputMismatch), it early-outs with bWithinEightFrameWindow=true and zero rollback (:163–167) — a correctly predicted frame costs nothing, exactly the property that keeps a clean connection at zero rewinds. On a mismatch it computes RollbackStart = max(LastConfirmedFrame, MismatchFrame), sets RollbackFrames = max(0, CurrentFrame − RollbackStart), mirrors that into ResimulatedFrames, and grades it against the 8-frame window (constant V5RollbackWindowFrames, :6; check at :172). The spec proves the arithmetic: EvaluateRollback(120, 113, 114, true) rolls back to frame 114 and reports 6 resimulated frames, within window.

The honest distinction from V2 matters here. V2 ships a full rollback engineFV2SimWorld with CaptureSnapshot/RestoreSnapshot/StepFrame, an 8 KB snapshot budget, a chained state hash and a golden-replay corpus. V5's EvaluateRollback is a span-and-window evaluator: it decides how many frames a rollback would cover and whether that fits the budget, but the snapshot/restore/replay machinery it would gate is not in this module. The monolith's behavioural rules — visuals snap for one frame, physics-particles and audio do not replay, torpedo trajectories are deterministic and need no rollback — describe the intended cosmetics layer that consumes this decision; the decision itself is what V5Netcode provides and tests.

Determinism: the seeded PRNG and what it guarantees#

V5's determinism backbone is a single, real, named algorithm. UV5_Net_PRNG implements xoshiro256+: Seed(MatchSeed) expands a 64-bit match seed into the 256-bit state with four SplitMix64 draws (:176–185, the standard 0x9E3779B97F4A7C15 increment and the two mix constants, :25–31) — the seeding procedure the xoshiro authors prescribe — and Next(State) returns s0 + s3 as the output, then advances the state with the canonical xor/shift/rotl-45 transition (:187–209). The unit float is taken from the top 24 bits of the output ((Value >> 40) & 0xFFFFFF, :204), which is correct practice for the + scrambler whose low bits have weak linear complexity. Because the state is integer and the transition is fixed, the stream is bit-identical across machines from the same seed — the spec asserts both Seed(12345) states and their first Next values are equal.

Two honest qualifications keep this from over-claiming. First, this is the whole determinism story in-code. There is no chained state-hash desync detector (V4's ComputeDeterministicHash), no RNG-consumption-order audit (V4's ValidateRngConsumptionOrder), no StableNameHash, and no replay serializer or golden corpus (V2's GoldenReplayCorpus). Cross-machine determinism is asserted for the PRNG and the integer frame arithmetic, not for a full gameplay sim. Second, the monolith's two stronger claims are unbacked by this tree: "fp-strict in deterministic paths" sets no compiler flag in any target, and the "opt-in save-replay with full input stream + initial seed" has no serializer here. The float-math open-world paths are safe precisely because they are server-reconciled, never cross-machine lockstep — V5, like V4, deliberately abandoned deterministic lockstep for the Urban heist in favour of client-server + lag-comp (per the monolith), so it never depends on bit-identical float replay across peers.

Sessions, host migration, dedicated servers and LAN#

V5Netcode also carries the session-shape layer. UV5_Net_DedicatedServer and UV5_Net_ListenServer build target profiles — dedicated on port 7777, 30 players (:232), listen on 7778, 6 players (:243), both bServerAuthoritative=true — matching the V5DedicatedServer/V5ListenServer build targets, which both compile (their intermediate trees exist alongside the editor's). ElectNewHost(Candidates, PreviousHost) (:138) is the 2-second host-migration rule: it scores each connected, non-previous-host peer by UploadKbps × 0.7 − PingMs × 2.0 (HostScore, :33–36), picks the highest, estimates a completion time clamped to [0.6 s, 2.0 s] from ping and upload headroom (:153), and reports bWithinTwoSecondCap (:156). The spec elects a 5 Mbps/38 ms peer over a disconnected old host and confirms the sub-two-second swap. UV5_Net_LAN::BuildLANAdvertisement (:254) mints an offline-capable LAN session (bRequiresOnlineServices=false), and UV5_Net_ServerBrowser::FilterRooms (:266) filters private rooms by cell/mode/region/password/ping and sorts the survivors by ascending ping (:280–283).

The choice of which cells may even cross platforms is policy data in V5/crossplay/crossplay-progression-policy.json: crossplay is on by default across 9 platforms, but the Sci-Fi mode.scifi.spaceship-pvp carries a documented opt-out with consoleInputParityReason: "spaceship_pvp_high_precision_input" — the one cell on the rollback path is also the one allowed to fence console players off for input-parity fairness. That file, the canonical-account ledger and the progression merge policies belong to the online/persistence layer and are detailed in ./persistence-online-and-crossplay.md.

How it connects#

The netcode module is consumed, not standalone. The GameFeatures mode plugins that select an Iris profile and an AOI band per session — and the World-Partition grid those relevancy radii stream against — are detailed in ./modes-streaming-procgen.md; the per-cell server ticks here are the same ticks the streaming budget plans around. The server-authoritative replication of non-combat state — guard suspicion, honor, bounty and wanted level, distinct from the rollback path — is the AI side of the same client-server backbone and lives in ./perception-crowd-and-morality.md, whose morality attributes mount on the very UV5_AttributeSet_Honor set this page shows replicating. The dedicated-server backend, matchmaking, anti-cheat, canonical-account crossplay and save-sync that the target profiles and session shapes feed into are covered in ./persistence-online-and-crossplay.md. The attribute-set field definitions, clamps and GAS replication metadata are in ./gas-animation-input.md. The orientation hub is ../V5_ARCHITECTURE.md.