# Live Service, Progression & the Vault

V4 is six genuinely different games — a Rainbow-Six breach, a Hitman sandbox, a
Commandos squad puzzle, a Black-Myth boss duel, an Age-of-Empires ladder, a
couch-co-op Contra run — wearing one roster, one account, and one online
backbone. What turns that catalogue into a _product that keeps growing_ rather
than six boxes you finish is the live-service spine: a 90-day season cadence, a
hundred-tier battle pass, two independent XP ladders, a year-long themed
calendar, operator and mission DLC delivered without a binary patch, a
region-aware store, and a per-account vault that keeps a player's best replays
and speedrun ghosts forever. This page is the player-facing tour of that spine,
and it keeps the same honesty line the rest of V4 holds to: the **composition
machinery is real, compiled C++ and tested Rust**, while the specific _content_
that machinery is built to deliver — the exact Year-1 cosmetics, the cooked
operator art — is authored design data the code is designed to execute, not
binary engine assets on disk. Where a claim is backed by code, this page names
the subsystem and the function; where it is a plan, it says so. The section hub
is [../V4_features.md](../V4_features.md).

The design choice underneath everything is the one V4 follows everywhere: a unit
of live content is **data plus a load plan**, never a new C++ subclass. A season
is an `FV4SeasonCadence` value; a DLC operator is an
`FV4DLCGameFeatureDefinition` whose `GameFeaturePluginURL` is a `plugin://` URI;
a cosmetic is an `FName` token routed into a typed inventory. That keeps the
whole live-service surface exhaustively unit-testable headless, long before any
map is cooked, and it keeps post-launch content flowing through the same
GameFeature plugin boundary the per-cell rulesets already use — never touching
the deterministic gameplay core.

## What ships, honestly

The live-service spine is split across two real code tiers plus one honest
"deployment substrate" seam.

- **`UV4LiveServiceSubsystem`** — the live-ops domain layer, ~1,116 lines of C++
  at `V4/ue/Source/V4OnlineServices/Private/V4LiveServiceSubsystem.cpp`. It
  exposes roughly forty `BlueprintPure` builders and validators for season
  cadence, battle-pass tracks, cell-themed cosmetics, operator/mission DLC, the
  themed calendar, ranked ladders, signature events, and brand partnerships. The
  composition is **real arithmetic and real validation**, not a manifest reader
  that echoes its input.
- **`UV4ProfileSubsystem`** and **`UV4CurrencyLedger`** — the progression layer
  in `V4/ue/Source/V4Persistence`. The profile subsystem owns the operator and
  account XP ladders, the Codex, and the typed cosmetic inventory; the currency
  ledger is an overspend-rejecting, server-validated wallet.
- **The Rust `online-services` crate** — `apps/v4/online-services` mounts the
  back-end of the same surface: a `ReplayService` (the vault), a
  `SpeedrunGhostArchive`, a `StoreService` (currency rules, pricing, DRM, DLC
  offers), and a `ContractAuthorService` (daily/weekly contracts, faction
  rewards), all behind real Axum routes in `src/http.rs`.

Coverage is genuine. The `V4Tests` suite is ~92 `.cpp` files;
`LiveServiceSpec.cpp` alone carries 84 `Test*` assertions over cadence, battle
pass, DLC, calendar, ranked, and partnerships, and `RoundTripSpec.cpp` carries
92 over the profile, ledger, contract, and replay-store subsystems. The Rust
crate adds 14 unit tests in `lib.rs` and 13 route tests in `http.rs`.

Four honest caveats, the same ones the architecture companion
[../architecture/game-modes-live-service.md](../architecture/game-modes-live-service.md)
records. **First, the cosmetic content is uncooked**: every reward in these
builders is an `FName` token (`Skin.Winter.RavenParkas`,
`WeaponSkin.Blacksite.Rifle`), and a scan of the plugin tree finds JSON
`*.uasset.v4asset.json` stand-ins and zero binary `.uasset` — the IDs are real,
the art is a target artifact. **Second, the Rust state is in-memory**
(`BTreeMap`, `Arc<Mutex<T>>`); the PostgreSQL/Redis/ClickHouse/S3 stores the
deployment names are the production target, covered in
[../architecture/game-modes-live-service.md](../architecture/game-modes-live-service.md).
**Third, the five-faction "season-long competition"** is real _reward_ data
(`ContractAuthorService::faction_rewards()` mints five factions) riding a
generic leaderboard primitive, not a dedicated faction-war engine. **Fourth,
Twitch Drops and the creator-code revenue program** are owned by
`community-service` and `creator-relations-service`, covered in
[Content, Creator & Community](./content-creator-and-community.md), not these
packages.

## Live service: seasons, the calendar & DLC

### The season cadence — and why client and server agree

A season is `FV4SeasonCadence`, and `BuildSeasonOneCadence` fixes Season 1 at a
**90-day** run, a **10-day** pre-season reset, **5** placement matches, and a
mid-season balance patch on **day 45**. The predicates around it are small, real
logic rather than flags: `IsSeasonActiveDay` bounds `[0, 90)`,
`IsPreSeasonResetDay` accepts `[-10, 0)`,
`RequiresPlacementMatchesDuringPreSeason` returns the 5 placements only inside
that pre-season window, and `IsMidSeasonBalancePatchDay` fires exactly on
day 45. The same constants are returned by the Rust `launch_season_cadence()`
(`lib.rs:645`) and its `is_preseason_reset_day` /
`is_midseason_balance_patch_day` mirrors — so the client UI and the server agree
on the calendar by construction, not by a hand-synced config. The mid-season
patch ships through the data-table hotfix channel, so the back half of the
season plays a tuned meta with no binary update.

### Battle pass, contracts & factions

`BuildBattlePassTracks` mints two tracks per season at a flat **1000 XP per
tier**: a **Free** track of 50 tiers and a **Premium** track of 100 tiers, each
carrying its reward-ID list. Tier progression is _driven by Account XP_, not a
separate pass currency — `operator-account-progression.json` sets
`drivesBattlePassTierProgress: true`, and the account ladder is the engine
underneath. The pass cosmetics never touch balance: a reskin shares its base
weapon's stats exactly, the line `StoreService::can_share_cosmetic` enforces by
refusing any stat-changing cosmetic.

The recurring engagement loop is contracts, modeled in the Rust
`ContractAuthorService`. `daily_contracts` mints three objectives at 250 XP each
(`Daily.Eliminate`, `Daily.Extract`, `Daily.Support`); `weekly_contracts` mints
seven at 1000 XP each, one per cell plus a social objective. Rotation is keyed
to a UTC server reset: `server_reset_key(epoch_hour, reset_hour)` snaps to a
normalized day with `div_euclid(24)`, and `should_refresh_at_server_reset`
returns true only when the previous and current reset keys differ — so dailies
roll over at the reset boundary and not before. `faction_rewards()` defines the
five factions the world-state fiction uses (Vanguard, Swarm, Choir, Modern
Forces, Resistance), each with a 500-XP reward and a themed cosmetic track;
faction reputation is per-faction and the aggregate ranking rides the service's
generic `leaderboard` / `submit_score` primitive.

### The themed calendar

`BuildLiveServiceThemeWindows` returns the five recurring windows that mirror
`V4/liveops/live-service-calendar.json` — Winter Operation (December), Lunar New
Year (Jan–Feb), Spring (Mar–May), Summer Heat (Jun–Aug), Harvest (Sep–Nov) —
each with a featured playlist, limited-time contracts, and themed cosmetics.
`ResolveLiveServiceThemeForMonth` walks them through `V4MonthInThemeWindow`,
which **handles the December→February wraparound correctly** (when
`StartMonth > EndMonth`, a month matches if it is `>= start` _or_ `<= end`). The
calendar is self-checking: `ValidateLiveServiceCalendar` asserts exactly one
theme covers every one of the twelve months, that the anniversary login bonus is
active on Oct 1 but not Oct 8, that there is exactly one 100%-proceeds charity
drive per year, and that the six platform cosmetic tie-ins cover all nine
required platform IDs. The competitive line is enforced in the data itself:
every `FV4PlatformCosmeticTieIn` carries `bGameplayStatsAffected = false` and a
platform-holder approval ticket, and `ValidatePlatformCosmeticTieIn` rejects any
tie-in that is not cosmetic-only and marketing-signed. Beyond the recurring
windows, `BuildSignatureEventModes` authors the Year-1 event slate — Halloween
"Night Shift" (a tactical-FPS PvE horror playlist with NPC reskins), Holiday
"Hometown Skirmish" (festive map reskins across all six cells plus a
limited-time RTS map), Pride "Signal Colors" (a creator-pick partner-charity
cosmetic suite), and a mid-season Esports All-Stars exhibition — and
`ValidateSignatureEventModes` pins each one's shape.

### DLC over the GameFeature boundary

New playable content rides the same plugin boundary as the rulesets.
`BuildOperatorDLCDefinitions` and `BuildMissionDLCDefinitions` emit
`FV4DLCGameFeatureDefinition`s whose `GameFeaturePluginURL` is
`plugin://<PluginName>` (built by `V4MakeDLC`). The free/paid split is encoded,
not described: an operator DLC is valid only when it is **free for premium-pass
holders at price 0** (`ValidateDLCGameFeatureDefinition` requires
`bFreeForPremiumPass && PriceUsdCents == 0` for the `Operator` type), while a
mission DLC must price inside the **$9.99–$19.99** band
(`ValidateMissionPriceTier` bounds `[999, 1999]` cents). The Rust
`StoreService::dlc_gamefeature_offers()` returns the same two offers — the
season-1 Nyx operator at 0 cents free-for-pass, and the Blacksite campaign at
1499 cents — so the store back-end and the in-engine builder describe one
catalogue.

```mermaid
flowchart LR
  Cad[BuildSeasonOneCadence / launch_season_cadence] -->|90d · 10d reset · day-45 patch| Pass[BuildBattlePassTracks]
  AccXP[Account XP ladder] -->|drives tier progress| Pass
  Contracts[daily/weekly contracts] -->|XP| AccXP
  Cal[BuildLiveServiceThemeWindows] -->|themed cosmetics + LTM contracts| Client[V4 client]
  DLC[BuildOperator/MissionDLCDefinitions] -->|plugin:// GameFeature, no client patch| Client
  Pass --> Client
```

## Progression: operator, account & the Codex

### Two XP ladders, one anti-grind cap

`UV4ProfileSubsystem` runs two independent tracks. **Operator XP** levels each
named operator **1→100** (max 99,000 XP); **Account XP** levels the player
**1→1000** (max 999,000 XP). Both share a flat 1000-XP-per-level curve through
the shared helpers `V4CalculateLevelFromXP` and `V4XPRequiredForLevel`, and both
**clamp at their ceiling** rather than overflowing — `AddXP` and `AddOperatorXP`
each pin the running total to `V4MaxXPForLevelTrack(...)`. The anti-grind rule
is real arithmetic: `ClampOperatorDailyXPGrant` returns 0 once an operator hits
the **5,000-XP daily cap** and otherwise clamps a grant to the remaining
headroom. `RoundTripSpec.cpp` pins exactly this —
`ClampOperatorDailyXPGrant(4900, 250)` returns `100`,
`CalculateAccountLevelFromXP(999000)` returns `1000`, and the operator-100
threshold is `99000`. Reward milestones (`DA_ProgressionModel` mirrors them)
hang Codex entries, titles, perk slots, cross-cell skins, and the Level-100 /
Level-1000 mastery cosmetics off the two ladders.

### The currency ledger

`UV4CurrencyLedger` (`V4/ue/Source/V4Persistence`) is the wallet, and it is
fail-closed. `ApplyTransaction` credits and debits a supported currency but
**refuses an overspend** — `RoundTripSpec.cpp` drives a balance of 60
OperatorTokens and asserts a −100 debit is rejected while the audited balance
stays 60. Hard currency takes a stricter path: `ApplyServerValidatedTransaction`
for `CombatPoints` requires a real platform and a server token, and the test
confirms a `NAME_None` platform is rejected. The back-end agrees on the shape:
`StoreService::currency_rules()` defines three currencies — `OperatorTokens` and
`EliteTokens` (soft, cross-platform) and `CombatPoints` (hard, **per-platform**)
— and `can_share_currency` / `is_per_platform_currency` encode the rule that
soft currency crosses platforms while hard currency cannot, the code-level
reason hard-currency balances are per-platform.

### Codex & the cosmetic inventory

The Codex is an unlockable in-game encyclopedia across eight categories
(`BuildCodexCategories`: Operator, Weapon, Gadget, Map, Faction, Civilization,
Ruleset, Vehicle), each `FV4CodexEntryDefinition` carrying lore, an asset
gallery, and design commentary plus level gates. `CanUnlockCodexEntry` is a real
predicate — it requires the account to meet `RequiredAccountLevel` _and_ (when
set) the named operator to meet `RequiredOperatorLevel` — and
`BuildLaunchCodexEntrySamples` ships nine fully written sample entries (Cobra's
dossier, the Clubhouse map, the MH-6 Little Bird, and so on). Cosmetics route
into a typed inventory across nine categories (`BuildLaunchCosmeticCategories`);
`UnlockCosmeticItem` rejects an unknown category, records source and a
cross-platform flag, and `HasCrossPlatformCosmetic` reads it back — the
round-trip test confirms an operator skin's cross-platform flag survives a
save/load cycle.

## The vault, the ghost archive & the store

### The replay vault

The per-account vault is the Rust `ReplayService`, and it is real retention
logic. A fresh upload gets `DEFAULT_REPLAY_RETENTION_DAYS = 14` and a
`DefaultCloud14Day` tier. **Starring** a replay (`star_archive_at`) flips it to
`LIFETIME_REPLAY_RETENTION_DAYS` (`u16::MAX`) and a `LifetimeStarredArchive`
tier — a starred replay survives the expiry sweep, which `expired_replays`
computes as `created_at + retention_days·86,400 ≤ now`, skipping anything
starred. The hard launch quota is **500 starred per account**: once
`starred_count` hits `MAX_STARRED_REPLAYS_PER_ACCOUNT`, the next star returns
`LimitReached`. The decisions are exhaustive — `Archived`, `AlreadyArchived`,
`NotFound`, `LimitReached`, `AccountMismatch`, and (on unstar)
`RestoredDefaultRetention`, which returns the replay to normal 14-day expiry.
`starred_archive` returns the account's vault ordered by archive time then ID.
And account-deletion is handled: `scrub_deleted_account_from_replay` clears the
deleted account's identifiers, repaints its pawn track to
`Skin.Anonymous.DeletedAccount`, and stamps the record `privacy_scrubbed`. The
vault test exercises all of it — stars to exactly 500 then asserts
`LimitReached`, asserts `AccountMismatch` when the wrong account stars a replay,
and asserts the scrub anonymizes the pawn track while preserving the replay.

### The ghost data archive

`SpeedrunGhostArchive` keeps the fastest _verified_ run per route so other
players can race it in-game. Submission is gated hard:
`submit_verified_speedrun_ghost` returns `RejectedInvalid` if any field is empty
or the duration is zero, `RejectedUnverified` unless `verified_by_server` is
set, and `RejectedSlowerOrEqual` if the run does not beat the current active
ghost. Every accepted ghost carries the replay's SHA-256, an input-stream hash,
and checkpoint hashes. A faster run **supersedes** the prior one: the previous
record flips to `Superseded` with a `superseded_by_ghost_id` pointer and the new
record records its `parent_ghost_id`, so `ghost_lineage` keeps the full chain
rather than overwriting history. The test submits a 510,500 ms run, rejects a
slower 512,000 ms run as `RejectedSlowerOrEqual`, accepts a faster 498,250 ms
run, and asserts the lineage retains the superseded entry with the correct
supersession pointer.

### The store & region-aware pricing

`StoreService` is the store back-end, and its routes are real (`store_router()`
in `http.rs` mounts purchases, currency-rules, battle-pass, dlc-offers, regional
prices, per-region lookup, and a pricing-transparency endpoint).
`regional_prices()` returns six PPP-anchored regions — US ($59.99 base,
tax-exclusive), EU, JP, BR, IN, TR — each with a `ppp_index`, a `tax_display` of
`inclusive`/`exclusive`, and minor-unit prices for the standard edition, the
battle pass, and a 900-CombatPoints pack; `platform-store-features.json` and
`DA_PlatformStoreFeatures` are the authored mirror.
`validate_pricing_transparency` is a genuine gate: it requires all six regions
present and every row to carry a non-empty currency, positive prices, a positive
PPP index, and a valid tax-display mode — the code behind the public
`/store/pricing` page that publishes method, last-updated time, and refund
policy. DRM is an allow-list, not a wrapper: `verify_drm_receipt` accepts only
the seven first-party providers (Steam, EOS, PSN, Xbox, Nintendo, App Store,
Google Play) and explicitly returns `ThirdPartyDrmRejected` for a Denuvo wrapper
— the code expression of V4's no-third-party-DRM commitment. Achievements unify
across platforms too: `platform_achievement_providers()` maps one
six-achievement design onto PSN trophies (with the Platinum), Xbox gamerscore,
Steam, Nintendo, Apple Game Center, and Google Play Games, each
server-authoritative with an offline queue and account-link backfill.

```mermaid
flowchart TD
  Match[match / speedrun] -->|upload| RS[ReplayService 14-day default]
  RS -->|star_archive| Vault[(lifetime vault · 500 cap)]
  Vault -->|unstar| RS
  RS -->|account deletion| Scrub[scrub → anonymous skin · privacy_scrubbed]
  Match -->|verified submission| Ghost[SpeedrunGhostArchive]
  Ghost -->|faster supersedes| Lineage[(retained lineage)]
  Store[StoreService] -->|regional_prices · DRM allow-list| Pricing[/store/pricing transparency/]
  Store -->|dlc_gamefeature_offers| Client[V4 client]
```

## How it connects

The through-line is the same as the rest of V4: the **machinery is real** —
compiled C++ composition over typed manifests, tested Rust domain services
behind Axum routes — and the page is precise about where shipped code ends and
the authored Year-1 content (the cooked cosmetics, the faction-war aggregation)
begins. The accounts, cross-progression, matchmaking, and replay _transport_
that this pass, vault, and ledger sit on top of are the online backbone's; the
cooked-content, cert, and store-of-record mechanics are the platform layer's.

## Related

- [Online Services, Networking & Esports](./online-services-networking-and-esports.md)
  — the login, matchmaking, leaderboard, and replay-transport backbone this
  spine reads from, and the esports stack the signature events feed
- [Platforms, Operations & Hardware](./platforms-operations-and-hardware.md) —
  the per-platform store of record, achievement/trophy sync, region cert, and
  hotfix channel the live calendar and pricing surface ride
- [Content, Creator & Community](./content-creator-and-community.md) — the
  workshop, contract author, Twitch Drops, and creator-code revenue program that
  share this backbone
- The architecture companion:
  [Game Modes & Live Service](../architecture/game-modes-live-service.md) — the
  subsystem topology, GameFeature delivery, and the in-memory-vs-deployment
  store split
- The section hub: [../V4_features.md](../V4_features.md)
