A competitive fighting-and-racing game lives or dies on two promises that are
really one: that the netcode is fair, and that the ladder is honest. V2's online
architecture exists to keep both — to get players into a low-latency,
rollback-clean match across PC, PlayStation, Xbox, and Switch, and to make sure
the result of that match means something on a ranked ladder that cheaters,
smurfs, and throwers cannot quietly poison. This page covers the online
backbone — the in-engine V2OnlineServices subsystem and the session surfaces
it fronts (auth, friends, parties, matchmaking, ranked, replay, ghost, store) —
and competitive integrity: anti-cheat, the replay-hash validation that rides
V2's deterministic simulation, and the cross-play / cross-progression model that
decides who may be matched with whom and what travels with an account. The
deterministic match runtime those services wrap lives one layer down in
Rollback Netcode & Tag-Team and
Combat: GAS, Frame Data & Determinism;
this page is about everything that happens around the match. The honesty bar
is the project's own: where the code is a deterministic in-engine model rather
than a wired backend, the page says so plainly, because "designed, not yet
built" beats implying a shipped service. The section hub is
../V2_ARCHITECTURE.md.
What ships, honestly#
The split here is sharp, and stating it up front keeps the rest of the page honest — sharper, in fact, than the prose around this module usually admits.
The client-side online surface is real Unreal C++, but it is a deterministic
model, not a wired backend. V2/ue/Source/V2OnlineServices ships a
UV2OnlineServicesSubsystem (a UGameInstanceSubsystem,
V2OnlineServicesSubsystem.h) over a ~25k-line type library
(V2OnlineServicesTypes.cpp) and a ~20k-line Blueprint library
(V2OnlineServicesBlueprintLibrary.cpp). It is the in-engine seam every menu,
lobby, and matchmaking screen calls, and it is substantial. But its Build.cs
declares exactly three dependencies — Core, CoreUObject, Engine. There is
no OnlineSubsystem, no EOS SDK, no HTTP/Json, no FSocket anywhere in
the module. What the C++ actually does is build configuration structs
(BuildDefault…Config), validate them (Validate…), plan operations
(Plan…Operation, Resolve…Request), and fold the results into a large
FV2OnlineServicesRuntimeSnapshot of counters and readiness flags. The "EOS /
Steamworks / GOG Galaxy / PlayStation / Xbox" surfaces are config-and-validator
pairs with operation planners — and the console ones are even named honestly:
FV2PlayStationSdkStubConfig, FV2XboxGdkSdkStub…. This is precisely the
"build a POD struct, never transmit" shape the sister
V5 backbone
flagged before V5 replaced it with a real FHttpModule transport; V2 has not
yet replaced it. The model is real, deterministic, and heavily tested; the
wire is not in this module.
The real TypeScript in apps/v2 is the spine around the backbone, not the
backbone itself. There are 91 service packages — but they are the live-ops,
telemetry, trust-and-safety, AI, and identity tiers (season-pass-service, the
telemetry-* family, kuanyin-* / themis-* moderation, iris-* / isis-* /
psyche-* AI, nous-anti-cheat-classifiers, oshun-identity-binding,
cross-product-entitlement). None of them is a session-backbone service:
there is no auth, matchmaking, ranked, replay, friends, party,
lobby, or store package. That backbone is specified as a gRPC surface under
libs/proto/v2/online/ — which does not exist in the tree — so the method
signatures below are the designed contract, not a generated stub. The kernel
anti-cheat client at V2/ue/Plugins/V2AntiCheat/ is likewise absent (the
present plugins are V2AICommentary, V2AdaptiveAI, V2AssetLinter,
V2Editor, BellonaUnrealEditor).
The one integrity claim that is architecturally real today is the one that needs no backend at all: because the match runs on a deterministic, integer-frame simulator, the server can re-simulate from inputs and compare a hash. That check rides the determinism the engine already guarantees — and it is where this page's honesty pays off.
The online backbone#
A deterministic in-engine service model#
V2OnlineServices is best understood as the shape of the online backbone
expressed in validated, deterministic C++. Each session surface is a triple: a
config builder, a validator, and — where an operation is involved — a planner
that turns a typed request into a typed result without touching a socket. The
platform-abstraction layer is the clearest example:
BuildDefaultPlatformSdkAbstractionSpec → ValidatePlatformSdkAbstractionSpec
→ ResolvePlatformSdkRequest, with provider-specific siblings
PlanEosSdkOperation, PlanSteamworksSdkOperation,
PlanGogGalaxySdkOperation, and the explicitly-named
PlanPlayStationSdkStubOperation / PlanXboxGdkSdkStubOperation. The EOS
"baseline" is enforced as a validation rule, not a link dependency:
EV2OnlineBackendProvider::EOS must bind the PC OnlineServicesEOS subsystem,
and a valid backend requires EOS-on-PC plus Sony, Xbox, and Switch shims
(V2OnlineServicesTypes.cpp:1108–1155) — so the topology the monolith promises
is checked, even though nothing dials out. The whole runtime is observable
through UV2OnlineServicesSubsystem::CaptureRuntimeSnapshot()
(V2OnlineServicesSubsystem.cpp:3729), which renders the entire backbone —
friends, parties, matchmaking, ranked seasons, replay theater, moderation,
fleet, server health — into one inspectable FV2OnlineServicesRuntimeSnapshot.
That snapshot is what the automation suite asserts against, and it is why the
model is testable without a server.
Enums anchor the surface: EV2OnlineAuthState (V2OnlineServicesTypes.h:7),
EV2MatchmakingTeamRole (:159), EV2PlatformFamily (:392),
EV2OnlineBackendProvider (:421), and EV2OnlineInputMethod for input-class
pairing. Gameplay code never branches on platform — it asks the subsystem and
reads the snapshot.
The session surfaces and the event-bus contract#
The subsystem fronts the full session set: auth (platform-token sign-in
exchanged for a V2 session, with refresh), friends & presence (including a
cross-platform unified friends list that resolves identities and de-duplicates
aliases), parties (≤ 8, the unit matchmaking submits on a player's behalf),
matchmaking (per-mode queues, below), lobby (custom rooms and the Battle
Hub), ranked / leaderboards (seasonal, per mode), replay cloud & ghost
store (UploadReplayFileToCloud, V2OnlineServicesSubsystem.cpp:926, plus
share-by-code and Tekken-ghost export), and store (the cosmetic catalogue,
detailed in the live-ops sibling).
The backbone's integration contract is event-bus-native by design. The
monolith specifies the lifecycle topics it publishes —
v2.player.session.started/ended, v2.match.ended, v2.match.replay.hash,
v2.player.reported, v2.cosmetic.purchased, v2.matchmaking.ticket.completed
— and the cross-domain signals it consumes — themis.appeal.resolved,
maat.balance.recommendation, iris.commentary.generated,
kuanyin.action.taken. The honest seam: the C++ model does not itself publish
to a bus (it has no transport); the live publication rides the platform
@oshun/event-bus, and the consumers are the real TS services in apps/v2
(themis, kuanyin, maat, iris). This is what lets moderation, balance, and AI
commentary act on match outcomes without V2 reaching into their databases.
Matchmaking and the ranked ladder#
Matchmaking is the backbone's most fairness-sensitive job, and the model carries
it as data plus deterministic policy. A ticket is an FV2MatchmakingTicket
submitted through SubmitMatchmakingTicket(…)
(V2OnlineServicesSubsystem.cpp:342); each queue is per-mode (ranked 1v1,
2v2 tag, FFA, the racing modes) and each player carries an
FV2MatchmakingSkillProfile. That profile is a genuine dual-model record with
the canonical default constants: TrueSkill μ = 1000, σ = 83.333 and
Glicko-2 rating = 1500, RD = 350, volatility = 0.06 — the same constants
Glickman's reference uses and the same family the platform's @oshun rating
services use elsewhere. HasExplicitSkillProfile
(V2OnlineServicesTypes.cpp:774) treats any deviation from those defaults (or a
non-zero placement-match count) as "this player has played," which is how
placement-vs-established is told apart. Role balancing is real logic, not a
flag: ContainsPointAndPartnerRole requires a Point plus an Assist /
Anchor / Support for tag and FFA team formation, and the snapshot exposes
bHasRoleBalancedFourPlayerQueue. Region weighting, a ping cap, and
search-radius expansion over wait time are modeled as
bRegionAwareMatchmakingReady, LastRegionAwareMatchmakingPingMs,
bLastRegionAwareMatchmakingWithinPing, and bLastMatchmakingUsedExpansion.
The honest qualification: this is a skill-and-policy data model with
validators, not a live rating solver. Unlike the V5 backend — which runs an
actual Glicko-2 update with an Illinois root-find on the volatility step — V2's
module stores the profile and its defaults and records results.
RecordRankedMatchResult (:681) delegates to ApplyRankedMatchResult and
copies the resulting skill into the ladder entry rather than re-deriving a
rating from a worked formula. The seasonal ladder on top is modeled in depth:
ApplyRankedSeasonReset (:747), a hidden-MMR policy
(bRankedSeasonHiddenMMRReady, asserted to keep hidden MMR never-shown and to
split the primary and secondary skill models), a unified cross-platform MMR pool
with cross-platform leaderboards, placement, promotion/demotion thresholds, and
a per-season reset. The designed SLOs are concrete enough to test against
once the backend exists: ticket p50 ≤ 12 s, p99 ≤ 35 s under 5× expected
launch concurrency, auth p99 ≤ 200 ms, replay upload p99 ≤ 8 s for a
10-MB replay, and ≥ 99.9% per-region availability. One correction to earlier
drafts of this page: the ranked/matchmaking tuning does not live in
V2/balance/online — that directory holds only
world-boss-community-raid.json. The matchmaking defaults are the C++ constants
above, and the tag-pairing curves live in V2/balance/tag/.
Competitive integrity#
Integrity is defended in depth, and — critically — the load-bearing line of
defense is the one that is architecturally real. Because the match runs on a
deterministic, integer-frame simulator (see
Rollback Netcode & Tag-Team), the server
can do what most fighting games cannot: re-simulate a match from its inputs
and compare the result hash. Every match emits a golden-replay hash on
v2.match.replay.hash; the design re-runs ~1% of matches end-to-end on a Linux
validator pool, and any non-zero frame drift flags manual review. The runtime
snapshot already carries the gate result
(bLastRankedReplayDeterminismGatePassed). That check needs no kernel driver —
only the determinism the engine guarantees — which is why it is the integrity
claim this architecture can stand behind today.
The other tiers are real as validated contracts and modeled state, and the
test surface here is genuinely large:
V2/ue/Source/V2Tests/Automation/OnlineServices.Module.spec.cpp carries 736
assertions, and V2Tests/Private/Online/ holds 53 dedicated contract specs.
- Server-side input/state validation. Input-rate sanity (≤ 180 inputs/s,
bursts > 240 flag) and per-ability gameplay-effect whitelisting, exercised by
the
ServerMovementValidation,ServerHitValidation,ServerDamageValidation,ServerEconomyValidation,SpeedHackDetection,AimbotDetection,MovementHackDetection,WallhackMitigation, andStatisticalAnomalyDetectionspecs. These ride the same authoritative path the netcode owns, and a fabricated effect application invalidates the match. Modeled and tested; the live server that would run them is the absent backend. - Kernel client anti-cheat. EAC primary / BattlEye fallback on PC,
platform-native anti-tamper on console (PSN ban-list, Xbox TruePlay, Switch
NEX). This is the
V2/ue/Plugins/V2AntiCheat/surface that is not present — but the client-signal contracts are modeled and contract-tested (DriverIntegrity,ProcessScanner,MemoryIntegrityScanner,OverlayHookDetection,HardwareFingerprint,ThirdPartyAntiCheatIntegration, andAntiCheatModeOptIn/MinimalFootprint/ModuleObfuscation/SelfUpdate/ReportSystem), backed byClientHeartbeatand theFairPlay*snapshot counters (FairPlayDetectionSignalCount,HwidBanCount,FairPlayForensicLogCount). Treat the kernel driver as the planned client tier, not a shipped one. - ML cheat classifiers.
nous-anti-cheat-classifiers(real TS) over@nous/training+@nous/safety— smurf, win-trading, coordinated-throw, geographic-anomaly. Its governing rule is the honest one: classifier output can prioritise human review but cannot issue automatic discipline and cannot touch rollback frames (bLastSmurfBlockedRankProgression,bLastTournamentVpnBlockedare queue/priority signals, not bans). Model-driven moderation never silently bans, matching the platform's review-only, appealable posture and the@oshun/audit-platformforensic-retention contract.
Discipline, shadow-bans, and appeals are modeled (FairPlayBanSystem,
FairPlayShadowBan, FairPlayBanAppealWorkflow, ReplayCheatReview,
TrustedPlayerProgram) and route out to the shared trust-and-safety plane —
Themis (themis-dispute-resolution, DSA Statement-of-Reasons) and Kuanyin —
over the event bus, so a ban is auditable and reversible by the same machinery
that governs every Oshun product. Rage-quit escalation (5-minute → 30-minute +
50 points → 24-hour ranked ban + 150 points) is carried as
bLastRageQuitPenaltyEscalated.
Edge cases and failure modes
- Unconfigured or malformed backend. Every operation returns through an
OutFailureReasonseam; an invalid ticket or backend config fails the validator loudly rather than silently "succeeding" — a fail-loud surface, not a fabricated ack. - Replay determinism drift. A re-sim mismatch surfaces as
bLastRankedReplayDeterminismGatePassed = falseand routes toReplayCheatReview, never an automatic ban. - Console with no kernel driver. The SdkStub path validates platform-native
anti-tamper bindings (
PlayStationSdkStub,XboxGdkSdkStubspecs) instead of asserting an EAC driver that cannot exist on console. - Classifier false positive. Output prioritises a review queue; the appeal
workflow (
FairPlayBanAppealWorkflow) is the only path to discipline, with a ≤ 0.5%-overturn threshold as the model-retrain trigger. - Cross-process hash drift. Mitigated upstream by the netcode's stable, content-based state hash, so a regression surfaces as a golden-replay mismatch in CI rather than a desync — or a false cheat flag — in the wild.
Cross-play & cross-progression#
Cross-play decides who can match whom; cross-progression decides what travels
with the account. Both are policy-rich, and both are modeled as validated state
in the subsystem (bCrossPlayPolicyValid, bCrossProgressionSnapshotValid)
with the implementations specified as the backend services above.
Cross-play is on by default for ranked 1v1, 2v2 tag, custom lobbies, the
Battle Hub, and World Tour across PC, PS5/PS5 Pro, XSX, and Switch 2, with
per-platform system opt-out honoured at session start (toggle changes
mid-session never affect the current match —
bLastCrossPlatformMatchmakingOptOutRespected). The subtle part is
input-method pairing: a ticket carries an EV2OnlineInputMethod, and
matchmaking compares TicketInputMethod against CandidateInputMethod
(V2OnlineServicesTypes.h:7353), so KBM, gamepad, fight-stick, fight-pad,
arcade-stick, and adaptive-controller classes can be paired or segregated per
mode. Cross-class is opt-in in ranked and default-on in unranked, and adaptive
controllers are always opt-in for both sides, so accessibility hardware is never
forced into a competitive mismatch. The iOS/Android companion is explicitly
read-only and not a play surface. The CrossPlatformSocial spec covers the
unified friends list, cross-platform party/lobby, and the central-server-routed
voice (native voice disabled, moderation enabled) the platform TRCs require.
Cross-progression roots every player in one identity. @oshun/identity is
the single account root; per-platform shadow accounts (PSN, Xbox Live, Nintendo
Account, Steam) bind to it. The real TS composition is oshun-identity-binding
over the shared @oshun/identity contract, mirrored in-engine as
FV2OshunIdentityAccountBinding, with re-binding gated behind a 30-day cool-off
and a TOTP step. The subsystem models the unified identity service
(bUnifiedPlayerIdentityServiceValid, internal-id-keyed so display names stay
distinct from platform usernames), cross-platform progression sync
(CrossPlatformProgressionLinkedPlatformCount), cross-platform ban
synchronisation (bCrossPlatformBanSynchronizationSystemValid — an Oshun-side
ban applies everywhere, a platform-side ban stays on that platform), and the
account-data privacy plane (bAccountDataPrivacyComplianceSystemValid, with
DSAR export and deletion propagated to every linked platform). Shared state
spans profile, the Crowns currency ledger (with per-platform IAP credit kept
separate for store-compliance reasons), cosmetic inventory, fighter unlocks,
ranked rank, Battle Pass progress, and the single-player career saves; conflict
resolution is last-write-wins for non-cosmetic state and union-of-unlocks for
cosmetic and fighter unlocks. Platform-only entitlements — a disc-bundle
cosmetic that cert forbids transferring — are verified through
PlatformEntitlementVerification and the real cross-product-entitlement
service, and region-locked cosmetics are region-stamped so a cross-region
account sees them locked rather than seeing the wrong variant. The identity
root is the platform's, not V2's — which is exactly why a ban or a deletion
request resolves consistently across every surface a player touches.
Where this connects#
- Down to the match: Rollback Netcode & Tag-Team and Combat: GAS, Frame Data & Determinism — the deterministic sim and stable state hash the replay-hash integrity check depends on.
- Sideways to live-ops: Live-Ops, Store, Progression & Community — the store, season-pass, and player-compensation services that share the backbone and the event bus.
- Sideways to esports:
Esports, Companion & AI Services —
tournaments, the spectator/companion surfaces, and the
@nousAI services. - Operability & assurance: Telemetry, Performance, Testing & Release Gates — reliability scores, network-diagnostics stamps, and the CI determinism gate behind the replay-hash check; and Security, Compliance & Sister-Monorepo Integration — the cross-play / cross-progression and anti-cheat cert constraints.
- Platform foundations: Contracts, Auth & Identity, and the BFF & gateway tier the V2 services compose.