Hidden rating, visible rank, promotion/demotion hysteresis, inactivity decay, tournament freezes, disputes, and season closure are separate. Broadcast and spectator views project this ledger without owning it.
A fighting game's competitive surface is judged by two things players can feel
but rarely see: whether the ladder they climb is honest, and whether the
broadcast they watch is produced. V2 treats both as first-class engine data,
not marketing copy. This page covers the three clusters that turn a
deterministic 1v1 into a season-long sport — the ranked season architecture
(90-day seasons, eight visible rank families over a hidden TrueSkill2/Glicko-2
pool, hysteresis, decay, and anti-throw integrity), the esports circuit (the
TO admin console, the Tournament-Edition rule freeze, the Crown Pro Tour points
overlay, and the public result archive), and the streamer / speedrun / coach /
spectator modes that wrap a match for an audience. The unusual thing about
V2's implementation is how much of this is real, validated Unreal C++ in the
V2OnlineServices module rather than a backend stub: the season catalogue, the
ten-part esports feature set, and their cross-checking validators all ship and
are pinned by contract automation specs. Where a piece is a designed contract or
a provider-gated capability, this page says so in code. The section hub is
../V2_features.md.
What ships, honestly#
The line between "shipped" and "designed" runs cleanly through this cluster, and it is worth stating up front.
- The ranked season is a validated C++ catalogue.
FV2RankedSeasonArchitectureCatalog(V2OnlineServicesTypes.h:12494) is a realUSTRUCTcarrying every season number — length, placements, tiers, regions, rewards, and four sub-policies (MMR, decay, Crown overlay, anti-throw). It is built byBuildDefaultRankedSeasonArchitectureCatalog()(V2OnlineServicesBlueprintLibrary.cpp:10419), gated by a cross-checking validator (IsValidCatalog,HasAllVisibleRankTiers), wired intoUV2OnlineServicesSubsystem::ConfigureRankedSeasonArchitecture()(V2OnlineServicesSubsystem.cpp:622), and exercised end-to-end by the specV2.Online.RankedSeasonArchitecture.AssetContract(V2/ue/Source/V2Tests/Private/Online/RankedSeasonArchitecture.spec.cpp). - The esports/streamer/coach/speedrun surface is one validated feature set.
FV2EsportsTournamentFeatureSet(V2OnlineServicesTypes.h:7913) bundles ten sub-configs — spectator policy, TO admin, broadcast control, Tournament-Edition snapshot, Crown ranking, streamer privacy, coach session, speedrun support, caster API, and pro-ghost tutoring — each with its ownIsValid…method, and anIsCompleteFeatureSet()that requires all ten. The module spec (V2Tests/Automation/OnlineServices.Module.spec.cpp:2267) builds it, validates every part, and configures it through the subsystem. - The ranked *tuning numbers live in C++, not in
V2/balance/online. That directory currently holds onlyworld-boss-community-raid.json; the ranked season's curves are the build-default catalogue above. The honest read is that ranked tuning is a code-default today, not yet a hot-editable JSON. - The broadcast/result operations are real TypeScript surfaces.
apps/v2/web/esports/resultsis a static result archive andapps/v2/esports-tools(@v2/esports-tools) is the operator broadcast pipeline — both shipped, both explicitly off the deterministic path. - What is designed, not shipped: the kernel anti-cheat client
(
V2/ue/Plugins/V2AntiCheat/) and thelibs/proto/v2/onlinegRPC contract are absent (see ../architecture/online-backbone-and-competitive-integrity.md), and the AI-produced broadcast (commentary, lip-sync, translation) is a provider-gated capability the orchestration calls, not a model V2 trains (see ../architecture/esports-companion-and-ai-services.md).
Ranked season architecture (§75)#
One catalogue, four policies, one validator#
The whole season hangs off FV2RankedSeasonArchitectureCatalog. Its scalar
frame is concrete and asserted: SeasonLengthDays = 90,
PlacementMatchesAtSeasonStart = 10, OffSeasonTournamentCycleDays = 14, plus
the booleans that encode the design's promises —
bPerRegionSeasonOverlapEnabled, bOffSeasonTournamentCycleUsesSandboxedMMR,
bVisibleRanksUseHysteresis, bPlacementUsesPriorSeasonMMRSeed, and
bLegendIsTop100Global. Hanging off it are four arrays/policies — the visible
tiers, the region seasons, the season rewards, and the MMRPolicy,
DecayPolicy, CrownOverlay, and AntiThrowIntegrity sub-structs. The spec
asserts the negative cases as well as the positive: it constructs the default,
checks IsValidCatalog, then drives the subsystem and reads the runtime
snapshot back, demanding RankedSeasonVisibleTierCount == 18 and
RankedSeasonRegionCount == 5. That round-trip — build → configure → snapshot —
is what makes this a checked spec rather than decorative data.
Visible tiers over a hidden rating#
The visible ladder is eight families —
EV2RankedVisibleTierFamily { Bronze, Silver, Gold, Platinum, Diamond, Master, Grandmaster, Legend }
(V2OnlineServicesTypes.h:128) — expressed as 18 FV2RankedVisibleTierSpec
entries (:12203). The default builder lays them out as
Bronze/Silver/Gold/Platinum/Diamond each in three divisions (a MaxDivision = 3
family) climbing on MinimumHiddenMMR from 0 up through 2250, then the three
apex singletons: Master (2400), Grandmaster (2600), and Legend (2850, the only
tier with bTop100Global = true). HasAllVisibleRankTiers()
(V2OnlineServicesTypes.cpp:12329) is not a length check — it iterates the five
divisional families requiring each of divisions 1-3 at MaxDivision == 3, then
requires a distinct Legend tier, so dropping Gold 2 or collapsing Diamond's
divisions fails validation outright. Every tier carries
PromotionHysteresisMatches = 3 and DemotionHysteresisMatches = 3 with
bRequiresMinimumRankChangeMatches, the field that implements the source's
"hysteresis prevents rapid promotion/demotion oscillation," and a
bPublicRankIconEligible flag the provisional system reads.
The rating that actually drives matchmaking is hidden.
FV2RankedSeasonMMRPolicy (:12308) pairs a PrimarySkillModel = TrueSkill2
with a SecondarySkillModel = Glicko2 (the same rating family the platform's
@oshun services use), keeps both behind hidden profile ids with
bHiddenMMRNeverShown = true, seeds a new season from the prior one at
PriorSeasonMMRSeedCarryoverPercent = 65, and unifies the pool across
{ PC, PlayStation, Xbox, Switch } with bUnifiedCrossPlatformMMRPool,
bCrossPlatformLeaderboard, and bPlatformIconLabels.
SupportsLaunchPlatforms() verifies all four are present — the spec calls this
"cross-platform unified MMR covers PC PS5 XSX Switch2."
bSmurfDetectionBlocksLowRankFarming is the hook that keeps a sharp new account
out of Bronze.
Placement, reset, decay, provisional#
The per-ladder runtime lives in FV2RankedLadderConfig (:11900) and
FV2RankedPlayerState (:11946): PlacementMatchCount,
StartingRating = 1000, SeasonalResetFloorRating = 900,
SeasonalResetCarryoverPercent = 50, and a TierThresholds array resolved by
ResolveTierId(Rating). The seasonal reset is a real deterministic
algorithm, not a flag —
UV2OnlineServicesBlueprintLibrary::ApplyRankedSeasonReset() computes the
rating offset from the ladder's starting rating, scales it by the carryover
percent, floors the result at SeasonalResetFloorRating, re-resolves the
visible tier, and re-arms the placement requirement:
const int32 RatingOffset = CurrentState.SkillRating - LadderConfig.StartingRating;
const int32 ResetRating = LadderConfig.StartingRating
+ (RatingOffset * LadderConfig.SeasonalResetCarryoverPercent) / 100;
OutResetState.SkillRating = FMath::Max(LadderConfig.SeasonalResetFloorRating, ResetRating);
OutResetState.TierId = LadderConfig.ResolveTierId(OutResetState.SkillRating);
FV2RankedSeasonDecayPolicy (:12356) implements the rest of the lifecycle:
decay applies only to { Grandmaster, Legend } after
MasterPlusInactivityDays = 14 (bDecayAppliesAboveMaster), reactivation costs
one placement match, ProvisionalMatchesRequired = 25 keeps the public rank
icon hidden for new accounts (bRankIconHiddenDuringProvisional), and
WeeklyRetentionBonusPoints = 15 rewards consistent weekly play. Each is
asserted by the spec, which demands the provisional gate be exactly 25 and the
retention bonus be non-zero.
Anti-throw integrity#
The competitive-integrity layer specific to ranked behaviour (as distinct from
the netcode anti-cheat covered in the
online-services sibling page) is
FV2RankedSeasonAntiThrowIntegrityConfig (:12444). It tracks loss streaks
against opponents more than LowerMMRDeltaThreshold = 250 rating below you,
flags an AnomalousLossStreakThreshold = 3, queue-penalizes chronic decliners
above a ChronicDeclineRatePercent = 35 for QueuePenaltyMinutes = 15, and
detects collusion when the same opponent recurs past
CollusionRepeatOpponentThreshold = 2. The booleans —
bSandbaggingThrowDetection, bAutoDerankConfirmedThrowing,
bMatchAcceptanceDeclineRateTracked, bCoordinatedThrowDetection,
bUsesFairPlaySignals — encode the source's "sandbagging / throwing detection,
match acceptance/decline rate tracked, coordinated-throw detection for
tournament play." Critically, bUsesFairPlaySignals means this consumes the
same fair-play event stream the ML classifiers do, and — matching the platform's
review-only posture — confirmed throwing de-ranks rather than silently
banning; discipline routes out to the shared trust-and-safety plane.
The esports circuit (§55)#
The TO admin console and the rule freeze#
A tournament organizer drives V2 through FV2TournamentAdminEventConfig
(:7433): bracket, seed-manifest, schedule, broadcast run-of-show, and
auto-result webhook ids, a SupportedBracketFormats list over
EV2TournamentBracketFormat { SingleElimination, DoubleElimination, RoundRobin, Swiss, Gsl },
a NoShowTimeoutSeconds = 300, a MaxRoundExtensionSeconds = 600, and the
TO-control booleans (bManualSeedingEnabled, bDisqualificationEnabled,
bRoundExtensionOverrideEnabled, bAutoResultReportingEnabled). The single
most important integrity feature is the rule freeze:
FV2TournamentEditionRuleSnapshot (:7557) captures a RulesHash, a
ReplayHeaderId, the ImportedRulesFileName, and the locked-down competitive
toggles — bClassicControlsOnly, bDefaultStagesOnly, bDefaultCostumesOnly,
bDisablesMercyFriendshipBabality, bForcedP1LeftP2Right,
bFinisherPolicyLocked — and stamps them with bSavedInReplayHeader = true.
This is the determinism dividend the architecture leans on everywhere: because
the match runs on an integer-frame simulator, freezing the TO's ruleset into the
replay header makes a recorded set reproducible against the exact conditions it
was played under. The cryptographic pull-and-verify of third-party results
(Start.gg / Challonge / Battlefy) against that replay hash is the designed
server-authoritative contract — the replay-hash determinism that backs it is the
part that is architecturally real today.
Crown Pro Tour points#
The season-long competitive ranking is the Crown overlay.
FV2RankedSeasonCrownOverlayConfig (:12394) wraps a
FV2CrownProTourRankingConfig (:7628) and layers points from four sources —
EV2RankedSeasonPointSource { Ranked, Tournament, Invitational, EvoBadge } —
weighted RankedPointWeight = 1, TournamentPointWeight = 3,
InvitationalPointWeight = 5, EvoBadgePointWeight = 2, so a deep run at a
major outscores a month of laddering. The ranking config sets a
QualificationCutoff = 32, awards points from both official and partnered
tournaments, surfaces an in-game Crown leaderboard widget and a profile badge,
and exposes a read-only third-party API.
bYearEndGrandFinalInvitesTopCrownPlayers closes the loop: the season's top
Crown players are invited to the year-end Grand Final. The broader per-region
major/regional calendar the source describes (NA/EU/JP/KR/LATAM/SEA…, qualifier
→ regional final → world final) is layered on top of this points engine; the
racing modes carry their own parallel FV2RacingEsportsBroadcastCatalog
(:26074) with explicit per-region series, validated separately in the module
spec.
The public result archive#
apps/v2/web/esports/results is the shipped, static face of the circuit
(§55.8). Its results.json carries a v2.esports.resultsArchive.v1 schema with
per-event, per-match, per-player, per-fighter records and rankingWeights
(championship 120, major 90, regional 55, local 25, plus an 8-point win bonus
and a 2-point replay bonus); results.js filters by fighter, player, date, or
event and computes the Crown-linked community power ranking. Its README is an
integrity statement as much as a description: the archive exposes only public
competitive results — never raw account identifiers, contact information,
private moderation notes, or unpublished replay links.
Streamer, speedrun, coach & spectator modes (§55)#
These four player-facing modes are the remaining sub-configs of the one
validated FV2EsportsTournamentFeatureSet, each with a real cross-checking
validator.
Spectator & broadcast#
FV2EsportsSpectatorPolicy (:7383) caps in-match observers at
MaxInMatchObservers = 8 (clamped), throttles spectator chat to
ChatMessagesPerMinute = 6, sets an AntiLeakDelaySeconds = 120 anti-spoiler
buffer, and enables the production toolkit — director-cam, scriptable cuts,
picture-in-picture, the side-by-side stick cam, drawing tools, freeze-frame,
slow-motion, name plates, and the score overlay. The caster's surface is
FV2BroadcastControlSurface (:7499): a manual control surface with
configurable SupportedDelaySeconds (0/30/60/120), output integrations over
EV2BroadcastOutputIntegration { Obs, Ndi, Spout, BrowserSource, JsonWebSocket },
replay-marker clip-cut, a post-match recap reel, and a documented public SDK at
apps/v2/web/dev-portal/caster-api/schema.json. Third-party overlay developers
consume FV2CasterOverlayApiContract (:7828) — a documented WebSocket route
(/v2/caster-api/ws) and REST route, gated by bPerEventApiTokenRequired so
only a verified TO's per-event token can read live match state. The operator
side of this — the actual program/clean-feed switcher, multiviewer, and
stream-health dashboard — is the shipped @v2/esports-tools package
(apps/v2/esports-tools/esports-broadcast-pipeline.ts), which composes
@uzume/broadcast and tags itself off-rollback-broadcast-operations; its OBS
WebSocket use is scoped to "streamer-mode-notification-suppression-only," and
result-reporting journalism runs through @veritas/fact-checking. None of it
can perturb the sim.
Streamer mode & stream-safe music#
FV2StreamerModePrivacyProfile (:7672) is the broadest of the validators.
IsValidProfile (V2OnlineServicesTypes.cpp) refuses the profile unless the
anti-stream-snipe match-start delay is configurable inside 1-5 minutes
(MinAntiStreamSnipeDelaySeconds = 60, Max = 300, with Min <= Max) and
every privacy flag is set: hide handles and region, show the opponent as
"Opponent," default voice chat off, blur non-friend avatars/emotes/lobby chat,
suppress capture-aware notifications, auto-activate stream-safe music, and
persist the pause/main-menu quick toggles. A second clause requires the streamer
toolkit — the overlay generator, Twitch/YouTube/Kick channel binding, OBS
browser-source widgets, subscriber-tier cosmetic gift triggers, and stream-aware
notification suppression. The "stream-safe music automatically swaps licensed
tracks for cleared analogues" promise is a different module:
FV2StreamerSafeMusicCatalog (V2Audio/Public/V2AudioTypes.h:6205) carries
per-track license metadata (bPerTrackLicenseMetadataRequired), a DMCA-safe
toggle, and a ResolveTrack() that returns a cleared replacement for a
restricted track, with bAutoApplyDefaultPresetInStreamerMode wiring it to the
privacy profile's bAutoActivatesStreamSafeMusic. It is validated by its own
FV2StreamerSafeMusicSpec.
Coach mode & async coaching#
FV2CoachSessionConfig (:7746) models both halves of the source's coaching
story. The live half binds a PlayerAccountId and CoachAccountId into a
training lobby (bTrainingOnlineLobby) where the coach gets a separate camera
(bCoachSeparateCamera), can record and play back dummy inputs
(bRecordPlaybackDummyInputs), annotate moments (bMomentAnnotations), and
push notes to the player (bPushNotesToPlayer). The async half is
bAsyncReplayAnnotations with bPlayerNotifiedForAnnotatedReplay: a coach
attaches annotations to a submitted replay and the player is notified to watch
it back. The deterministic replay pipeline this rides on is documented in the
mode catalogue & replay page.
Speedrun support#
FV2SpeedrunSupportConfig (:7790) ships the built-in run timer
(bBuiltInRunTimer) with per-mode split definitions
(SplitDefinitionSetId = "Speedrun.Splits.LaunchModes"), a pace tracker against
personal best, and two integration seams: a local LiveSplit bridge on PC
(bLiveSplitLocalWebSocketPc, LiveSplitLocalWebSocketPort = 16834) and a
read-only ingest from the speedrun.com partner program
(SpeedrunPartnerProgramId = "speedrun.com.partner.readonly"). The read-only
framing is deliberate — V2 displays community speedrun standings without letting
an external surface write into the competitive record. (The Speedrun Race
multiplayer stipulation — racing the Arcade ladder side-by-side — is a separate
mode-catalogue spec, FV2SpeedrunRaceModeSpec, covered in
signature events & standalone modes.)
How it connects#
Ranked seasons and the esports feature set are both V2OnlineServices C++
catalogues validated by contract specs, and they share a spine: the
deterministic, integer-frame match. That determinism is what lets the
Tournament-Edition snapshot freeze a ruleset into a replay header, lets the
anti-throw layer and the server validators re-derive a result from inputs, and
lets the AI-produced broadcast sit entirely off the simulation path. The numbers
that tune the ladder are a C++ build-default today, not yet hot-editable JSON;
the kernel anti-cheat client and the gRPC wire contract are designed, not
present; and the generative half of the broadcast is a provider-gated capability
the orchestration calls. Everything player-facing here — the eight rank
families, the ten-part esports feature set, the streamer privacy profile, the
public result archive — is shipped and pinned by a spec that would fail on a
stub. The section hub is ../V2_features.md.
Related#
- Online Services, Network & Tournaments — the matchmaking backbone, netcode selection, anti-cheat, and TO tooling this ladder rides on
- Community, Store, Support & AI Services — the season rewards, the companion app, and the AI-produced commentary the broadcast consumes
- Mode Catalogue, Training & Replay — the deterministic replay pipeline behind coach annotations and the broadcast recap reel
- Signature Events & Standalone Modes — the EVO Top 8 / King of Iron Fist event catalogue and the Speedrun Race stipulation
- Esports, Companion & AI Services — the architecture companion for the broadcast/spectator stack and the provider-gated AI services
- Online Backbone & Competitive Integrity — the backbone, the replay-hash integrity check, and the designed-not-present surfaces
- The section hub: ../V2_features.md