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.
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, andV2FrameDataPublisherappear in the monolith's engine- module table but are not directories underV2/ue/Source/and are not plugins. Treat them as named-but-unbuilt. - Two glossary "modules" are actually plugins.
V2AdaptiveAIandV2AICommentaryare listed as engine modules but live as GameFeature/runtime plugins underV2/ue/Plugins/, which is whyV2Gameplaycan take a hard module dependency onV2AdaptiveAI(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) andV2Modding(mod loading) are fully present on disk withBuild.csfiles but appear nowhere in the glossary table (agrepforV2World/V2Moddingin the monolith returns nothing). - The per-mode plugins do not exist. The ~90
V2Mode_*,V2Event_*, andV2RaceMode_*rows are a planned GameFeature surface; mode identity today lives only in theV2Modesregistry module. The monolith's own disk-status note (2026-06-12) already concedes this. Plugins/V2Editor/is a vestigial folder — it contains only aResourcesdirectory, no.upluginand no module. The real editor tooling is the Source moduleV2/ue/Source/V2Editor/, which the.uprojectloads as anEditor-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 "
V2UIdoes not depend onV2Netcodedirectly" is false in code —V2UI.Build.cslistsV2Netcodeas a public dependency. - V2 has no central Zod contracts. Unlike V1 (whose domain contracts live in
libs/contracts/src/<domain>), there is nolibs/contracts/src/v2. V2's data contracts live in UE C++UDataAsset/DataTabletypes 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.
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.csdeclaresV2Combat(Animation reads frame data to drive motion). Likewise the monolith'sAnimation → Audio/Animation → VFXedges do not exist —V2AudioandV2VFXhave zeroV2*dependencies. It isV2Cinematicsthat depends onV2AudioandV2VFX. - Netcode depends on Combat, not the reverse. The monolith draws
Combat → Netcode;V2Netcode.Build.csdeclaresV2CombatandV2Input(the rollback simulation re-runs combat).V2Telemetryin turn depends onV2Netcode, so analytics can tap rollback and network-quality events. - UI reaches deep, including into Netcode.
V2UI.Build.cspublicly depends onV2Combat,V2Gameplay,V2Input,V2Modes,V2Modding, andV2Netcode— 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 → PersistenceandOnline → Telemetry; in codeV2OnlineServiceshas noV2*dependencies, and it is the (glossary-absent)V2Worldmodule that depends onV2OnlineServices,V2Persistence, andV2Telemetry. - Modes is leaner than drawn, and server-aware.
V2Modesdepends onV2Core/V2Input/V2Netcode(public) andV2Combat/V2Gameplay(private), and addsV2Animationonly on non-server targets (if (Target.Type != TargetType.Server)inV2Modes.Build.cs). It does not depend onV2UI,V2Cinematics, orV2Persistenceas 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 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 and
rollback netcode; 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.
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,
live-ops, store & community,
esports, companion & AI services, and
telemetry, performance & release gates.
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.
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.
- The spine in depth: combat, GAS, frame data & determinism, animation & input pipeline, rollback netcode & tag-team.
- Modes and content built on
V2Modes/V2World: game modes, training & replay, open-world, co-op & special modes, presentation, A/V & signature content, UI, HUD, VR/AR & accessibility. - The racing satellite cluster: racing & vehicle architecture.
- The backend the
V2Servicesmodule bridges to: online backbone & competitive integrity, live-ops, store, progression & community, esports, companion & AI services. - Build/test/release topology: build, cook, assets, data & production, telemetry, performance, testing & release gates, security, compliance & sister-monorepo integration.
- The full catalogue: ../V2_ARCHITECTURE.md.