# Subsystem Glossary, Module Map & Runtime Topology

This is the orientation map for V2 — the page you read before any of the deep
architecture pages, so that every later reference to "the `V2Combat` module" or
"the dedicated-server target" or "the gRPC adapter layer" lands on a name you
already trust. V2 is a frame-deterministic fighting game built on Unreal Engine
5.5, and its module split is not cosmetic packaging: it exists so that
frame-critical combat stays in C++ behind an explicitly declared, acyclic
dependency graph, so that a headless dedicated server can drop every rendering
and audio module without touching gameplay, and so that the build itself can be
compiled with strict floating-point and unity builds disabled for bit-stable
results. The single source of truth is the engine project at `V2/ue/`: its
`.uproject` enumerates **27 runtime/editor/tool C++ modules** plus a curated
plugin set, and each module under `V2/ue/Source/` carries its own `*.Build.cs`
declaring exactly what it links. This page reconciles that on-disk reality with
the prose glossary in the architecture monolith, and names the surrounding
TypeScript services and web surfaces that the game talks to. It is the companion
to the catalogue at [../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md).

The reason to read the _code_ rather than the glossary table is that the two
have drifted. The monolith's "Subsystem Glossary" lists 30 engine modules; the
disk has 27, and the overlap is imperfect in both directions. Where they
disagree, this page treats the `.uproject` and the `Build.cs` files as
authoritative and the glossary as the aspirational spec — and says so each time,
because an honest "the glossary names a module that has no code yet" is worth
more than a confident restatement of a table that the compiler would reject.

## What ships, honestly

**Real and on-disk (the compiler agrees):** the 27 C++ modules under
`V2/ue/Source/` are all present, each with a `*.Build.cs`, a
`Public/`/`Private/` split, and a module class; the `.uproject` `Modules` array
lists the same 27 names with explicit loading phases (verified: 27 source
directories == 27 `.uproject` entries). The fighting-game spine is substantial
rather than skeletal — `V2Gameplay` carries ~218 source and header files, `V2UI`
~172, `V2Combat` 36, and `V2Tests` holds **424 `.cpp` files** — 30 module
automation specs under `V2Tests/Automation/` (24 of them `*.Module.spec.cpp`)
plus a large `Private/` suite of Gauntlet-style bot harnesses (`V2CombatBot`,
`V2BotHarness`, `V2QuestCompletionBot`, `V2RandomExplorationBot`,
`V2RLTrainedExplorationAgent`, `V2BotCoverageMapping`), which is what backs the
glossary's "gauntlet drivers" line. The build targets are real and deterministic
(`V2.Target.cs`, `V2Server.Target.cs`, `V2Editor.Target.cs`). Three project
plugins ship with working modules (`V2AdaptiveAI`, `V2AICommentary`,
`V2AssetLinter`) plus the synced `BellonaUnrealEditor`. `V2Services` contains a
genuine gRPC adapter layer (`V2GrpcChannelManager`, generated stubs). Outside
the engine, **91 service packages** under `apps/v2/` are real Nx libraries (all
91 have a `project.json`), and the web tile at `apps/oshun/web/src/app/v2/` and
the standalone site at `apps/v2/web/` both exist.

**Glossary drift (spec-only or mislabelled), found by reading the disk:**

- **Four glossary modules have no code.** `V2Peripherals`, `V2AntiCheat`,
  `V2DynamicMusic`, and `V2FrameDataPublisher` appear in the monolith's engine-
  module table but are **not** directories under `V2/ue/Source/` and are not
  plugins. Treat them as named-but-unbuilt.
- **Two glossary "modules" are actually plugins.** `V2AdaptiveAI` and
  `V2AICommentary` are listed as engine modules but live as
  **GameFeature/runtime plugins** under `V2/ue/Plugins/`, which is why
  `V2Gameplay` can take a hard module dependency on `V2AdaptiveAI`
  (`V2Gameplay.Build.cs:20`) — a Source module is allowed to depend on a plugin
  module.
- **Two real modules are missing from the glossary.** `V2World` (persistent /
  open-world catalogue) and `V2Modding` (mod loading) are fully present on disk
  with `Build.cs` files but appear nowhere in the glossary table (a `grep` for
  `V2World`/`V2Modding` in the monolith returns nothing).
- **The per-mode plugins do not exist.** The ~90 `V2Mode_*`, `V2Event_*`, and
  `V2RaceMode_*` rows are a planned GameFeature surface; mode identity today
  lives only in the `V2Modes` registry module. The monolith's own disk-status
  note (2026-06-12) already concedes this.
- **`Plugins/V2Editor/` is a vestigial folder** — it contains only a `Resources`
  directory, no `.uplugin` and no module. The real editor tooling is the Source
  module `V2/ue/Source/V2Editor/`, which the `.uproject` loads as an
  `Editor`-type module. Do not mistake the empty plugin folder for a plugin.
- **The Module Split diagram's arrows are partly inverted** (detailed below),
  and its stated rule "`V2UI` does not depend on `V2Netcode` directly" is
  **false in code** — `V2UI.Build.cs` lists `V2Netcode` as a public dependency.
- **V2 has no central Zod contracts.** Unlike V1 (whose domain contracts live in
  `libs/contracts/src/<domain>`), there is no `libs/contracts/src/v2`. V2's data
  contracts live in UE C++ `UDataAsset`/`DataTable` types and in per-service
  TypeScript schemas, not a shared contracts library.

Everything below is grounded in those files; where a claim is the glossary's
intent rather than shipped code, it is labelled.

## The module graph as it is built

The `.uproject` declares the load order, and that order encodes the layering.
`V2Core` and `V2Gameplay` load in the **`PreDefault`** phase
(`V2.uproject:9–17`); everything else loads in **`Default`**, except `V2Editor`
(`Editor` type) and `V2Tests` (`DeveloperTool` type). `PreDefault` for `V2Core`
matters because `V2Core` owns the native gameplay-tag registry
(`V2CoreGameplayTags`) and the engine/game-instance subsystems that later
modules query during their own startup; `V2Gameplay` is hoisted alongside it
because it is the GAS spine that combat, modes, and UI all build on.

Reading every `*.Build.cs` and extracting the `V2*` dependencies yields a clean
**directed acyclic graph** — the monolith's "no circular deps" claim holds in
code. But the _shape_ differs from the monolith's Module Split mermaid in
several load-bearing edges. The diagram below is the graph as actually declared,
grouped by layer; corrected edges are called out after it.

```mermaid
flowchart TB
    subgraph FOUND["Foundation (no V2 deps)"]
        direction LR
        Core[V2Core]
        Audio[V2Audio]
        VFX[V2VFX]
        Online[V2OnlineServices]
    end
    subgraph SPINE["Fighting-game spine"]
        direction LR
        Input[V2Input]
        Gameplay[V2Gameplay]
        Combat[V2Combat]
        Anim[V2Animation]
        Net[V2Netcode]
        Modes[V2Modes]
        UI[V2UI]
    end
    subgraph SAT["Satellites"]
        direction LR
        Cine[V2Cinematics]
        Persist[V2Persistence]
        Tele[V2Telemetry]
        World[V2World]
        Modding[V2Modding]
        Svc[V2Services]
    end
    AdaptiveAI[[V2AdaptiveAI plugin]]

    Input --> Core
    Gameplay --> Core
    Gameplay --> Input
    Gameplay --> AdaptiveAI
    Combat --> Core
    Combat --> Gameplay
    Anim --> Combat
    Net --> Combat
    Net --> Input
    Modes --> Gameplay
    Modes --> Net
    UI --> Combat
    UI --> Modes
    UI --> Net
    UI --> Modding
    Cine --> Audio
    Cine --> VFX
    Persist --> AdaptiveAI
    Persist --> Input
    Tele --> Net
    World --> Online
    World --> Persist
    World --> Tele
    Modding --> Core
    Svc --> Core
```

**Corrections versus the monolith's Module Split diagram** — each verified
against the relevant `Build.cs`:

- **Animation depends on Combat, not the reverse.** The monolith draws
  `Combat → Animation`; `V2Animation.Build.cs` declares `V2Combat` (Animation
  reads frame data to drive motion). Likewise the monolith's `Animation → Audio`
  / `Animation → VFX` edges do not exist — `V2Audio` and `V2VFX` have **zero**
  `V2*` dependencies. It is `V2Cinematics` that depends on `V2Audio` and
  `V2VFX`.
- **Netcode depends on Combat, not the reverse.** The monolith draws
  `Combat → Netcode`; `V2Netcode.Build.cs` declares `V2Combat` and `V2Input`
  (the rollback simulation re-runs combat). `V2Telemetry` in turn depends on
  `V2Netcode`, so analytics can tap rollback and network-quality events.
- **UI reaches deep, including into Netcode.** `V2UI.Build.cs` publicly depends
  on `V2Combat`, `V2Gameplay`, `V2Input`, `V2Modes`, `V2Modding`, **and
  `V2Netcode`** — directly contradicting the glossary rule that uses this exact
  pair as its example. In practice the HUD needs rollback/connection state, so
  the dependency is real; the rule is the thing that is wrong.
- **OnlineServices is a leaf; World is the aggregator.** The monolith draws
  `Online → Persistence` and `Online → Telemetry`; in code `V2OnlineServices`
  has no `V2*` dependencies, and it is the (glossary-absent) `V2World` module
  that depends on `V2OnlineServices`, `V2Persistence`, and `V2Telemetry`.
- **Modes is leaner than drawn, and server-aware.** `V2Modes` depends on
  `V2Core`/`V2Input`/`V2Netcode` (public) and `V2Combat`/`V2Gameplay` (private),
  and adds `V2Animation` **only on non-server targets**
  (`if (Target.Type != TargetType.Server)` in `V2Modes.Build.cs`). It does _not_
  depend on `V2UI`, `V2Cinematics`, or `V2Persistence` as the monolith suggests.

### The composition root: the `V2` module

The module named simply `V2` (`V2/ue/Source/V2/`, six files) is the composition
root — the one module the `Game` and `Server` targets actually name via
`ExtraModuleNames.Add("V2")` (`V2.Target.cs:14`). It hosts the concrete classes
that fuse the spine together: `AV2CombatCharacter` and `AV2GameMode`. Its
`Build.cs` is the cleanest statement of the runtime topology: it publicly
depends on the gameplay/combat/modes/netcode/persistence/telemetry/world/racing
modules unconditionally, and then wraps the **presentation** modules —
`V2Animation`, `V2Audio`, `V2Cinematics`, `V2Input`, `V2UI`, `V2VFX`,
`V2VehicleAudio`, `V2VehicleVFX` — in `if (Target.Type != TargetType.Server)`. A
dedicated server therefore never links animation, audio, UI, or VFX at all; the
simulation half of the game compiles and runs without them. This is the
module-level expression of the headless-server design that
[the netcode page](./rollback-netcode-and-tag-team.md) relies on.

### Plugins: engine, project, and the empty folder

`V2.uproject` sets `"DisableEnginePluginsByDefault": true` (`V2.uproject:6`), so
every plugin the game uses is enabled explicitly — there are **35 plugin
entries**. Thirty-one are stock engine plugins, and they read like a bill of
materials for the genre: `GameplayAbilities` (GAS), `EnhancedInput`,
`CommonUI` + `ModelViewViewModel` (UI/MVVM), `Metasound` + `AudioModulation` +
`AudioGameplayVolume` (audio), `Niagara` (VFX), the animation stack
(`MotionWarping`, `AnimationWarping`, `PoseSearch`, `IKRig`, `Mover`, `Chooser`,
`ACLPlugin`), the deformer/grooming set (`ChaosFlesh`, `ChaosClothAsset`,
`HairStrands`, `AlembicHairImporter`), the networking set (`ReplicationGraph`,
`NetworkPrediction`, `Iris`), `GameFeatures` + `ModularGameplay` (the basis for
the planned per-mode plugins), `OnlineServices` + `OnlineServicesEOS`, and
`Gauntlet` + `TraceSourceFilters` for automation and tracing.

Four entries are project plugins. **`V2AdaptiveAI`** (runtime) and
**`V2AICommentary`** (runtime) carry real modules — confirmed by their
`.uplugin` `Modules` blocks — and **`V2AssetLinter`** is an `Editor`-type
plugin. **`BellonaUnrealEditor`** is the synced editor-consumer plugin from the
sister Bellona stack (it has a full `Source/`, `Config/`, and `Binaries/`). As
noted above, `Plugins/V2Editor/` is _not_ among them — it is an empty
`Resources` folder, and the editor module lives in `Source/` instead.

## Determinism is a build-target property, not a comment

A fighting game with rollback netcode has to produce identical simulation
results on two machines from the same inputs, and V2 enforces this where it
cannot be forgotten — in the target rules. `V2.Target.cs` (`:13–24`) sets
`bUseUnityBuild = false`, defines `DETERMINISM=1`, `V2_DETERMINISM=1`, and
`V2_STRICT_FP=1`, and appends strict floating-point compiler arguments:
`/fp:strict /fp:except-` on Win64 and `-fno-fast-math -ffp-contract=off`
elsewhere (`GetV2StrictFloatingPointCompilerArguments`). The same deterministic
block is duplicated in `V2Server.Target.cs` so the server simulates identically.
These are not decorative: determinism markers appear throughout the modules that
need them — `V2Combat` (`V2CombatResolver`, `V2CollisionAuthorityComponent`,
`V2CombatTypes`, `V2CombatRulesetData`) and `V2Netcode` (`V2RollbackSession`,
`V2RollbackSimWorld`, `V2RollbackTransport`, `V2NetworkQuality`). The full
treatment lives in
[combat & determinism](./combat-system-gas-frame-data-and-determinism.md) and
[rollback netcode](./rollback-netcode-and-tag-team.md); the point _here_ is
topological: determinism is a property the build target stamps onto every
module, which is why the module split keeps anything frame-critical out of
Blueprint and inside these C++ modules.

`V2Server.Target.cs` then carves out the dedicated-server slice (`:40–69`): it
sets `bBuildWithEditorOnlyData = false`, defines a wall of server flags
(`V2_HEADLESS_SERVER`, `V2_NO_RENDERER`, `V2_NO_AUDIO`, `V2_DEDICATED_SERVER`,
Linux/Win64 binary-pipeline variants), and **disables the rendering/audio engine
plugins outright** — `AudioGameplayVolume`, `AudioModulation`, `CommonUI`,
`Metasound`, `Niagara`. Combined with the `V2` module's presentation-slicing,
the server target is a genuinely thin headless build, not a full client with the
window hidden.

## Runtime topology: client, dedicated server, services, web

Three UE targets and two non-engine surface families make up the running system.

```mermaid
flowchart LR
    subgraph CLIENT["V2 Game Client (V2.Target.cs)"]
        spine["27 modules · GAS · rollback · CommonUI · Metasound · Niagara"]
    end
    subgraph SERVER["Dedicated Server (V2Server.Target.cs)"]
        hl["headless sim · no renderer/audio · rollback authority"]
    end
    svcbridge["V2Services module<br/><sub>gRPC channel mgr + generated stubs (HTTP/JSON)</sub>"]
    subgraph BACKEND["apps/v2 — 91 Nx packages"]
        direction LR
        tele[telemetry-*]
        online[matchmaking / seasons]
        live[live-ops / store / economy]
        ac[nous-anti-cheat-classifiers]
    end
    subgraph WEB["Web surfaces"]
        direction LR
        tile["apps/oshun/web/.../v2 (shell tile)"]
        standalone["apps/v2/web (standalone SPA)"]
        esports["@v2/esports-tools"]
    end

    CLIENT -- inputs/replays --> SERVER
    CLIENT --> svcbridge
    SERVER --> svcbridge
    svcbridge -- proto-generated --> BACKEND
    BACKEND --> WEB
    EOS[(EOS / OnlineServices plugins)] --- CLIENT
    EOS --- SERVER
```

The bridge from C++ to the TypeScript backend is the **`V2Services`** module.
Its public surface is `V2GrpcChannelManager`, `V2OshunDomainAdapters`, and
`V2ServiceTypes`, backed by `Generated/V2GeneratedGrpcStubs.h`. Those stubs are
not hand-written: both targets register a `PreBuildStep` that runs
`pnpm --filter @oshun/codegen run v2:grpc-stubs` (`V2.Target.cs:37–47`,
`V2Server.Target.cs:71–81`), so the `.proto` definitions under `libs/proto` are
regenerated into C++ on every build. `V2Services.Build.cs` adds the proto and
generated include paths plus `Json`, `JsonUtilities`, and `HTTP`, which is how
the module speaks to the services over HTTP/JSON-framed gRPC. Login, parties,
and matchmaking ride the engine's `OnlineServices` + `OnlineServicesEOS` plugins
on both client and server.

### The service backbone

`apps/v2/` holds **91 packages**, each a real Nx library (`package.json` +
`project.json` + `src/` + `vitest.config.ts`). They are not uniform in depth —
`telemetry-ingestion/src` is ~1,000 lines, while a focused service like
`nous-anti-cheat-classifiers/src` is ~170 — but every one is a buildable
TypeScript package, not a placeholder folder. They cluster into the families the
monolith's later sections describe: a large **telemetry** group
(`telemetry-ingestion`, `-data-pipeline`, `-schema-migrations`,
`-privacy-compliance`, `-session-reconstruction`, and more), **live-ops &
store** (`season-pass-service`, `dlc-content-delivery-service`,
`limited-time-game-mode-service`, `economy-analytics`,
`message-of-the-day-service`), **competitive integrity**
(`nous-anti-cheat-classifiers`, `themis-*` governance/dispute/DSR), and the
**sister-monorepo adapters** that bridge V2 to other Oshun deities
(`oshun-adapter`, `oshun-identity-binding`, `hathor-npc-adapter`,
`iris-realtime-translation`, `psyche-ai-director-hints`, `maat-finance-ledger`).
These are explored per-domain in
[online backbone & competitive integrity](./online-backbone-and-competitive-integrity.md),
[live-ops, store & community](./live-ops-store-progression-and-community.md),
[esports, companion & AI services](./esports-companion-and-ai-services.md), and
[telemetry, performance & release gates](./telemetry-performance-testing-and-release-gates.md).

### Web and companion surfaces

Two web homes exist and neither replaces the other. `apps/oshun/web/src/app/v2/`
is the **in-shell product tile**: `page.tsx` renders a single
`<V2ShellSurface/>` component, with `glossary/`, `roadmap/`, and `wiki/`
subroutes — the V2 entry inside the shared Oshun Next.js shell. `apps/v2/web/`
is the **standalone marketing / community / dev-portal SPA** (a Vite app with
`calendar/`, `community/`, `support/`, `esports/`, `dev-portal/`, `hub/`,
`legal/`, `live-service/`, and `balance/` sub-sites). The esports toolkit is a
separate package, `@v2/esports-tools`, at `apps/v2/esports-tools/`. Note that
`V2/tools/` otherwise contains only that toolkit and a `validate-v2-docs.py`
linter — the glossary's "Build, release, esports, mocap, data tooling" is mostly
aspirational, and `V2/tools/release/` does not exist (the monolith already marks
it "planned"). Balance authoring is its own tree at `V2/balance/` (30
subdirectories: `fighters/`, `racing/`, `stages/`, `feel/`, `progression/`, …)
that feeds DataTables; see
[build, cook, assets & data](./build-cook-assets-data-and-production.md).

## Glossary reconciliation table

The fastest way to use the monolith glossary safely is to read it through this
column. "Module" = a directory under `V2/ue/Source/` with a `Build.cs`; "Plugin"
= a module under `V2/ue/Plugins/`; "Service" = an Nx package under `apps/v2/`;
"Spec" = named but not present in code.

| Glossary name                                                                                      | On disk as                                                                                                                                            |
| -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| V2Core … V2Telemetry                                                                               | **Module** (each present)                                                                                                                             |
| V2Racing / V2Vehicles / V2RacePhysics / V2RaceTracks / V2RaceModes / V2VehicleAudio / V2VehicleVFX | **Module** (each present)                                                                                                                             |
| V2Editor                                                                                           | **Module** (Source); the `Plugins/V2Editor/` folder is empty                                                                                          |
| V2Tests                                                                                            | **Module** (`DeveloperTool`; 424 `.cpp` = 30 automation specs + bot harnesses)                                                                        |
| V2Services                                                                                         | **Module** (gRPC adapter layer)                                                                                                                       |
| V2AdaptiveAI                                                                                       | **Plugin** (runtime) — not a Source module                                                                                                            |
| V2AICommentary                                                                                     | **Plugin** (runtime) — not a Source module                                                                                                            |
| V2AssetLinter (not in glossary table)                                                              | **Plugin** (editor)                                                                                                                                   |
| V2World / V2Modding (not in glossary)                                                              | **Module** (both present)                                                                                                                             |
| V2Peripherals                                                                                      | **Spec** — no module/plugin                                                                                                                           |
| V2AntiCheat                                                                                        | **Spec** as a module; the `nous-anti-cheat-classifiers` **Service** is the present-day surface (no EAC/BattlEye plugin is enabled in the `.uproject`) |
| V2DynamicMusic                                                                                     | **Spec** — no dedicated module; the audio subsystem is `V2Audio`, and `euterpe-commentary-ducking` is a present **Service**                           |
| V2FrameDataPublisher                                                                               | **Spec** — frame data lives in `V2Combat` DataAssets; no publisher module                                                                             |
| `V2Mode_*` / `V2Event_*` / `V2RaceMode_*`                                                          | **Spec** — registry-only in `V2Modes`; planned GameFeature plugins                                                                                    |

## Where to go next

- The product framing this topology serves:
  [V2 product promise](./v2-product-promise.md).
- The spine in depth:
  [combat, GAS, frame data & determinism](./combat-system-gas-frame-data-and-determinism.md),
  [animation & input pipeline](./animation-and-input-pipeline.md),
  [rollback netcode & tag-team](./rollback-netcode-and-tag-team.md).
- Modes and content built on `V2Modes`/`V2World`:
  [game modes, training & replay](./game-modes-training-and-replay.md),
  [open-world, co-op & special modes](./open-world-coop-and-special-modes.md),
  [presentation, A/V & signature content](./presentation-av-and-signature-content.md),
  [UI, HUD, VR/AR & accessibility](./ui-hud-vr-ar-and-accessibility.md).
- The racing satellite cluster:
  [racing & vehicle architecture](./racing-and-vehicle-architecture.md).
- The backend the `V2Services` module bridges to:
  [online backbone & competitive integrity](./online-backbone-and-competitive-integrity.md),
  [live-ops, store, progression & community](./live-ops-store-progression-and-community.md),
  [esports, companion & AI services](./esports-companion-and-ai-services.md).
- Build/test/release topology:
  [build, cook, assets, data & production](./build-cook-assets-data-and-production.md),
  [telemetry, performance, testing & release gates](./telemetry-performance-testing-and-release-gates.md),
  [security, compliance & sister-monorepo integration](./security-compliance-and-sister-monorepo-integration.md).
- The full catalogue: [../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md).
