Tactical Action · Architecture

High-Level Architecture

A focused page within the Tactical Action Architecture documentation. The full map and every sibling page live in the Architecture hub.

5sections9 minread2diagrams

On this page

V4 is a tactical-action universe rather than a single game: one Unreal Engine 5.5 LTS project hosts six distinct gameplay "cells" — tactical FPS, stealth, real-time-tactics (RTST), souls-like Action RPG, RTS, and 2D run-and-gun — under one shared roster, one shared AI-perception model, and one online backbone. The architectural bet that makes that universe tractable is modular hosting: the frame-critical mechanics for each genre live in their own C++ engine module, and each ruleset (Rainbow-Six-style 5v5, a Hitman sandbox, a Commandos squad mission, an Age-of-Empires ladder) ships as an Unreal GameFeature plugin layered on top of those modules, so a cell can be enabled, disabled, stripped per platform, or shipped as DLC without touching the shared engine. This is not a slide-deck claim — it is wired through the repository. The project at V4/ue/V4.uproject sets "DisableEnginePluginsByDefault": true, declares 28 C++ modules, and enables 28 V4Mode_* GameFeature plugins (plus four content-only DLC plugins and two editor tools), every one of which exists on disk with a real *.Build.cs and a Public//Private/ source split. Across V4/ue/Source/ there are 272 .cpp and 189 .h files; one sample cell plugin (V4Mode_Tactical_R6Modern) has already been compiled on this box, with Binaries/Linux/libUnrealEditor-V4Mode_Tactical_R6Modern.so sitting next to its source. This page is the orientation map for how those pieces fit at runtime; the section index for the full catalogue is ../V4_ARCHITECTURE.md.

The reason to read the code rather than the monolith's "High-Level Architecture" prose is that the two have drifted in a handful of load-bearing places, and an honest map says so each time. Where the .uproject, the Build.cs files, and the on-disk plugin tree disagree with the architecture monolith, this page treats the compiler's view as authoritative and labels the monolith as the aspirational spec.

What ships, honestly#

Real and on-disk (the compiler agrees). All 28 modules named in the .uproject Modules array exist as directories under V4/ue/Source/, each with a *.Build.cs declaring exactly what it links. The genre cores are substantial, not skeletal: V4Tactical carries 12 .cpp/12 .h (aim, ADS, recoil, cover, weapon attachments), V4ActionRPG and V4RTS 11 each, V4OnlineServices 15 .cpp/19 .h, and V4Tests holds 92 .cpp of automation (per-cell specs like AsymmetricRTSSpec.cpp, SpiesVsMercsSpec.cpp, ContractsAuthorSpec.cpp plus Gauntlet-style harnesses). The cell mechanics are domain-specific, not generic CRUD: V4Stealth ships V4LightGaugeComponent, V4SoundFootprintComponent, V4DisguiseComponent, V4BodyDragComponent, and V4MarkAndExecuteComponent; V4RTS ships V4FogOfWarComponent, V4TechTreeComponent, V4AgeUpComponent, and V4PathfindingSubsystem; V4ActionRPG ships V4PostureComponent, V4ParryComponent, and V4TransformationComponent. The four per-cell netcode strategies the monolith promises are real, distinct classes in V4Netcode (detailed below). The 28 V4Mode_* plugins are fully present with C++ modules — a genuine improvement over V2, where the analogous per-mode plugins were planned but absent.

Modeled as data, not binary art. V4's content is described in JSON sidecars, not cooked Unreal binaries: a tree-wide search finds 0 binary .uasset and exactly one binary .umap (Content/V4Core/Maps/BootMap.umap), against 891 .v4asset.json descriptors (GameFeatureData, DataAssets, maps, and DataTables all in JSON form — e.g. V4Mode_Tactical_R6Modern/Content/.../DA_R6ModernMode.uasset.v4asset.json plus DT_Operator_R6Modern.json). So the logic and data skeleton of every cell is real and version-controlled, while the hand-authored meshes, MetaHumans, audio, and cooked levels are not in-tree. Where a claim depends on that art, this page says so.

Spec-only or mislabelled, found by reading the disk. Five drifts are worth naming up front, because the deep pages reference these names: (1) the monolith's Project Layout shows a Source/V4Server directory — it does not exist; the server build is V4TournamentServer.Target.cs, which names the V4 module. (2) Unlike V2, the V4 build targets are minimal — none of them set determinism flags, presentation-slicing, or *_NO_RENDERER headless defines. (3) The Module Split table omits a real edge: V4UI publicly depends on V4Stealth. (4) The glossary lists 27 mode plugins; the disk and .uproject have 28 (the extra is V4Mode_Crossover_ShadowWar), and the four V4DLC_* plugins and V4Tools_DataLinter are unlisted entirely. (5) The primary V4 module is a thin bootstrap, not the fat composition root V2's V2 module is. Everything below is grounded in those files.

The runtime stack, ground-up#

The monolith renders the stack as a five-tier ASCII block; in code the layering is enforced by Build.cs dependency edges, and it resolves cleanly into a directed acyclic graph. The foundation is V4Core, whose Build.cs links only engine modules (Core, CoreUObject, Engine, InputCore, RenderCore, Slate, SlateCore) — zero V4* dependencies, exactly what a foundation module should be. Above it sit the engine subsystems (V4Gameplay for GAS, V4Animation, V4Input, V4Netcode, V4Modes, V4UI, V4Audio, V4VFX, V4Cinematics, V4Persistence, V4Telemetry). The shared cross-cell AI stack (V4PerceptionV4CrowdV4Schedules) and the six cell-mechanic modules form the next tier, and the GameFeature plugins ride on top.

flowchart TB subgraph PLUG["Tier 3 — Rulesets (28 V4Mode_* GameFeature plugins)"] direction LR p1[V4Mode_Tactical_R6Modern] p2[V4Mode_Stealth_Hitman] p3[V4Mode_RTS_Asymmetric] p4[V4Mode_ARPG_Wukong] pN["… 24 more (+4 V4DLC_*)"] end subgraph CELLS["Tier 2 — Six cell-mechanic modules + shared AI"] direction LR Tac[V4Tactical] Ste[V4Stealth] Tcs[V4Tactics] Arpg[V4ActionRPG] Rts[V4RTS] Arc[V4Arcade] Perc[V4Perception] Crowd[V4Crowd] Sched[V4Schedules] end subgraph SPINE["Tier 1 — Engine subsystems"] direction LR GP[V4Gameplay · GAS] Anim[V4Animation] Inp[V4Input] Net[V4Netcode] Modes[V4Modes] UI[V4UI] end Core[V4Core · foundation] Boot[[V4 · bootstrap module]] p1 --> Tac & Modes & Net p2 --> Ste & Modes p3 --> Rts & Modes p4 --> Arpg & Modes Tac --> GP & Anim & Inp Ste --> GP & Perc Tcs --> GP & Perc & Sched Arpg --> GP & Anim Rts --> GP & Net Arc --> GP & Anim Crowd --> Perc Sched --> Crowd & Perc GP --> Core UI --> Ste Modes --> GP Anim --> Core Inp --> Core Net --> Core Perc --> Core Boot -.engine-only.-> Core

Two edges in that graph are worth dwelling on because they reveal the design. First, V4UI --> V4Stealth: the HUD links the stealth module directly (the light/shadow and detection gauges are first-class UI), which the monolith's Module Split table does not draw. Second, V4Schedules --> V4Crowd --> V4Perception: the NPC daily-routine system builds on the Mass-based crowd system, which builds on the unified perception model — so a Hitman crowd, a Commandos patrol, and a Splinter Cell mercenary all read stimuli through the same V4Perception state machine, which is the monolith's central "one AI model across every cell" promise expressed as a dependency arrow.

The cell-hosting model: GameFeatures, not a fat root#

The single most important structural fact about V4 is how a cell becomes active, and it is the cleanest departure from V2. The module named simply V4 (V4/ue/Source/V4/, 3 .cpp/3 .h) is the composition root that all three targets name via ExtraModuleNames.Add("V4") — but its Build.cs depends on engine modules only (Core, CoreUObject, Engine, GameplayTags, InputCore) and on none of the gameplay or cell modules. It hosts exactly two classes: UV4BootstrapSubsystem (a UGameInstanceSubsystem) and UV4GameplayTagsManager (a UEngineSubsystem), each with an Initialize override. In other words, the root does not fuse the cells together the way V2's V2 module fuses AV2CombatCharacter and AV2GameMode; it boots the engine and the native tag registry and then gets out of the way.

The actual fusing is done at runtime by V4Modes, the GameFeature activation machinery. Its public surface — V4ModeSubsystem, V4ModeBootstrapSubsystem, V4ModeRoutingActor, V4QuickPlayPlaylistRunner, V4LocalMultiplayer, and crucially V4GameFeatureAction_ActivateModeAssets — is the concrete mechanism by which selecting a mode activates its plugin's assets and components. Each cell plugin is a real Unreal GameFeature: V4Mode_Tactical_R6Modern.uplugin declares a Runtime module, "CanContainContent": true, "EnabledByDefault": false (mounted but not auto-activated — it is hot-activated per match), and pulls in the GameFeatures and GeometryCollectionPlugin engine plugins it needs for replicated destruction. Its Build.cs depends on V4Modes, V4Netcode, V4Tactical, and V4VFX — i.e. the ruleset plugin composes the shared cell-mechanic module (V4Tactical) with the activation, networking, and VFX infrastructure. The same pattern holds across genres: V4Mode_ARPG_Wukong depends on V4ActionRPG/V4Core/V4Modes; V4Mode_RTS_Asymmetric on V4RTS/V4Core/V4Modes. Each plugin then ships its own JSON-described GameFeatureData, DataTables, and map descriptors under its Content/ tree.

This is why "five cells" and "six cell-mechanic modules" both appear truthfully in the codebase. The High-Level Architecture stack diagram markets five genre families (Tactical FPS, RTST, Action RPG, RTS, 2D Run-and-Gun), folding stealth into the tactical family; the engine actually partitions six cell modules — V4Tactical, V4Stealth, V4Tactics, V4ActionRPG, V4RTS, V4Arcade — and maps the 28 ruleset plugins (five tactical, four stealth, two RTST, two ARPG, three RTS, two arcade, plus spec-ops/roguelike/horde/editor/replay/spectator/ training/lobby/crossover) onto them.

The load order encodes one more honest contrast with V2. Every one of the 26 runtime modules declares "LoadingPhase": "Default" in the .uproject — there is no PreDefault hoisting of V4Core or V4Gameplay the way V2 lifts its foundation and GAS spine ahead of the rest. Only V4Tests (a DeveloperTool module) and V4Editor (an Editor module at PostEngineInit) differ in type. V4 leans instead on Unreal's subsystem lifecycle to order startup: UV4GameplayTagsManager is a UEngineSubsystem, so the native tag registry initializes with the engine regardless of module phase, and UV4BootstrapSubsystem is a UGameInstanceSubsystem that runs as the game instance spins up — which is why the bootstrap root can stay engine-only and still guarantee tags exist before any cell activates. The four V4DLC_* plugins (V4DLC_Operator_Season01_Nyx, V4DLC_Campaign_Season01_Blacksite, two ADR community/parody packs) are content-only GameFeature plugins with no Source module — the same delivery mechanism, used for post-launch operators, campaigns, and remixes.

Subsystem boundaries: targets, netcode, and the plugin set#

Build targets — client, editor, tournament server#

Three .Target.cs files define the runtime topology, and they are deliberately thin. V4.Target.cs is a TargetType.Game build that adds the V4 module and sets BuildSettingsVersion.V5 — nothing more. V4Editor.Target.cs is the Editor build. V4TournamentServer.Target.cs is the TargetType.Server build; it disables developer tools and adds four broadcast-oriented defines — V4_TOURNAMENT_BUILD, V4_BROADCAST_TOOLS, V4_OBSERVER_CAMERAS, and V4_PAUSE_ON_DISCONNECT. Note honestly what is not here: unlike V2's V2Server.Target.cs, this server target does not define headless/no-renderer flags, does not strip the audio/UI/VFX plugins, and does not stamp determinism compiler arguments onto the build. V4's authority and determinism guarantees live one level down — in V4Netcode classes — rather than being enforced by the target rules. The "dedicated-server" topology the monolith describes is therefore a per-cell netcode choice, realized in code, plus a tournament/observer server variant, rather than a globally stripped headless build.

flowchart LR Game["V4 Game client<br/><sub>V4.Target.cs · all cells mountable</sub>"] Server["Tournament server<br/><sub>V4TournamentServer.Target.cs · observer/broadcast</sub>"] Editor["Editor + tools<br/><sub>V4Editor · V4Tools_AssetLinter/DataLinter</sub>"] subgraph BACK["Off-client plane (apps/v4 — Rust)"] online[online-services] tele[telemetry-ingest] sh[shared] end Game -- inputs / replication --> Server Game -- login/MM/replay/telemetry --> BACK Server -- match results / telemetry --> BACK Editor -. authors .-> Game

Netcode — four strategies, four real classes#

V4Netcode is where "a netcode strategy per cell" stops being prose. Its Public/ headers are: V4ClientServerNetcode + V4ServerAuthorityComponent (dedicated-server authoritative, for tactical PvP and Battle Royale); V4RTSLockstepSubsystem + V4RTSLockstepReplay (deterministic lockstep, for RTS); V4RollbackEmulatedComponent (rollback-emulated prediction, for tight twitch PvP); and V4LocalDeterminism (offline-deterministic, for single-player and co-op). It also ships V4ReplicationBandBudgeter (per-tier bandwidth budget) and a V4AntiCheatSubsystem. A keyword sweep over those headers confirms the weight is where the genres need it — 41 mentions of Lockstep, 28 of Rollback, 9 of Authoritative. The module depends only on V4Core plus the engine's NetworkPrediction and Iris plugins, so each cell selects its strategy without the strategies entangling each other.

The plugin set — explicit, genre-shaped#

Because "DisableEnginePluginsByDefault": true, every plugin is named explicitly, and the list reads like a bill of materials for a multi-genre engine: GameplayAbilities (GAS), EnhancedInput, CommonUI + ModelViewViewModel (UI/MVVM), the animation stack (MotionWarping, AnimationWarping, PoseSearch, IKRig, Mover, Chooser), Niagara + the Chaos deformer/destruction set (ChaosClothAsset, ChaosFlesh, GeometryCollectionPlugin, ChaosVehiclesPlugin), the Mass framework for crowds (MassEntity, MassAI, MassGameplay), PCG for procedural layouts, Paper2D for the arcade cell, the networking set (ReplicationGraph, NetworkPrediction, Iris), GameFeatures + ModularGameplay (the basis of the whole cell-hosting model), OnlineSubsystem/OnlineServices/EOSShared, Gauntlet for automation, the XR set (OpenXR, OpenXRHandTracking, OpenXREyeTracker, plus AppleARKit/ AppleVision gated by TargetAllowList), and the spatial-audio pair SteamAudio + ResonanceAudio. Platform stripping is .Target.cs-driven (the monolith notes Switch 2 and mobile drop the Warzone and R6 plugins), not #ifdef-driven, which is the whole point of putting rulesets in hot-swappable GameFeature plugins.

The off-client plane#

The cross-cutting backend lives outside the engine in apps/v4/, a small real Rust Cargo workspace (online-services, telemetry-ingest, shared; 11 .rs files) — login, matchmaking, replay, leaderboards, telemetry ingest, and balance publication, per the monolith's "Rust + Axum" framing. It is a skeleton relative to V2's 91-package TypeScript service tree, but it is genuine Rust, not a placeholder. The companion app, spectator portal, and marketing web surfaces sit alongside under apps/v4/companion/, apps/v4/spectator/, and apps/v4/web/.

Where to go next#

This page is the orientation hub; three sibling pages take the topology apart:

  • Glossary — the fixed vocabulary, the full 28-module map, and the module/plugin/service reconciliation table.
  • GAS Layout — how V4Gameplay carries per-cell attribute sets, ability classes, and gameplay tags as the shared combat spine.
  • Per-Cell Deep-Dives — the six cell-mechanic modules and their ruleset plugins, one genre at a time.
  • The full catalogue: ../V4_ARCHITECTURE.md.