# Live-Ops, Store, Progression & Community

A modern fighting/racing game is a service, not a box — it ships and then lives
for years through seasons, balance patches, DLC fighters, cosmetic drops,
limited-time events, and the community that argues about all of it. This page
covers the four systems that keep V2 alive after launch: the **live-operations**
machinery (how content and events reach players, and how a broken event is made
good), the **store and economy** (how cosmetics and DLC are sold transparently,
within spend limits, and priced fairly across the world), **progression** (the
battle pass, fighter mastery, account level, and the codex), and the **community
and support** surfaces (governed social spaces, ambassadors, support tickets,
and the out-of-game web). The defining choice mirrors the rest of V2: the
live-ops spine is a set of real, narrow `apps/v2/` TypeScript packages composing
the shared Oshun economy, calendar, governance, and content substrates — not a
bespoke monolithic live-service backend — fronted in-engine by the real
`V2Services` and `V2OnlineServices` modules. The section hub is
[../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md).

## What ships, honestly

Three layers are **real code**, and one is honestly a plan.

The **live-ops service packages are real TypeScript** under `apps/v2/` (part of
the same ~91-package set the
[online backbone](./online-backbone-and-competitive-integrity.md) catalogues):
`season-pass-service` (2.0 K lines), `dlc-content-delivery-service`,
`live-event-scheduling-service`, `live-event-content-delivery-service`,
`patch-notes-service`, and `player-compensation-service` are all
fully-implemented pure-function surfaces with validation and tests, alongside
the economy packages (`economy-analytics-dashboard`,
`economy-balance-tuning-interface`, `isis-cosmetic-pipeline`,
`aje-web3-cosmetic-ownership`, `maat-finance-ledger`) and the community ones
(`kuanyin-community-harmony`, `themis-community-governance`,
`world-boss-community-raid-bridge`). The **per-platform store and entitlement
seam is real Unreal C++**: `V2OnlineServicesTypes.h` carries
`EV2OnlineServiceCategory::Store/Entitlements`, an
`OpenStore`/`QueryEntitlements` platform-SDK request surface, store-receipt
validation (`bStoreEntitlementReceiptValidation`), and a typed cross-product
entitlement claim (`FV2CrossProductEntitlementClaim`). The **progression and
codex data-of-truth is real**: CSV tables under `V2/balance/progression/` and
`V2/balance/codex/`.

What is **plan, not artifact**, and labelled as such throughout: the Year-1
_roadmap_ (which four fighters, which seasons, which drops) is a schedule the
services execute; the **gRPC wire contracts** the monolith specifies
(`libs/proto/v2/{live,progression,community}/*.proto`) **do not exist in the
tree** (`libs/proto/v2` is absent), so those method signatures are the designed
contract, not generated stubs; the `GameFeaturePlugin` delivery mechanism is the
documented engine system the download plans target, not a built V2 plugin; and
the premium-currency name "Crowns" is a design label — the live currency IDs in
service code are `fight-coins`, `season-credits`, and a `soft` earned currency.

## Live operations & content delivery

### The season calendar and event scheduling

The live calendar is **not a standalone V2 schema** — authority is the shared
Maat strategy plane. `@v2/maat-live-service-calendar`
(`maat-live-service-calendar.ts:31`) wraps
`buildMaatV2FightingGameLiveOpsCalendar` from `@maat/strategy` and asserts
`standaloneV2LiveCalendarReplaced` / `noStandaloneV2CalendarSchema`. Maat owns
seasons, the **Crown Points** seasonal pool (the ranking/esports points
currency, distinct from spend currency), the Pro Circuit calendar, anniversary
events, and charity events. The surface even pins the cross-domain wiring it
depends on as concrete arrays: `requiredGrpcSurfaces` (`Rank.GetSeasonState`,
`Rank.GetCrownPoints`, `Esports.GetBracket`, `Esports.QualifyForFinals`) and
`requiredEventTopics` (`v2.rank.season.started`, `v2.crown-points.granted`,
`v2.live-ops.anniversary.started`, …) — designed contracts, named honestly.

Individual events are scheduled by `live-event-scheduling-service`. A
`V2LiveEventScheduleDefinition` (`live-event-scheduling-service.ts:35`) carries
`startsAt`/`endsAt`, an optional earlier `visibilityStartsAt` (so an event can
be _announced_ before it is _playable_), `regions`, `activationTags`, the
`gameModes` it turns on (each with a `queueId` and `rulesetId`), and its
`rewards`. The service resolves each into an `upcoming` / `active` / `ended`
state and emits per-mode and per-reward activations — the engine flips a queue
on by reading state, never by shipping a patch.

### DLC and live-event content delivery

Post-launch content rides Unreal's **GameFeaturePlugin** system (the documented
delivery target): each DLC fighter pack, story expansion, and cosmetic drop is a
modular plugin delivered, activated, and — for license-conditional content —
hot-removable over the same per-fighter chunk boundaries the
[asset pipeline](./build-cook-assets-data-and-production.md) defines. The
`dlc-content-delivery-service` makes that delivery **entitlement-gated and
incremental**. `V2_DEFAULT_DLC_CONTENT_PACKS`
(`dlc-content-delivery-service.ts:105`) covers all three required pack kinds —
`fighter-pack` (the 620 MB "Nyx" fighter), `story-expansion` (the 1.25 GB "Storm
Market" chapter), `cosmetic-pack` (the 90 MB "Golden Gi") — each with `sha256:`
content hashes, `https://` asset URIs, and `/Game/V2/DLC/...` mount points, all
validated. `planV2DlcContentDownload` (line 221) is the real logic: if the
caller's `entitlementRefs` don't include the pack's `entitlementRef` it returns
`lockedReason: 'entitlement-required'` with a zero-byte plan; otherwise it diffs
`installedContentHashes` against the pack's assets and returns only the
**pending** assets plus the exact `totalDownloadBytes`.
`live-event-content-delivery-service` mirrors this for time-boxed event content
(`map` / `cosmetic` / `npc-dialogue` bundles) with the same entitlement-and-diff
download plan. Both are `serverAuthoritative: true, requiresClientPatch: false`
— content is a download, not a binary update.

### Patch notes and player compensation

Every balance hotfix pairs with a human-readable record. `patch-notes-service`
(`patch-notes-service.ts:12`) structures each release into three categories —
`balance`, `bug-fixes`, `new-content` — and renders a localized in-game payload
(`buildV2PatchNotesInGamePayload`) of display cards grouped by category,
carrying `locale`, `publishedAt`, and `minClientVersion`. The data-only hotfix
mechanism those notes describe is documented under
[Security & Compliance](./security-compliance-and-sister-monorepo-integration.md).

When something goes wrong — a broken event, a mispriced item, downtime —
**make-goods are a first-class capability**. `player-compensation-service`
(`player-compensation-service.ts`) models compensation **campaigns** keyed to an
`incidentId`, covering both required reasons (`bug` and `outage`), each with an
explicit approval chain (`approvals` must be non-empty —
`approvalRequired: true`), a grant bundle of currency and items, and a list of
`affectedPlayers` each carrying an `evidenceRef` (e.g.
`telemetry:ranked:reconnect:…`) and a severity. The two load-bearing properties
are **evidence and idempotency**: `buildGrantRecord` derives a deterministic
`grantId` of `comp:{campaignId}:{accountIdHash}` (line 506), and
`applyV2PlayerCompensationGrant` (line 340) refuses to double-pay — if the
ledger's `processedGrantIds` already contains the grant it returns
`duplicate: true, applied: false` and leaves balances untouched, otherwise it
merges currency and item grants into the ledger. A player is compensated exactly
once per incident, with a paper trail.

The Year-1 shape the services execute: 4 character DLC packs, a mode-expansion
DLC, and seasonal cosmetic drops on the paid side; balance patches, new stages,
new tower content, new tutorials, and accessibility on the **free** side — the
split that keeps the competitive playerbase unified (everyone gets balance and
stages) while monetising cosmetics and roster.

## Store, currency & PPP pricing

### Per-platform store, entitlement, and cross-product claims

The store integration is **per-platform-store-native**: Steam, PSN, Microsoft
Store, Nintendo eShop, and the Epic Games Store each have their own
consumable/entitlement/refund/family-share semantics, surfaced through a thin
`IPlatformStore`-style adapter behind the real `UV2OnlineServicesSubsystem`. In
engine, `V2OnlineServicesTypes.h` carries the typed store surface —
`EV2OnlineServiceCategory::Store`/`Entitlements`, the `OpenStore` /
`QueryEntitlements` SDK requests, store-receipt validation
(`bStoreEntitlementReceiptValidation`), platform-specific entitlement queries
(PS Plus, Smart Delivery, Game Pass) that **fail closed**
(`bPsPlusEntitlementsFailClosed`), and a verification surface whose issue types
(`MissingUserEntitlement`, `EntitlementNotOwned`, `EntitlementExpired`) make a
revoked or refunded purchase a real, handled state. Cross-product grants are
typed too: `FV2CrossProductEntitlementClaim` (issued by, e.g., `Lilith`, of
grant type `Cosmetic`, defaulting to `PrivateInventory` visibility) is how a
cosmetic earned in a sister product appears in V2 without leaking its source.
iOS and Android stores are **companion-app subscription only** — they never
grant game items.

### Currency, spend limits, and the make-good economy

The economy is deliberately **player-protective, by construction, not policy**.
Premium currency buys transparent items — no real-money loot boxes — with daily
spend limits, and per-platform IAP credit is kept ledger-separate from earned
currency for store-compliance reasons (see the cross-progression model in
[Online Backbone](./online-backbone-and-competitive-integrity.md)). The economy
is instrumented and tunable through real services: `economy-analytics-dashboard`
composes `@maat/finance` and classifies currency flow as `source-heavy` /
`sink-heavy` / `balanced` over real event topics
(`v2.economy.currency.earned/spent`, `v2.cosmetic.purchased`, supply/wealth
snapshots); `economy-balance-tuning-interface` composes
`@v2/remote-config-service` to expose `drop-rate` / `price` / `reward` tuning
families through `slider` / `currency-input` / `stepper` controls, so
rebalancing the economy is a config change, not a redeploy. Cosmetics are purely
cosmetic — nothing sold touches the deterministic combat sim, a hard
competitive-integrity line.

### PPP regional pricing — a real formula, not a table lookup

Fair global pricing is **real, tested math**. `@v2/maat-finance-ledger`
(`maat-finance-ledger.ts`) composes `@maat/finance`, whose
`calculateV2MaatFinanceRegionalPriceMinor`
(`libs/maat/finance/src/v2-persistence-ledger.ts:88`) computes
`min(priceCeiling, max(floor, round(baseline × pppRatioBasisPoints / 10_000)))`
— baseline price scaled by a per-region purchasing-power ratio, clamped to a
ceiling (capped at baseline, so no region pays a premium) and a floor (the
`priceFloorRatioBasisPoints` is the arch's ratio × 0.4 = 4000 bps guard against
inversion attacks). The same module's `buildV2MaatFinanceLedgerDecision` is the
spend gate: a `spend` whose `unitPriceMinor` disagrees with the computed
regional price, or whose gross ≠ price × quantity, is rejected
`region-price-mismatch`; a spend over the per-transaction cap or that would push
the day's total past the `regulatoryDailySpendCapMinor` (or the stricter
`minorDailySpendCapMinor` for minor accounts) is rejected
`regulatory-cap-exceeded` — **this is the "daily spend limit," enforced in code,
not prose**. Refunds require a `refundReferenceId` and fall inside
`refundWindowDays` or they are `refund-window-expired`. And because a console
can go offline mid-purchase, the engine keeps an in-cache ledger
(`offlineLedgerCacheMode: 'v2-engine-ledger-cache-reconcile-on-sync'`): an
offline-approved spend is marked `reconciliationRequired` and replayed against
the Maat source-of-truth on next sync. The whole ledger is
`offRollback: true, mayInfluenceRollback: false` — money never touches a
rollback frame.

### Cosmetic pipeline and opt-in on-chain ownership

Cosmetics originate in `isis-cosmetic-pipeline` (`cosmetic-pipeline.ts`), a real
four-stage pipeline — `model_generation` (`@isis/3d-generation`) →
`ai_texturing` (`@isis/ai-texturing`) → `universal_rigging`
(`@isis/universal-rigging`) → `bellona_cook_enqueue` (`@bellona/unreal`) —
covering ten cosmetic slots (outfit, hair, mask, gear, entrance prop, weapon
skin, vehicle skin, decal, palette, avatar accessory) across five platforms,
each variant stamped with a `V2CosmeticVariantProvenance` rights record
(`first_party` / `licensed_brand` / `ugc_creator` / `live_ops`). On-chain
ownership is the **clearly-bounded, opt-in, fail-closed** surface:
`aje-web3-cosmetic-ownership` (`aje-web3-cosmetic-ownership.ts:117`) only
approves a wallet-linked cosmetic when the player explicitly opted in **and**
accepted the exact warning text **and** the platform-cert policy hasn't banned
the surface **and** has explicitly cleared it **and** the verifiable credential
and ERC-721 metadata validate — every other path returns a typed `blocked-*`
reason. It is `off-rollback-opt-in-cosmetic-only`; the default is that nothing
is exposed.

```mermaid
flowchart LR
  Cal["maat-live-service-calendar<br/>(seasons · Crown Points)"] --> Sched[live-event-scheduling]
  Sched --> Del["dlc + live-event<br/>content delivery"]
  Del -->|"GameFeaturePlugin · entitlement-gated plan"| Client[V2 client]
  Store["UE Store / Entitlements"] --> Ent["entitlement verification<br/>(fail-closed)"]
  Ent --> Client
  PPP["maat-finance-ledger<br/>regional price + spend caps"] --> Store
  Econ["economy-analytics + balance-tuning"] -.tunes.-> Store
  Cos[isis-cosmetic-pipeline] --> Store
  Issue["outage / mispricing / bug"] --> Comp["player-compensation-service<br/>(idempotent make-good)"] --> Client
```

## Progression & codex

Progression spans the battle pass, fighter mastery, account level/prestige, the
codex, the unified quest log, and the reward inbox — all part of the
**cross-progression** shared state bound to one `@oshun/identity` root, so a
player's progress and purchases follow them across PC, PlayStation, Xbox, and
Switch (detailed in
[Online Backbone & Competitive Integrity](./online-backbone-and-competitive-integrity.md)).

The battle pass is the real, tested heart of it. `season-pass-service`
(`season-pass-service.ts`) builds an XP-based track of up to 60 tiers over a ≤
90-day season, with parallel `free` and `premium` reward lanes and rewards at
**every** level — verified by tests that assert `maxTier === 60`,
`durationDays === 90`, and rewards present at each tier. XP is
**server-authoritative and idempotent**: `applyV2SeasonPassXpGrant` (line 931)
dedups by `grantId`, so the spec's replayed grant leaves `totalXp` at `1200`
twice over; the four XP sources (`match-completion` 150–500, `daily-challenge`
500–1000, `weekly-challenge` 1500–2500, `event-bonus` 250–2000) require replay
evidence and anti-cheat validation; and premium-lane rewards lock with
`lockedReason: 'premium-entitlement-required'` rather than silently granting. A
weighted daily/weekly **challenge pool** auto-rotates a deterministic selection
per window, paying XP plus the `season-credits` currency.

The **codex and broader progression are data-of-truth, not a service stub**.
There is no dedicated progression-codex package; instead the real artifacts are
the CSV tables that round-trip into UE DataTables: `V2/balance/codex/`
(`codex-categories.csv`, `codex-fighter-entries.csv`) and
`V2/balance/progression/` (`account-level-rewards.csv`,
`fighter-mastery-tracks.csv`, `style-mastery-tracks.csv`, `prestige-tiers.csv`,
`mastery-level-rewards.csv`, `xp-gain-rates.csv`, `quest-log-catalog.csv`,
`reward-inbox-rules.csv`, `long-form-goals.csv`). The gRPC
`Progression`/`Codex`/`QuestLog`/`RewardInbox` service surface the monolith
specifies is the **designed contract** (the `libs/proto/v2/progression` package
is absent), with computation and the reward inbox living server-side and
mirrored to the client for HUD display. The principle throughout: progression
unlocks _content and cosmetics_, never _competitive advantage_ — fighters and
their frame data are balance-locked, not pay-gated.

## Community & support

Community is **governed, not unmoderated**, and the governance is composed
shared infrastructure rather than a V2 reimplementation.
`kuanyin-community-harmony` (`kuanyin-community-harmony.ts`) wraps
`@kuanyin/community-harmony` to bring emotional-temperature scoring, raid
detection, and defense-mode/trusted-only escalation to the V2 `crew` / `faction`
/ `battle-hub` spaces; `themis-community-governance` wraps `@themis/community`
(association- and sports-club-governance managers) for the rules-of-the-space
layer; and `world-boss-community-raid-bridge` composes `@hathor/simulation`
politics with the Kuanyin raid-defense toolkit so cooperative community-event
content is both driven and protected. All three are off-rollback,
trust-and-safety-only. Crucially, **discipline routes out to the same audited
Themis/Kuanyin plane that governs every Oshun product** over the event bus, so a
community ban and a match-conduct ban are the same auditable, appealable action.

The out-of-game surfaces are real web: `apps/v2/web/community` (an `index.html`
with `community.css/js/json` and a `meetups.ics` calendar feed) and
`apps/v2/web/hub`, alongside the read-only mobile companion covered in
[Esports, Companion & AI Services](./esports-companion-and-ai-services.md). The
**support backend** — a priority-tier SLA router (P0 account/payment/harassment
first-response ≤ 1 h through P3 feedback), Zendesk webhook integration,
Canny-style feature voting, an ambassador moderation console, a Hall of Fame,
and a 24-hour news-localization SLA across 18 launch locales — is **designed as
a gRPC/REST contract** (`libs/proto/v2/community/*.proto`, absent today). The
in-engine adapter list that binds all of this — `@maat/finance`,
`@maat/strategy`, `@kuanyin/moderation`, `@themis/community`, `@isis/*` and the
rest — is the real, validated `BuildRequiredAdapters` registry in
`V2OshunDomainAdapters.cpp:39`, every entry flagged
`bMayInfluenceRollback = false`.

## Edge cases & failure modes

- **A make-good pays once.** `applyV2PlayerCompensationGrant` dedups by
  `grantId`; a replayed campaign grant returns `duplicate: true` and changes no
  balances. Every grant carries an `evidenceRef` and a non-empty approval chain.
- **DLC won't download without entitlement.** `planV2DlcContentDownload` returns
  `lockedReason: 'entitlement-required'` with zero bytes for an unentitled
  caller; an entitled caller only downloads the assets whose content hashes
  aren't already installed.
- **Price can't drift or be spoofed.** A spend whose `unitPriceMinor` ≠ the
  computed regional price, or whose total ≠ price × quantity, is rejected
  `region-price-mismatch`; the regional price is clamped between a floor and a
  baseline ceiling so no region is overcharged and inversion attacks are
  bounded.
- **Daily spend limits are enforced server-side**, with a stricter cap for minor
  accounts, returning `regulatory-cap-exceeded` — and an offline purchase is
  cached and reconciled on next sync, never silently lost.
- **On-chain ownership fails closed.** Missing opt-in, an unaccepted warning, a
  cert-banned or un-cleared surface, or an invalid credential/metadata each
  yield a typed `blocked-*` reason; nothing is exposed by default.
- **The wire contracts are honest.** The gRPC calendar/progression/community
  services and the `GameFeaturePlugin`/EAC client tiers are designed contracts —
  `libs/proto/v2` and `V2/ue/Plugins/V2AntiCheat/` are not in the tree — while
  the pure-function ledgers, download planners, and the UE store/entitlement
  surface are real.

## Where this connects

- **Sideways:**
  [Online Backbone & Competitive Integrity](./online-backbone-and-competitive-integrity.md)
  (store entitlements, cross-progression, the event bus),
  [Esports, Companion & AI Services](./esports-companion-and-ai-services.md)
  (tournaments, Crown Points, mobile companion), and
  [Security, Compliance & Sister-Monorepo Integration](./security-compliance-and-sister-monorepo-integration.md)
  (spend limits, store compliance, hotfix mechanics).
- **Down to delivery:**
  [Build, Cook, Assets, Data & Production](./build-cook-assets-data-and-production.md)
  (the chunk boundaries DLC ships over, and the CSV ↔ DataTable round-trip the
  codex and progression tables use).
- **Platform:** the [shared platform](../../platform/overview.html) economy,
  calendar, governance, and persistence foundations the V2 services compose.
