Tactical Action · Features

Training, Replay, Signature Modes & the AI Director

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

7sections10 minread1diagram2tables

On this page

This is the connective tissue around V4's six genre cells: the rooms you go to to learn a cell before you queue, the theater that records and plays back what happened, the evergreen "premium identity" mode each cell carries beyond generic skirmish, and the invisible session-level Director that keeps a single-player fight from walling a beginner or boring an expert. None of these are a cell of their own — they are cross-cell surfaces that hang off the same shared roster, perception model, and online backbone — but each is a real, separately-shipped GameFeature plugin (or, for the Director, an in-tree game-instance subsystem), and three of the four are pinned by their own automation specs inside the V4Tests suite.

What makes this page worth its own entry is that one of its four subjects — the AI Director — is the place where V4 visibly out-builds its V2 ancestor. In V2 the "AI Director" was an engine plugin plus a pile of TypeScript hints with the named state machine and per-mode tuning left as feature-doc design spec. In V4 the Director is fully real, deterministic C++ with a compile-time guarantee that it can never touch competitive PvP — the kind of safety invariant V2 only described. The other three surfaces (training, replay, spectator) follow the house pattern: real domain logic in-tree, with the cooked content and the capture codec sitting at the documented engine boundary.

For the full mode taxonomy, roster, and the scope this slots into, start at the hub: ../V4_features.md.

What ships, honestly#

Four real surfaces, one of them a standout. The training range, replay theater, and spectator portal are three GameFeature plugins — V4Mode_Training_Range, V4Mode_Replay, V4Mode_Spectator — each a real .uplugin Runtime module depending on GameFeatures (the replay plugin also pulls in MovieRenderPipeline for its MP4 export). The AI Director is UV4AIDirectorSubsystem, a 459-line .cpp / 378-line .h game-instance subsystem inside V4Gameplay. Coverage is dedicated, not incidental: ReplayModeSpec.cpp carries 123 assertions, SpectatorModeSpec.cpp 55, HordeDefenseSpec.cpp 33, AIDirectorSpec.cpp 38, and TrainingRangeSpec.cpp 21 — and they test computed values, not truthiness (e.g. "objective capture outranks lower-value replay moments" pins HighlightReel[0].MarkerId against the ranking algorithm's output, not its existence).

Three honest qualifications, in the spirit of the architecture companion. First, the capture codec is the engine boundary. The replay plugin is the theater, archive, coach, ghost, and commentary logic; the bytes themselves ride Unreal's demo netdriver (for action cells) or a lockstep input-bundle (for RTS) — that recording layer is engine integration, and the soft asset paths these systems mint resolve to nothing until content is cooked, the same JSON-stand-in honesty the rest of V4 carries. Second, AI-generated commentary is a labeled seam. The highlight-reel scoring, mistake/what-went-well classification, consent gating, watermark/provenance requirements, and bias-review policy are all real C++; the text and voice route to a Calliope persona and a Psyche voice-synthesis request — those generative backends are an injected boundary, not synthesized in-engine. Third, signature-mode content is stand-in except where it isn't. The ten signature modes are a validated live-service manifest pointing at DA_*.uasset.v4asset.json stand-ins; the one whose gameplay engine is real compiled C++ is Horde Defense (the CoD-Zombies analogue), covered below.

Training: the practice surfaces#

V4Mode_Training_Range is the offline, pause-friendly onboarding cell. Training never gates content, but completing a cell's tutorial flight is the soft signal the matchmaker uses to seed a new player into a lower MMR band. The plugin ships four trainers plus a curriculum, each with real domain math.

Weapon range & recoil study#

UV4TrainingWeaponRange::BuildHitZoneVisualization authors four hit zones with real damage multipliers — head ×2.0, torso ×1.0, arms ×0.75, legs ×0.65 — and EvaluateShot returns a score of round(100 × multiplier) (200 for a headshot, 65 for a leg), so a player studying time-to-kill reads the same numbers the combat resolver would apply. BuildRecoilStudy walks a weapon's per-shot offset list, timestamps each shot at index × interval, and tracks TotalVerticalClimb and MaxHorizontalDrift so the held weapon's recoil pattern can be overlaid as a ghost trace.

Build-order trainer#

UV4TrainingBuildOrderTrainer carries a timestamped command list (queue worker at 0s, scout at 18s, barracks at 42s, age-up tech at 74s, first pressure squad at 110s) and ScrubReplayToTime partitions it at any clock value into completed command ids plus the next pending command — the engine behind "overlay the target build timeline and flag each step on-time / early / late."

Parry trainer & vision-cone range#

The Wukong parry trainer models a boss attack as frame bands — StartupFrames 28, ActiveFrames 12, RecoveryFrames 34, with a perfect-parry window on frames 24–30 — and EvaluateParryFrame color-codes any frame green (in the perfect window), red (inside the active attack), or yellow, drawing the on-screen frame bar the feature promises. The RTST cone-calibration range is genuine geometry: EvaluateTarget takes the acos of the clamped dot product between cone-forward and the direction to the target, marks it inside the cone only when within 1200 cm range and 35° half-angle, and computes a visibility score as distanceFactor × 0.5 + angleFactor × 0.5. UV4TrainingTutorialCatalog assembles the ~90-minute Master Tutorial across five cells, and ValidateCurriculum is a real gate — it fails the build unless the modules sum to exactly 90 minutes and cover all five training cells.

Replay theater, archive, coach & ghosts#

V4Mode_Replay is the largest of these surfaces — a 1,529-line systems file — and it splits into five real controllers.

Viewer & moment markers#

UV4ReplayViewerController builds a per-player track list (clamped 1–64), free-flight cameras with collision disabled and HUD hidden, a picture-in-picture grid that lays out min(N, 4) feeds on a ceil(sqrt(viewCount))-column tiling, and a frame cursor that steps, sets a playback rate clamped to 0.1×–8×, and rewinds by seconds. It also ships six cinematography presets — one per cell, from the Tactical "Handheld Combat Cam" to the RTS "Sweeping Overhead" — and resolves a preset by cell id. Moment markers are validated, sanitized, sorted by frame, and tag-defaulted to Replay.Marker.Custom.

Cloud archive & privacy scrub#

UV4ReplayCloudArchive enforces the retention policy in code: 14-day default retention, a 500-starred-per-account cap, and a lifetime expiry (9999-12-31) for starred replays. Starring promotes a record to LifetimeStarredArchive; unstarring drops it back to DefaultCloud14Day with a recomputed expiry. Crucially, ScrubDeletedAccountFromReplay is a real GDPR-style erasure: on account deletion it anonymizes every matching pawn track (clears the account id, swaps to Skin.Anonymous.DeletedAccount, flags it removed) and strips owner identifiers — the same retention/star/scrub contract the Rust online-services replay vault enforces server-side, so client and backend agree.

Speedrun ghosts & coach mode#

UV4SpeedrunGhostArchive::SubmitVerifiedGhost accepts a submission only if it is server-verified and carries an input-stream hash, a replay SHA-256, and checkpoint state hashes; a new ghost supersedes the active one only when its duration is strictly faster, and the superseded record is kept with a parent pointer so the full lineage survives. UV4ReplayCoachSessionController builds a same-client instructor/student session where the instructor controls playback and the student mirrors the camera and sees annotations; AddAnnotationStroke accepts freehand strokes only while paused for instruction, only from the instructor, and only with ≥2 points (clamping width to 1–24 and defaulting to yellow), and BuildTaggedMomentPlayback jumps the shared cursor to any tagged frame and gathers that frame's annotations.

Export & AI commentary#

UV4ReplayExportPipeline builds a Movie Render Queue job whose ValidateExportJob rejects anything that is not .mp4, lacks an MRQ preset, or exceeds 4K (3840×2160). The AI-commentary pipeline is the labeled seam: V4MomentScore ranks markers (objective/capture 100, clutch 95, save/parry 85, kill/combo 75), BuildAutoCutHighlightReel cuts the top five into 4-second-pre / 6-second-post windows, and BuildMistakeCallouts / BuildWhatWentWellReel classify coaching moments — all real algorithms — before handing a grounded script to a Calliope persona and a Psyche voice request, each gated by a consent policy that requires opt-in, friend consent, revocation checks, watermarking, and provenance, with minor accounts blocked outright.

Spectator & broadcast#

V4Mode_Spectator is the in-engine broadcast toolkit; the public web portal is a real Next.js app at apps/v4/spectator/. UV4SpectatorPolicyService::BuildReadOnlyPolicy makes a spectator read-only with gameplay input blocked and a 30-second default broadcast delay, and CanIssueGameplayCommand returns false for any read-only session — the integrity seam. UV4BroadcastCameraDirector ships five camera rigs (player-follow, free-fly, tactical-map, objective, cinematic-rail) plus observer presets and a PiP layout. The esports overlay service validates sponsor lower-thirds (must be approved, 0–15-second display) and builds a telemetry HUD that sorts critical metrics first. UV4LiveAICommentaryBroadcastService carries ten host personas — a play-by-play and a color analyst per cell — across twelve launch VO languages, and gates every line behind a bias-review policy that blocks unreviewed broadcast and forbids inferring player gender, region, or playstyle traits. The tournament toolkit forces pause-on-disconnect (90-second resume countdown), forces replay export at match end, caps observers at 8, and rejects any unlisted workshop mod; a live-replay rewind buffer lets a producer seek back inside a bounded window.

Signature modes#

Each cell carries one evergreen "premium identity" mode, registered in V4/modes/signature-modes.json and loaded/validated by the live-service subsystem's BuildSignatureEventModes / ValidateSignatureEventModes. Each entry binds a signatureModeId to a baseModeId, a cell, a stand-in asset, and a requiredFeatures list:

Signature mode Cell Required features (sample)
Raven Shield Anniversary Tactical Original2003MissionFlow, ModernPlanningUI
CoD-Zombies-class Horde Tactical WaveDefense, PerkMachines, EasterEggQuest
Black-List Spec-Ops Stealth CoopStealthMissions, GhostPantherRatings
Hitman Elusive Targets Stealth WeeklyOneShotContracts, NoRetry
Commandos Lost Patrols Tactics AlternativeHistoryMissions
Desperados Bounty Hunt Tactics RandomizedBounties, OpenFrontier
Wukong Mirror Veneration ARPG BossRush, RotatingModifiers
StarCraft Co-op Commander RTS ThreeCommanderHeroUnits
AoE Empire of Empires RTS PopCap1200, TwoHourMatches
Contra Survival Arcade EndlessRunAndGun, EscalatingBulletPatterns

The manifest and its validator are real; the per-mode content is stand-in — with one exception. The CoD-Zombies-class Horde mode has a real, compiled pacing engine in V4Mode_HordeDefense. UV4HordeVariantCatalog authors six launch variants — one per cell, from "Tactical Last Stand" to the evade-only "Shadow Evade" to the 2D "Contra Barrage" — and ValidateLaunchContent fails unless exactly six variants exist and all six cells and variant kinds are covered. UV4HordeWavePacingDirector::BuildWavePlan is genuine difficulty math: spawn rate scales by a wave scalar (1 + 0.12 × (wave−1)), a player scalar (1 + 0.18 × (players−1)), a clamped performance pressure (0.75–1.35), and a variant scalar (tower-defense pushes spawns to 1.20×, side-scroll to 1.35×), with elite counts and objective-pressure derived per wave. A post-launch cross-cell variant even lets a tactical-FPS player defend an RTST-cell base.

The AI Director#

UV4AIDirectorSubsystem is the session-level pacing brain, and it is fully real C++. Its defaults are honest about scope: PvE-only, achievement-neutral (bAffectsAchievements = false), purist opt-out disables it entirely, target pressure 0.55, deadband 0.08, 30-second minimum step interval.

ComputePressure scores a 90-second performance window with a real weighted blend — 0.42 × damage-taken + 0.25 × death-pressure (deaths ÷ 3) + 0.20 × detection-pressure (events ÷ 5) + 0.13 × inverted objective-progress — into a single 0–1 value. ResolveDifficultyStep then moves at most one step per evaluation and only outside the deadband: a struggling player (high pressure) steps the fight down, a dominant player (low pressure) steps it up. Each cell clamps inside a published band so the Director can never trivialize or brick a fight:

Cell Tunables (floor … ceiling)
Tactical FPS aim ±15% (0.85–1.15), reaction 280–520 ms, grenades ±25%
RTST patrol density ±15%, vision-cone half-angle 45°–65°
Wukong boss damage ±20%, parry window never below the 6-frame floor
RTS (campaign only) AI economy/attack-wave/scout scalars, never PvP
Contra enemy-spawn ±20%, bullet-pattern ±15%

Two guarantees make this more than a tuning table. The Director freezes during scripted boss phases so authored encounters read as designed, and — the V2 upgrade — a static_assert(V4AIDirectorPvPHooksCompileDisabled(), ...) over a hook-compile-policy table makes it a compile-time error for Director hooks to be enabled in any PvP mode. The post-launch refinement path (EvaluateDirectorWithRefinement) calibrates against launch-window skill and parry-success percentiles, keeps the chapter-2 boss clear rate inside a 35–55% five-attempt target, and rejects any adjustment that would read as rubber-banding (too large a delta, or too soon after the last one), returning a fixed tuning with bRejectedBySafetyProfile = true.

flowchart TD W[Performance window: damage, deaths, detection, objective] --> P[ComputePressure 0..1] P --> Gate{ShouldUseFixedDifficulty?} Gate -->|PvP / opt-out / scripted boss| Fixed[Fixed launch tuning, no change] Gate -->|PvE adaptive| Step[ResolveDifficultyStep vs target 0.55 +/- deadband 0.08] Step --> Apply[V4ApplyCellStep: clamp to per-cell band] Apply --> RB{Perceptible rubber-banding?} RB -->|yes| Reject[Revert to fixed, bRejectedBySafetyProfile] RB -->|no| Eval[FV4AIDirectorEvaluation: pressure, step, tuning] Compile[[static_assert: PvP hooks compile-disabled]] -.guards.-> Gate

ValidateLaunchCoverage and ValidatePostLaunchRefinement then assert the whole contract — adaptive on in PvE for every cell, the Wukong floor respected, RTS bonuses never applying to PvP, the opt-out and rubber-band rejections firing — and the 38-assertion spec exercises each path with dominant and struggling windows.