# V2 Product Promise & Cross-Reference Conventions

V2 is one game — a fighting game built on Unreal Engine 5.5 — not a platform of
seven loosely-bound modes. This page is the orientation door to the V2
architecture: it states the product V2 commits to shipping, and it defines the
notation that lets four large planning documents, twenty-seven Unreal C++
modules, and an automated validation backbone all point at the same things
without drifting. The promise and the conventions belong together because, in
this repo, the convention is the mechanism by which the promise is kept honest:
a bare `§7.1` in any V2 doc resolves to a numbered task in `V2_TODOS.md`, that
task owns a JSON _contract_ under `V2/ue/Content/`, and a Python _checker_ under
`V2/ue/Tools/` fails CI if the shipped tree drifts from the contract. The
architecture file says it plainly — "Where a section names a module or path, it
names a **target artifact** unless the path already exists in the repo. The TODO
that first references the artifact owns creating it with tests and validation"
(`V2/V2_ARCHITECTURE.md:15`).

That target-artifact discipline is why this orientation page can be precise
about what is real versus planned: the same words that describe a subsystem are
the words a checker greps for. The backlog carries **138 numbered top-level
sections** — a count that is not a stylistic claim but a machine invariant:
`V2/tools/validate-v2-docs.py:156` literally asserts `if len(sections) != 138`
and fails the docs gate otherwise. The determinism the netcode promise rests on
is wired into the build target (`V2/ue/Source/V2.Target.cs`) as strict
floating-point compiler flags and a deterministic cook policy, not merely
asserted in prose. This page is the feature-and-promise companion to the
architecture catalogue; the section hub is
[../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md).

## What ships, honestly

The **module skeleton is real and consistent**. `V2/ue/V2.uproject` declares 27
modules and exactly those 27 directories exist under `V2/ue/Source/` — there is
no drift between the project file and the disk. Several modules carry genuine
weight rather than stubs: `V2Gameplay` is ~218 C++ files (GAS abilities,
attributes, match-state, the network-prediction movement component), `V2Combat`
~36, `V2Netcode` ~20, `V2Input` ~14. The **determinism build policy is real**:
all three targets — `V2.Target.cs`, `V2Server.Target.cs`, `V2Editor.Target.cs` —
turn off unity builds, add `/fp:strict /fp:except-` (MSVC) or
`-fno-fast-math -ffp-contract=off` (Clang), and
`V2/ue/Config/ DefaultGame.ini:10` sets `bEnableDeterministicCookOrder=True` and
`bDeterministicShaderCodeOrder=True`. The **validation backbone is real and
large**: **826** `*_Contract.json` files under `V2/ue/Content/` are paired with
**1,155** `check-v2-*.py` checkers under `V2/ue/Tools/`, fed by a 196 KB CI
workflow at `.github/workflows/v2-build.yml`. The **gRPC pre-build step is
real** — `V2.Target.cs` shells out to
`pnpm --filter @oshun/codegen run v2:grpc-stubs`, which resolves to
`tsx src/v2-grpc-stubs.ts` in `tools/codegen/package.json`. And the
**doc-convention gate is real**: `validate-v2-docs.py` resolves every Markdown
link to a file and anchor, checks every bare `§N` against `V2_TODOS.md`, and
rejects re-introduced "open decision" language.

A handful of promise-level claims are **spec-only or aspirational**, and this
page names them rather than implying they are shipped:

- The preprocessor symbols `V2_DETERMINISM` / `V2_STRICT_FP` are added as
  `ProjectDefinitions` in the targets, but **no `.cpp`/`.h` in `V2/ue/Source/`
  branches on them** — determinism is enforced today by compiler flags, cook
  settings, and the contract+checker gate, not by `#if V2_DETERMINISM` code
  paths. The defines are reserved seams.
- The architecture glossary lists **V2Peripherals, V2AntiCheat, V2DynamicMusic,
  and V2FrameDataPublisher** as engine modules; **none exist on disk** as Source
  modules or plugins. **V2AICommentary** and **V2AdaptiveAI** are listed as
  engine modules but actually ship as **plugins** under `V2/ue/Plugins/`, not as
  `V2/ue/Source/` modules.
- The 60-plus `V2Mode_*`, `V2Event_*`, and `V2RaceMode_*` rows in the
  game-feature-plugin roster are **planned GameFeature surfaces**; the disk has
  five plugin directories (`BellonaUnrealEditor`, `V2AICommentary`,
  `V2AdaptiveAI`, `V2AssetLinter`, `V2Editor`) and none of the per-mode plugins
  yet. Mode identity currently lives in the `V2Modes` registry module.
- The headline netcode numbers (rollback default for 1v1 + 2v2 tag, **≤ 8
  frames** of rollback at **≤ 100 ms** RTT, 60 Hz) are **stated targets** in the
  promise, not measured ship metrics on this page; the rollback engine's real
  state is the subject of
  [./rollback-netcode-and-tag-team.md](./rollback-netcode-and-tag-team.md).

**Provider-gated** surfaces are honest seams, not failures: cross-play and
cross-progression depend on the `OnlineServices` / `OnlineServicesEOS` plugins
enabled in the uproject and on per-platform back ends; locale-aware gore opt-out
depends on real rating-board data (`V2/legal/rating-boards.json`,
`platform-cert-bans.json`). Those are real integrations awaiting credentials and
platform sign-off, covered in
[./online-backbone-and-competitive-integrity.md](./online-backbone-and-competitive-integrity.md)
and
[./security-compliance-and-sister-monorepo-integration.md](./security-compliance-and-sister-monorepo-integration.md).

## The product promise

V2's promise, as authored in `V2_features.md` § "V2 Product Promise" and the
architecture's [`V2 Product Promise`](../V2_ARCHITECTURE.md) section, is a small
set of non-negotiable commitments. The unifying idea is **per-ruleset feel, one
shared spine**: when a match is in Mortal Kombat ruleset it must feel like MK;
in Tekken ruleset, like Tekken; in WWE ruleset, like WWE — "no compromise
blends" — yet all rulesets share one roster, one creator suite, one online
backbone, and one story.

| #   | Commitment                                                                                                                       | Code-grounding / status                                                                                                                                           |
| --- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1   | One product, not seven — per-ruleset feel with no compromise blends                                                              | Per-ruleset feel lives in the swappable `V2Modes` registry + (planned) per-mode GameFeature plugins                                                               |
| 2   | Rollback netcode **default** for 1v1 and 2v2 tag; ≤ 8 frames @ ≤ 100 ms RTT; 60 Hz                                               | Target. `V2Netcode` module exists (~20 files); strict-FP build backs frame-accuracy. See [./rollback-netcode-and-tag-team.md](./rollback-netcode-and-tag-team.md) |
| 3   | 3v3 tag, Royal Rumble, ≥ 30-in-ring on client-server with rollback-emulated prediction                                           | Tiered netcode envelope (diagram below); `V2_NetworkPredictionComponent` present in `V2Gameplay`                                                                  |
| 4   | BR-100, World Tour, Battle Hub, Convoy, Heist, World Boss on dedicated servers                                                   | `V2Server.Target.cs` is a real `TargetType.Server` with a Linux-dedicated-server contract gate                                                                    |
| 5   | Complete launch content — **no "coming soon" panels**                                                                            | Enforced socially by the backlog; `validate-v2-docs.py` rejects open-decision markers                                                                             |
| 6   | First-class single-player (Story, MyCAREER, MyRISE, Universe, MyGM, MyFACTION, GOAT Career, …) each ≥ 10 h                       | Planned `V2Mode_*` plugin surfaces; identity in `V2Modes` today                                                                                                   |
| 7   | Honor the audience — gore opt-in/out & locale-aware, faithful UFC sim, SF unsmoothed motion inputs, Tekken juggle, Def Jam feel  | Locale data in `V2/legal/`; input fidelity owned by `V2Input`                                                                                                     |
| 8   | Creator suite (CAF/CAW/CAS/CAA/CAE/CAM) as a first-class surface                                                                 | Spec-level; authoring tools in `V2Editor`                                                                                                                         |
| 9   | Cross-play & cross-progression across PC, PS5, XSX, Switch2, Steam Deck                                                          | Provider-gated via `OnlineServices`/`OnlineServicesEOS`                                                                                                           |
| 10  | Degrade safely under offline, partial-net, weak-grounding, low-bandwidth, controller-loss, mid-match-disconnect, provider-outage | Network quality & fallback design; `V2Netcode` + `V2OnlineServices`                                                                                               |
| 11  | Launch only with verification, observability, runbooks, release gates, rollback plans, post-deploy monitoring                    | The 1,155-checker + `v2-build.yml` gate plus `apps/v2/*` ops surfaces                                                                                             |

### The netcode envelope is a promise tier, not one switch

Commitments 2–4 are really one decision expressed in three tiers, because
rollback does not scale to arbitrary player counts at 60 Hz. The promise draws
the line explicitly, and the architecture mirrors it: rollback is the **default
for the small-roster competitive core**, prediction-on-client-server covers the
**mid-size scrums**, and dedicated servers carry the **large-world and
free-roam** modes where rollback is neither affordable nor meaningful.

```mermaid
flowchart TD
    A[Match request] --> B{Active fighters<br/>per side & mode}
    B -->|1v1 or 2v2 tag| C[Rollback netcode<br/>60 Hz · ≤8f @ ≤100ms RTT<br/>strict-FP determinism required]
    B -->|3v3 tag · Royal Rumble · ≥30 in-ring| D[Client-server<br/>+ rollback-emulated input prediction]
    B -->|BR-100 · World Tour · Battle Hub<br/>Convoy · Heist · World Boss| E[Dedicated server<br/>V2Server.Target.cs · authoritative]
    C --> F[V2Netcode rollback engine]
    D --> F
    E --> G[V2OnlineServices · ReplicationGraph · Iris]
```

The hard floor under tier 1 is determinism: rollback re-simulates past frames,
so the same inputs must produce bit-identical state on both peers. That is why
the build, not just the gameplay code, carries the determinism policy — it is a
property of how every module is compiled, covered next and in depth in
[./combat-system-gas-frame-data-and-determinism.md](./combat-system-gas-frame-data-and-determinism.md).

## Cross-reference conventions

Five V2 documents reference one another constantly. To avoid five competing
numbering schemes, V2 fixes one rule and machine-checks it.

**Bare `§N` and `§N.M` always resolve to `V2_TODOS.md`.** The backlog is the
only V2 document whose section numbers are used as hyperlinks. Verified counts:
**138** top-level `## N.` sections, **865** `### N.M` subsections, and **19**
`#### N.M.K` sub-subsections — **1,022 numbered headings** in total. (The
monolith's shorthand "~1000 numbered subsections" is best read as that
all-numbered-headings figure; the strict subsection count is ~884.) The
top-level **138** is the one figure the gate pins exactly.

Where ambiguity matters, references are **doc-prefixed**:

| Form                | Resolves to                          | Example                                                     |
| ------------------- | ------------------------------------ | ----------------------------------------------------------- |
| `§N` / `§N.M`       | `V2_TODOS.md` section (default)      | `§80` → Compliance Deep; `§52.8` → Live-service ops cadence |
| `deps§N`            | `V2_DEPENDENCIES.md` §N              | `deps§57` → Hardware Peripheral SDKs                        |
| `features§"anchor"` | `V2_features.md` by named anchor     | `features§"V2 Product Promise"`                             |
| `arch§"anchor"`     | `V2_ARCHITECTURE.md` by named anchor | `arch§"Rollback Netcode"`                                   |

`V2_features.md` and `V2_ARCHITECTURE.md` deliberately use **named anchors, not
numbers**, so they never duplicate the backlog's numbering. The docs-center
pages you are reading (this one and its siblings) follow the same rule: link a
backlog task by its `§N`, link a sibling page by its relative `./slug.md` path.

### The convention is enforced, not merely documented

`V2/tools/validate-v2-docs.py` is a real gate, and its checks map one-to-one
onto the rules above:

- **Section count** — `if len(sections) != 138: errors.append(...)`
  (`validate-v2-docs.py:156`). Add or delete a top-level backlog section without
  updating the docs and the gate fails.
- **Bare-ref resolution** — `BARE_SECTION_RE = §\s*(\d+)(?:\.(\d+))?`
  (`validate-v2-docs.py:39`); every `§N`/`§N.M` must resolve to a real
  `V2_TODOS.md` section or the script reports "does not resolve to V2_TODOS.md".
- **Link integrity** — every `[text](href)` must resolve to an existing file and
  (for `#anchor` links) a real heading slug.
- **No open decisions** — markers like `Owner: TBD`, `pending decision`,
  `placeholder task`, and `currently empty stub` are rejected, which is the
  enforcement arm of promise #5 ("no coming soon").
- **Package-name honesty** — every backticked `@scope/pkg` reference must be a
  real repo package, a package declared as planned in `V2_DEPENDENCIES.md`, or a
  name explicitly marked corrected/not-to-use.

### Worked example: following `§7.1` end to end

Take the bare reference `§7.1` (floating-point determinism). The convention says
it resolves to `V2_TODOS.md` §7.1. That task owns a target artifact, and the
artifact is a real contract on disk:

```jsonc
// V2/ue/Content/V2/Netcode/Determinism/FloatingPointDeterminism_V2_Contract.json
{
  "schema": "v2.netcode.floatingPointDeterminism.v1",
  "task": "V2_TODOS.7.1.floating-point-determinism",
  "targets": ["V2.Target.cs", "V2Editor.Target.cs", "V2Server.Target.cs"],
  "compilerDefinitions": [
    "DETERMINISM=1",
    "V2_DETERMINISM=1",
    "V2_STRICT_FP=1",
  ],
  "strictFloatingPoint": {
    "msvc": ["/fp:strict", "/fp:except-"],
    "clang": ["-fno-fast-math", "-ffp-contract=off"],
  },
  "cookSettings": {
    "bEnableDeterministicCookOrder": true,
    "bDeterministicShaderCodeOrder": true,
    "referenceDdcRequired": true,
  },
  "automation": {
    "checker": "V2/ue/Tools/check-v2-floating-point-determinism.py",
    "workflow": ".github/workflows/v2-build.yml",
  },
}
```

The contract's `automation.checker` points at
`check-v2-floating-point-determinism.py`, which reads the JSON and then
cross-validates the actual tree: it confirms the three `.Target.cs` files
declare the definitions and strict-FP flags, that `Config/DefaultGame.ini`
carries `bEnableDeterministicCookOrder=True` and
`bDeterministicShaderCodeOrder=True`, and that `Build/Build.xml` and the
`cook-all.sh` / `cook-all.ps1` wrappers pass `-architecture=x64` with a
reference DDC. That is the full chain a single `§7.1` implies: **doc reference →
backlog task → JSON contract → cross-file checker → CI workflow.** Multiply by
826 contracts and 1,155 checkers and you have the V2 verification backbone.

## How the promise is enforced in the tree

V1's domains ship their contracts as Zod schemas in `libs/contracts/src/`; V2
does **not** — there is no `libs/contracts/src/v2`. V2's "contracts" are a
different shape because the artifact under test is an Unreal project, not a
TypeScript service. Three enforcement layers carry the promise:

1. **Build-target invariants.** `V2.Target.cs` (game), `V2Server.Target.cs`
   (`[SupportedPlatforms(UnrealPlatformClass.Server)]`, editor-only data
   stripped), and `V2Editor.Target.cs` all call the same
   `ConfigureV2DeterministicBuild` and `AddV2GrpcGenerationStep` helpers, so
   determinism and the gRPC stub generation are uniform across game, server, and
   editor builds. `bUseUnityBuild = false` keeps translation-unit boundaries
   stable for reproducible builds.
2. **Contract + checker gates.** The 826 `*_Contract.json` files are the
   machine-readable spec for each target artifact; the 1,155 `check-v2-*.py`
   scripts are the gates that fail when the tree drifts. Their names read like a
   table of contents for the game — `check-v2-combo-counter.py`,
   `check-v2-hit-once-registry.py`, `check-v2-tekken-movement-layer.py`,
   `check-v2-chaos-cloth-presets.py` — each owned by the `§N` task that
   introduced it.
3. **CI orchestration.** `.github/workflows/v2-build.yml` runs the checkers and
   (on supported runners) the build/cook. The pre-build gRPC step keeps the
   service contracts and the engine client in lockstep: `tools/codegen` exposes
   both `v2:grpc-stubs` and `v2:grpc-stubs:check`, the latter for verifying
   generated stubs are current without rewriting them.

This is also why promise #11 ("launch only with verification, observability,
runbooks, release gates") is structurally credible rather than a slogan: the
gates already exist as code. The detailed treatment of those gates is
[./telemetry-performance-testing-and-release-gates.md](./telemetry-performance-testing-and-release-gates.md),
and the build/cook side is
[./build-cook-assets-data-and-production.md](./build-cook-assets-data-and-production.md).

## Module topology, briefly

The glossary's **engine-module table lists 30 names**; the disk has **27 Source
modules**. The deltas are worth stating once here and are explored in full in
[./glossary-and-module-topology.md](./glossary-and-module-topology.md):

- **In the glossary, absent from disk as Source modules:** `V2Peripherals`,
  `V2AntiCheat`, `V2DynamicMusic`, `V2FrameDataPublisher` (no on-disk presence
  at all), plus `V2AICommentary` and `V2AdaptiveAI` (present, but as **plugins**
  under `V2/ue/Plugins/`).
- **On disk, absent from the glossary table:** the umbrella `V2` game module
  (the target's `ExtraModuleNames.Add("V2")`), `V2Modding` (a real
  `UV2ModLoadingSubsystem` GameInstance subsystem), and `V2World` (whose
  `FV2WorldCatalog` is annotated "§130 runtime resolution requests/results
  (deterministic; no RNG)" — the open-world/persistent-world catalog).

The honest reading: the glossary is a forward-looking vocabulary, and the
on-disk module set is its current, internally-consistent realization plus two
modules (`V2World`, `V2Modding`) the glossary has not yet absorbed.

## Surfaces the promise spans

V2 is one game, but the product reaches beyond `V2/ue/`. Verified repository
surfaces:

| Surface                 | Path                         | Notes                                                                    |
| ----------------------- | ---------------------------- | ------------------------------------------------------------------------ |
| Game client             | `V2/ue/`                     | UE5.5 project, 27 modules, 5 plugin dirs                                 |
| Marketing / wiki tile   | `apps/oshun/web/src/app/v2/` | `glossary`, `roadmap`, `wiki`, `page.tsx`                                |
| Standalone web surfaces | `apps/v2/web/`               | 16 subtrees (`balance`, `calendar`, `community`, `dev-portal`, `e2e`, …) |
| Online services         | `apps/v2/`                   | 91 service directories (cloud back end)                                  |
| Balance authoring       | `V2/balance/`                | 30 category trees (`ai`, `audio`, `battle-royale`, `cinema`, `codex`, …) |
| Esports / doc tooling   | `V2/tools/`                  | `esports/` toolkit + `validate-v2-docs.py`                               |
| Legal / compliance      | `V2/legal/`                  | `rating-boards.json`, `platform-cert-bans.json`, `sub-processors.md`     |
| Engineering docs        | `V2/docs/`                   | 34 entries (`accessibility`, `asset-pipeline`, `audio`, …)               |

The breadth is itself part of promise #11: the live-ops, store, and community
back ends
([./live-ops-store-progression-and-community.md](./live-ops-store-progression-and-community.md)),
the esports/companion tooling
([./esports-companion-and-ai-services.md](./esports-companion-and-ai-services.md)),
and the racing surfaces
([./racing-and-vehicle-architecture.md](./racing-and-vehicle-architecture.md))
all hang off the same shared spine rather than forking it.

## How this connects to neighbouring systems

This page is intentionally shallow on subsystem detail — it owns the promise and
the notation, and hands off everywhere else. The combat core and its determinism
rules are
[./combat-system-gas-frame-data-and-determinism.md](./combat-system-gas-frame-data-and-determinism.md);
how inputs become deterministic frames is
[./animation-and-input-pipeline.md](./animation-and-input-pipeline.md); the
netcode tiering above is detailed in
[./rollback-netcode-and-tag-team.md](./rollback-netcode-and-tag-team.md). The
single-player and special surfaces — training/replay, presentation, UI/VR/AR
accessibility, and the open-world/co-op modes — are
[./game-modes-training-and-replay.md](./game-modes-training-and-replay.md),
[./presentation-av-and-signature-content.md](./presentation-av-and-signature-content.md),
[./ui-hud-vr-ar-and-accessibility.md](./ui-hud-vr-ar-and-accessibility.md), and
[./open-world-coop-and-special-modes.md](./open-world-coop-and-special-modes.md).
When you see a `§N` in any of those pages, this page's convention tells you
exactly where it points and how it is checked.

## Related

- Section hub: [../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md); feature map
  `V2/V2_features.md`; backlog `V2/V2_TODOS.md`; dependencies
  `V2/V2_DEPENDENCIES.md`
- [./glossary-and-module-topology.md](./glossary-and-module-topology.md) — the
  full 30-vs-27 module map, plugins, and racing modules
- [./combat-system-gas-frame-data-and-determinism.md](./combat-system-gas-frame-data-and-determinism.md)
  and [./rollback-netcode-and-tag-team.md](./rollback-netcode-and-tag-team.md) —
  where the determinism and rollback promises are made real
- [./telemetry-performance-testing-and-release-gates.md](./telemetry-performance-testing-and-release-gates.md)
  and
  [./build-cook-assets-data-and-production.md](./build-cook-assets-data-and-production.md)
  — the contract/checker/CI backbone in depth
- [./online-backbone-and-competitive-integrity.md](./online-backbone-and-competitive-integrity.md)
  and
  [./security-compliance-and-sister-monorepo-integration.md](./security-compliance-and-sister-monorepo-integration.md)
  — provider-gated cross-play, anti-cheat, and compliance surfaces
