Fighting Game · Features

Online Services, Network Quality & Tournaments

A focused page within the Fighting Game Features documentation. The full map and every sibling page live in the Features hub.

6sections11 minread1diagram

On this page
sequenceDiagram actor Player participant Client participant Matchmaking participant Quality as Network quality participant Authority as Match authority participant Tournament Player->>Client: Queue with mode ruleset region and party Client->>Matchmaking: Auth entitlement build and preferences Matchmaking->>Quality: Evaluate peers route latency and integrity Quality-->>Client: Transport authority and compatibility decision Client->>Authority: Join signed match configuration Authority-->>Tournament: Replay hash and result receipt Tournament-->>Player: Bracket advancement broadcast and dispute state

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.