Finding peers, selecting transport, admitting a compatible match, validating the result, and advancing a bracket are independently observable steps. A client-reported win never settles a tournament by itself.
A competitive fighting game makes one promise that is really three: that you can find a match, that the match runs on netcode worthy of the inputs you put into it, and that when the bracket starts the result is real. This page is the player-facing tour of the systems that keep all three — V2's online services backbone (the auth, party, matchmaking, replay, and moderation plumbing every menu sits on top of), the network-quality surfaces that decide how a match is transported and where you can play it (rollback selection, the pre-match handshake, LAN mode, the dedicated server browser, and private rooms), and the in-game tournament stack that lets a TO run an entire event — bracket, broadcast, and verified results — from inside the client. It deliberately stops at two seams handled by siblings: the seasonal ranked ladder, the Crown pro circuit, and local/online co-op live in Ranked, the Esports Circuit & Local Co-op, and the store, season pass, and companion app live in Live Service, DLC, Battle Pass & Companion. The deep engine treatment of the backbone and competitive integrity is the architecture companion, ../architecture/online-backbone-and-competitive-integrity.md. For the full feature scope this slots into, start at the hub: ../V2_features.md.
What ships, honestly#
The split here is sharp and worth stating up front. The client-side online
surface is real, shipped Unreal C++, and it is large.
V2/ue/Source/V2OnlineServices is a UGameInstanceSubsystem
(V2OnlineServicesSubsystem.h, ~2,500 lines) over a typed contract
(V2OnlineServicesTypes.h, ~26,700 lines) and a Blueprint library
(V2OnlineServicesBlueprintLibrary.h, ~2,900 lines), with ~25,400 lines of
type implementation in V2OnlineServicesTypes.cpp. Every feature on this page
is a validated USTRUCT with a real IsValid… predicate and, where it does
work, a real algorithm — the server-browser filter, the network-quality grading,
the tournament feature-set completeness gate. The single automation spec
V2Tests/Automation/OnlineServices.Module.spec.cpp is 5,044 lines carrying
737 TestTrue/TestEqual/TestFalse/TestNotNull assertions over that
surface, ~129 of them touching the network-quality, server-browser, LAN, room,
spectator, and tournament types specifically. The service tier is real
TypeScript too: apps/v2/ holds 91 packages, including
nous-anti-cheat-classifiers, whose buildV2NousAntiCheatClassifierSuite
carries the same rollback-safety constant
(V2_NOUS_ANTI_CHEAT_CLASSIFIERS_ROLLBACK_POLICY) the architecture page
describes.
Four honest qualifications. First, the subsystem is a typed client
abstraction with validation and local query logic — it is not a running cloud
fleet. The fleet-management, autoscaling, canary, DDoS, and SLO machinery
(matchmaking p50 ≤ 12 s / p99 ≤ 35 s at 5× launch concurrency, auth p99 ≤ 200
ms, ≥ 99.9% per-region availability) are designed contracts and operational
targets, represented in-engine as validated config/state snapshots, not a
server this header boots. Second, the wire contract to that backend — the
gRPC package the monolith specifies under libs/proto/v2/online/ — does not
exist in the tree (confirmed: no such path), so the proto method signatures
are the designed contract, not generated stubs. Third, the kernel anti-cheat
client specified at V2/ue/Plugins/V2AntiCheat/ is not present (the shipped
plugins are V2AICommentary, V2AdaptiveAI, V2AssetLinter, plus the
Bellona/V2 editor helpers) — so EAC/BattlEye is a plan, while the server-side
integrity check is the part that is architecturally real because it rides the
deterministic sim. Fourth, ranked/matchmaking tuning is baked into the C++
defaults rather than data: V2/balance/online/ currently holds only
world-boss-community-raid.json. Where prose and code disagree, the code is the
authority.
The online backbone, from the player's seat#
Press Online and you are talking to one gateway that fronts auth, friends, presence, parties (≤ 8), matchmaking, lobbies, ranked, the replay cloud, and the store — the engine never branches on platform, because Sony NP, Microsoft Live, and the Switch SDK are reached through shims behind the same subsystem interface over an Epic Online Services baseline. A session is a short-lived JWT (15 min) plus a rotating 30-day refresh token, so a sign-in survives a console sleep without re-prompting. Matchmaking is per-mode — Casual, Ranked, Tournament, Crew, Royal Rumble lobby — and each ticket carries a Glicko-2 / TrueSkill2 skill estimate, region weighting, a ping cap that widens the longer you wait, and role-preference balancing for tag and 4-player. Replays are first-class: every match is stored as re-simulatable inputs you can share by code, pull from a cloud library, or download locally, and the same file doubles as the ghost data the Ghost Battle and master-training modes consume.
The integrity story is where the backbone earns its keep, and the load-bearing
line of defense is the one that is real today. Because a V2 match runs on a
deterministic, integer-frame simulator, the server can do what most fighting
games cannot: re-simulate a match from its inputs and compare the result
hash. That check is a shipped type — FV2ReplayDeterminismGateResult
(V2OnlineServicesTypes.h:12063) carries the InputStreamHash, RngSeed,
ClientOutcomeHash, and ServerOutcomeHash, and its ShouldBlockRankedWrite()
predicate refuses to commit a ranked result when bOutcomeDiverged is set. The
gate result is then embedded directly in the match row: FV2RankedMatchRecord
(:12111) holds both the determinism gate and the network-quality handshake
as required fields, so a ranked match cannot be written without both having been
evaluated. The other anti-cheat layers — kernel client drivers, ML smurf /
win-trading / coordinated-throw / geo-anomaly classifiers — are real-as-designed
but governed by an honest rule: classifier output prioritizes human review and
never issues automatic discipline, and discipline/appeals route out to the
shared Themis/Kuanyin trust-and-safety plane rather than living in V2.
Network quality: how a match picks its netcode#
A 1v1 match does not assume good conditions; it measures them first. The
pre-match handshake samples RTT, jitter, and packet loss on both ends, and
the result is the shipped FV2NetworkQualityHandshakeResult
(V2OnlineServicesTypes.h:12022), built by BuildNetworkQualityHandshake with
bRunsBeforeRankedMatchStart, bMeasuresBothSides, and
bStampedIntoMatchRecord all true. The per-side FV2NetworkQualityMeasurement
(:11993) carries a real threshold, not a vibe: IsPoorQuality()
(V2OnlineServicesTypes.cpp:12532) returns true when
RttMs >= 150 || JitterMs >= 30 || PacketLossPercent >= 3.0. From the two
measurements the handshake resolves a grade — EV2OnlineNetworkQualityGrade is
{ Good, Fair, Poor } (:384) — and the transport mode follows from it
(EV2NetworkQualityTransportMode { Rollback, Delay, Hybrid }, :169): a Good
read runs full rollback at 60 Hz with the engine's ≤ 8-frame budget, a Fair
read runs the hybrid of rollback plus a small input-delay buffer, and RTT > 150
ms or sustained rollback pressure runs delay-based netcode.
The honest part is the out. IsDeclinable()
(V2OnlineServicesTypes.cpp:12581) returns true when the player is allowed to
decline and the grade is Poor or either side reads poor — and per the feature
contract, declining a degraded rollback match in ranked converts it to a
no-contest rather than forcing a bad fight. The handshake also surfaces
connection hygiene the platform exposes: RequiresWirelessWarning() flags Wi-Fi
and RequiresMobileHotspotWarning() flags MobileHotspot / Cellular4G /
Cellular5G off the EV2NetworkConnectionType enum (:373), and those bubble up
to the match record as the bLastRankedNetworkWirelessWarning /
…MobileWarning snapshot fields. A per-account network-reliability score feeds
the ops dashboard from these stamps over time.
LAN tournament mode#
For a venue with no internet to trust, V2 ships a LAN path that stands entirely
on its own. FV2LanTournamentModeConfig (V2OnlineServicesTypes.h:11675) does
UDP-broadcast peer discovery on port 36666 with bNoInternetRequired,
keeps a bLanOnlyRankingLedger strictly separate from the online ladder, still
bCapturesReplays and bPreservesPerMatchRuleSheet, and auto-enables when the
client sees a registered venue SSID — the default catalog
(BuildDefaultNetworkQualityOnlineCatalog,
V2OnlineServicesBlueprintLibrary.cpp:9651) ships three: EVO-Stage-LAN,
CPT-Arena-Admin, Oshun-TO-Offline. IsValidConfig
(V2OnlineServicesTypes.cpp:11731) is a real gate: it fails the config unless
the SSID list is non-empty and every one of those guarantees holds.
The dedicated server browser#
The server browser is primarily a PC surface (and console where TRC permits) and
runs on real query logic, not a mock list. A host's listing is an
FV2ServerBrowserEntry (:24109); a search is an FV2ServerBrowserQuery
(:24071, default MaxPingMs = 120), and the match is decided by
FV2ServerBrowserEntry::MatchesQuery (V2OnlineServicesTypes.cpp:23112) — a
genuine multi-clause filter that rejects a server on visibility, dedicated-only,
healthy-only, join-in-progress, game-mode, region, platform, a
PingMs > MaxPingMs cap, and requires
OpenPlayerSlots >= MinOpenPlayerSlots. The Blueprint library's
QueryServerBrowser runs that filter over the directory and then sorts the
survivors by ascending ping, while the subsystem's
QueryServerBrowserDirectory fails loud — "directory must be refreshed before
query" — rather than return a stale or empty list silently. The host-side config
(FV2DedicatedServerBrowserConfig, :11710) covers what you'd expect a host to
control — ruleset, stipulation, fighter restriction, password, AFK-kick,
rotating maps, kick/ban/mute moderation, chat-log audit, and a server reputation
rating — plus a bring-your-own-dedicated-server path and a MaxBrowserLatencyMs
ceiling of 250. Listings are typed by EV2DedicatedServerListingKind
({ Official, BringYourOwnServer, CommunityLeague }, :177).
Custom rooms & private lobbies#
FV2CustomRoomConfig (:11757) is the private-lobby contract, and its
validators are strict by design. HasRequiredModes()
(V2OnlineServicesTypes.cpp:11781) demands all six EV2CustomRoomMode values —
OneVOne, TwoVTwo, FourCorner, Tournament, BattleRoyal, RoyalRumble
(:185) — and HasRequiredRotationPolicies() demands all three of
EV2RoomQueueRotationPolicy { WinnersStayOn, LosersRotateOut, RandomizedSeating }
(:196). A room seats up to 16 participants and 8 spectators (both
clamp-enforced in the property metadata), gates on an optional password, lets
the host force a specific transport (bHostCanForceRollbackDelayHybrid), runs a
who-plays-next queue, and — the nice touch — enables a bSpectatorMiniLab so a
waiting player drills in a practice space instead of idling. Above the room sits
FV2CrossServerTournamentConfig (:11803) for events that span regional
servers with a unified bracket and an anti-stream-snipe start delay, and a
region pool (FV2RegionMatchmakingPoolConfig) the default catalog seeds with
nine regions: NA, EU, JP, KR, LATAM, SEA, India, MENA, Oceania.
In-game tournaments & broadcast#
V2's tournament stack is a single typed bundle, FV2EsportsTournamentFeatureSet
(V2OnlineServicesTypes.h:7913), and the subsystem's
ConfigureEsportsTournamentFeatures will only accept it if it is complete:
IsCompleteFeatureSet (V2OnlineServicesTypes.cpp) validates all ten
sub-configs — spectator policy, admin event config, broadcast control surface,
the tournament-edition rule snapshot, the Crown ranking config, the
streamer-mode profile, coach/speedrun configs, the caster API contract, and the
pro-ghost catalog — and short-circuits to false with a precise reason on the
first one that fails. There is no half-configured tournament.
A TO with a badge account drives FV2TournamentAdminEventConfig (:7433): it
builds any of the five EV2TournamentBracketFormat values —
SingleElimination, DoubleElimination, RoundRobin, Swiss, Gsl (:1589)
— assigns seeds, schedules matches, drives a broadcast run-of-show, and
auto-reports results, with DQ, a no-show timeout (default 300 s, clamped
30–1800), and round-extension override as TO controls. Tournament Edition is
the lockdown: FV2TournamentEditionRuleSnapshot (:7557) forces classic
controls only, default stages and costumes only, no Mercy/Friendship/Babality, a
forced P1-left/P2-right side, and a locked finisher policy — and critically it
carries a RulesHash and ReplayHeaderId, so the exact conditions a match was
played under are stamped into every replay header and auditable forever.
Spectating and casting are real policy, not a toggle.
FV2EsportsSpectatorPolicy (:7383) is validated by IsValidPolicy
(V2OnlineServicesTypes.cpp) to allow exactly 8 in-match observers with a
chat throttle and a configurable anti-leak delay (default 120 s), and it
requires the overlay, drawing tools, freeze-frame, slow-mo, name plates, score
overlay, director-cam, scriptable cuts, picture-in-picture, and side-by-side
stick cam all be present. The caster-facing FV2BroadcastControlSurface
(:7499) is a manual control surface that toggles HUD elements, supports a
configurable broadcast delay and a stream-lag injector, outputs to OBS / NDI /
Spout / a browser source / a JSON WebSocket (EV2BroadcastOutputIntegration),
and points third-party overlay developers at a documented public SDK schema
(apps/v2/web/dev-portal/caster-api/schema.json).
The two ends — playing and ranking — are joined by result integrity that a
client cannot forge. Results are server-authoritative: the design pulls
results from Start.gg / Challonge / Battlefy / Tournament.app and
cryptographically verifies each against the replay hash before it counts toward
Crown Points, and the FV2CrownProTourRankingConfig (:7628) holds the
approved-tournament and third-party-integration allowlists, a
QualificationCutoff of 32 for the Grand Final, and read-only third-party API
display. The same machinery makes Battle Hub Crown Tournaments possible
inside the client — a public bracket, auto-progression, a per-match side-stream,
and a public leaderboard — so a player enters a real bracket without ever
leaving the game. Streamer Mode (FV2StreamerModePrivacyProfile) rounds it out:
it hides handles and region, renders the opponent as "Opponent," defaults voice
off, auto-enables stream-safe music, and exposes an anti-stream-snipe delay
between 60 and 300 seconds.
How it connects#
The online subsystem is the seam every networked surface in V2 runs through, but it deliberately hands off two large neighbors. The seasonal ranked ladder, the Crown pro circuit, and split-screen / online co-op are the player-facing focus of Ranked, the Esports Circuit & Local Co-op; the store, season pass, player compensation, and companion app that share this same backbone are in Live Service, DLC, Battle Pass & Companion. For the engine-side treatment — the EOS abstraction, the matchmaking SLO contract, the event-bus topics, the replay-hash re-simulation pipeline, and the cross-play / cross-progression policy model — read the architecture companion, ../architecture/online-backbone-and-competitive-integrity.md.
Related#
- The feature hub: ../V2_features.md
- Ranked, the Esports Circuit & Local Co-op — the seasonal ladder, Crown pro tour, and couch/online co-op
- Live Service, DLC, Battle Pass & Companion — the store and live-ops services that share the backbone
- Architecture companion: ../architecture/online-backbone-and-competitive-integrity.md — the backbone, anti-cheat, and cross-play/cross-progression model