# UI / HUD, VR / AR & Accessibility

V2's interface layer is the everything-the-player-touches surface: front-end
menus, the in-match HUD, the settings tree, and the accessibility and VR/AR
support that sit on top of them. It serves every player — but it is engineered
first for the ones who need it most, because console accessibility is
cert-critical (Sony, Microsoft, and Nintendo each gate shipping on a
required-feature list). What makes V2's interface unusual is _how_ it is built:
not as a pile of opaque Blueprint widgets, but as **plain-C++ value types that
validate themselves**, paired with JSON contracts and Python gates. The
canonical example is `FV2UIAccessibilitySettings`
(`V2/ue/Source/V2UI/Public/V2UITypes.h:9135`), an eleven-field struct with a
`Normalize()` method and an `IsValidSettings()` self-check that every HUD widget
and accessibility subsystem reads from. The whole `V2UI` module is 85
implementation files (`V2/ue/Source/V2UI/Private/*.cpp`), and a single
3,894-line automation test, `V2.UI.Module` (`FV2UIModuleSpec` in
`V2/ue/Source/V2Tests/Automation/UI.Module.spec.cpp`), exercises them with
roughly 1,500 `TestTrue`/`TestEqual` assertions — HUD-scale clamping,
camera-shake normalization, reduced-motion variants, the screen-reader profile,
colour-blind palettes, and caption configuration all run headless, with no live
match.

Why this shape? Because a HUD that binds directly to the Ability System
Component cannot be tested without spinning up a match, and an accessibility
claim that cannot be proven offline cannot be presented to a platform cert
reviewer. By moving the _decisions_ (what colour, what scale, how much shake)
into deterministic structs and the _enforcement_ into validators and gates, V2
makes presentation provable and — crucially — keeps every accommodation on the
correct side of the rollback boundary. This page is a companion to the
architecture catalogue; the hub is
[../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md).

## What ships, honestly

**Real and tested.** The accessibility subsystems are genuine C++ with
domain-specific algorithms and constants, each with a `BuildDefault*` factory, a
self-validating profile, and assertions in the module spec: the colour-blind
palette (`V2ColorblindSafePalette.cpp`, 17 indicator roles × 5 modes), the
photosensitivity filter (`V2PhotosensitivityFilter.cpp`, a 3-flash-per-second
cap), visual sound indicators (`V2VisualSoundIndicators.cpp`, directional
off-screen cues with real screen-edge projection), the camera-shake intensity
slider (`V2CameraShakeIntensitySlider.cpp`), the screen-reader bridge
(`V2ScreenReaderBridge.cpp`), reduced motion, high contrast, font options,
subtitle rendering, and more. The TypeScript services `@v2/iris-accessibility`
and `@v2/psyche-caption-streaming`
(`apps/v2/{iris-accessibility,psyche-caption-streaming}/src/`) are real and
compose the shared `@iris/accessibility` and `@psyche/caption-streaming`
libraries. VR/AR ships as a validated **data + contract** layer
(`V2/balance/data/vr-ar-support.json` plus
`V2/ue/Content/V2/UI/VRARSupport_V2_Contract.json`) with a CI gate. A family of
**61 Python checkers** (`V2/ue/Tools/check-v2-*` covering accessibility, HUD,
caption, VR, colour-blind, photosensitivity, …) gate these surfaces in CI.

**Spec-only / aspirational.** The architecture monolith describes a CommonUI 5.5
activation tree under `Content/UI/FrontEnd/` with `W_HUD_Base`, `W_Settings_*`
panels, an `IRulesetHUD`/`IModeHUD` injection interface, and `.uplugin`
`HUDInjections`. **Those binary UMG assets do not exist in the tree.** What
ships under `V2/ue/Content/V2/UI/` is JSON _contracts_ (for example
`RulesetHUDOverlay_V2_Contract.json`,
`HUDAccessibilityPresentation_V2_Contract.json`), and the per-ruleset HUD is
realised as the spec-driven C++ class `UV2RulesetHUDOverlayWidget`, not a
literal `UInterface`. Treat the front-end `.uasset` activation tree, the HUD
render budgets (≤0.6 ms/frame), and the named linters
`check-widget-tree-depth.py` / `check-a11y-coverage.py` (neither is present) as
design intent. The monolith's `Source/V2Peripherals/` module does not exist
either — peripheral/adaptive-controller logic lives in `V2Input` and
`V2/balance/data/hardware-peripherals.json`.

**Provider / platform-gated.** Live OS screen-reader announcement (NVDA, JAWS,
VoiceOver, TalkBack) is reached through a real, validated _tree-export model_,
but the actual OS-runtime hookup is the integration seam. Per-platform VR
rendering paths (PSVR2 foveation/eye-tracking, Quest async-timewarp, Vision Pro
passthrough) are described in data and depend on platform SDKs not present in
this tree. Platform accessibility certification and VR comfort review are
external sign-offs.

## The settings model: one struct, normalized, validated

Everything downstream reads `FV2UIAccessibilitySettings`. Its fields and bounds
are the contract:

| Field                         | Type                    | Range / default                                              |
| ----------------------------- | ----------------------- | ------------------------------------------------------------ |
| `HUDScalePercent`             | int32                   | 75–150, default 100                                          |
| `HUDOpacity`                  | float                   | 0.0–1.0, default 1.0                                         |
| `bReducedMotion`              | bool                    | default false                                                |
| `CameraShakeIntensityPercent` | int32                   | 0–100, default 100                                           |
| `bScreenReaderAnnouncements`  | bool                    | default true                                                 |
| `bLargeText` / `TextScale`    | bool / float            | TextScale 0.5–3.0                                            |
| `PaletteMode`                 | `EV2UIColorPaletteMode` | Default · Protanope · Deuteranope · Tritanope · Monochromacy |
| `ContrastMode`                | `EV2UIContrastMode`     | Standard · Medium · High                                     |
| `ReadableFontMode`            | `EV2UIReadableFontMode` | Default · AtkinsonHyperlegible · OpenDyslexic                |
| `LetterSpacingPercent`        | int32                   | 0–50                                                         |

`Normalize()` snaps every field into range, and the module spec proves it:
setting `HUDScalePercent = 153` and `CameraShakeIntensityPercent = 42` yields a
clamped `150` and a `40` that rounds to the nearest five
(`UI.Module.spec.cpp:3589–3603`), with `GetCameraShakeIntensityMultiplier()`
resolving to `0.40`. The three enums are exact: the palette modes line up
one-for-one with the colour-blind catalogue, and the readable-font modes name
the two bundled accessibility typefaces (Atkinson Hyperlegible, OpenDyslexic).
Two sibling configs extend the model — `FV2AccessibilityVisualConfig`
(`Accessibility.Visual.V2`, with `MaxFlashesPerSecond`, high-contrast HUD,
photosensitivity-limiter, and opponent/hit-zone outlining flags) and
`FV2AccessibilitySubtitleCaptionConfig` (`Accessibility.Captions.V2`, with sign-
language locales, caption cues, subtitle background opacity, and speaker tags).

The settings _screen_ that edits this lives in `V2SettingsScreen.cpp`. It is a
spec-validated category tree (`UV2SettingsScreen::ConfigureFromSettingsSpec`),
and its predicate methods are what the gates assert against:
`HasCameraShakeIntensitySlider()` checks the row is a 0–100/step-5/default-100
slider; `HasReducedMotionModeToggle()` checks the description literally mentions
"screen shake," "particle effects," and "camera transitions";
`HasFontAccessibilityOptions()` checks the readable-font choice exposes Default
/ AtkinsonHyperlegible / OpenDyslexic alongside a 0–50 letter-spacing slider;
and `HasOneHandedControls()` / `HasControlsRebind()` cover motor remapping.
Privacy rows require confirmation (`HasPrivacySafeguards()`), and locale
selection covers OS-auto-detect plus an explicit text/voice language split.

## The determinism boundary — the load-bearing idea

The single most important architectural rule here: **accessibility
accommodations are presentation-only and must never alter the deterministic
simulation.** V2 is a rollback-netcode fighting game (see
[./rollback-netcode-and-tag-team.md](./rollback-netcode-and-tag-team.md) and
[./combat-system-gas-frame-data-and-determinism.md](./combat-system-gas-frame-data-and-determinism.md)),
so a visual setting that changed even one frame of hit-stop would desync a
match. The code enforces the wall explicitly.

```mermaid
flowchart TD
    Player[Player setting] --> Norm[FV2UIAccessibilitySettings::Normalize]
    Norm --> Shake[CameraShake resolution<br/>scale, never amplify]
    Norm --> Reduced[ReducedMotion state]
    Norm --> Palette[Colorblind palette resolve]
    Norm --> Photo[Photosensitivity filter ≤3 fps]
    Norm --> Caption[Caption session plan]
    Shake --> Present[Presentation / HUD render]
    Reduced --> Present
    Palette --> Present
    Photo --> Present
    Caption --> Present
    Sim[GAS + rollback simulation<br/>frame data, hit-stop] -. authored intensity only .-> Shake
    Present -. NEVER writes .-> Sim
```

The camera-shake slider is the clearest proof. `ResolveShakeIntensity()` takes a
normalized settings struct, an _authored_ intensity, and a source (`CombatHit`,
`EnvironmentalImpact`, `VehicleImpact`, `Cinematic`, `UIImpact`), and returns
`ResolvedIntensity = AuthoredIntensity × multiplier`. The validator
`FV2CameraShakeIntensityResolution::IsValidResolution()` then refuses any result
where `ResolvedIntensity > AuthoredIntensity` (it may only attenuate, never
amplify), where `0%` fails to fully disable shake, or where the resolution is
not `bGameplayDeterministic` and `bDoesNotAlterFrameData`. The profile's
`bDoesNotAffectHitStopFrameData` flag feeds those booleans, so the type system
records that the slider scales the _camera_ but leaves hit-stop frame data
untouched. The slider is also marked `bTournamentSafe`.

The same principle governs `EV2AccessibilityRankedEligibility` (RankedAllowed /
RankedDisabled). Visual-only accommodations — reduced motion, camera shake,
colour-blind palette, high contrast — do **not** flip ranked eligibility. Motor
_assist macros_ that change gameplay outcomes (auto-combo, motion-shortcut,
parry-window-extend, block-assist) **do** flip it, routing the player into
assist-eligible queues. The interface layer therefore carries the policy that
separates "I changed how the game looks" from "I changed how the game plays."

## In-match HUD and per-ruleset injection

The HUD base class is `UV2HUDWidget` (declared in `V2ActivatableScreen.h`);
every overlay derives from it. Per-ruleset meters are injected through
`UV2RulesetHUDOverlayWidget::ConfigureFromRulesetHUDOverlaySpec()`, which takes
a `FV2RulesetHUDOverlaySpec` keyed by `EV2ShaktiRulesetId` (the Shakti
fighting-ruleset identity — see
[./combat-system-gas-frame-data-and-determinism.md](./combat-system-gas-frame-data-and-determinism.md))
and a list of `FV2RulesetHUDMeterSpec`/`EV2RulesetHUDMeterKind` entries. The
widget exposes `HasMeterKind()`, `IsReducedMotionSafe()`, and
`IsSpectatorSafe()` — the last two are how a ruleset overlay proves it honours
the reduced-motion accommodation and is safe to show in spectator/broadcast
contexts. The module spec asserts `RulesetHUDWidget->IsReducedMotionSafe()`
directly (`UI.Module.spec.cpp:646`).

A worked example is the MMA/UFC body-damage overlay.
`UV2MMABodyDamageIndicatorOverlay` (a `UV2HUDWidget`) is configured from
`FV2MMABodyDamageIndicatorSpec`; on a valid spec it calls
`ConfigureFromHUDEntry(OverlaySpec.ToHUDWidgetEntry())` and then surfaces
`GetVisualZoneTag()`, `GetVisualIntensity()`, `IsLimbBruisingVisible()`, and
`IsBodyRednessVisible()`. The overlay refuses to configure from an invalid spec
(`ConfigureFromOverlaySpec` returns false and resets), which is the fail-loud
pattern repeated across the module — a HUD widget either holds a validated spec
or holds nothing.

HUD scaling and reduced motion flow through `UV2UISubsystem` (the LocalPlayer
subsystem): `SetHUDScalePercent(70)` clamps to `75`,
`SetHUDReducedMotionEnabled(true)` returns a presentation with
`bReducedMotionVariantActive`, and `SetHUDHighContrastEnabled(false)` toggles
the high-contrast theme (`UI.Module.spec.cpp:3442–3516`). The HUD-scale slider
is documented as 75–150 % in 5 % steps with an 18 px @ 1080p
minimum-readable-size floor; the clamping is real and tested, while the
design-time min-readable linter named in the monolith is not a shipped file.

## Visual accessibility

**Colour-blind-safe palette.** `FV2ColorblindSafePalette::BuildDefaultCatalog()`
ships 17 indicator roles — Health, Guard, Stamina, Super, Warning, Danger,
Success, Objective, QuestPrimary, QuestOptional, Interact, Focus, three Ping
qualities, TeamAlly, TeamEnemy — and each role carries **five** mode-specific
colours (Default plus four vision types) _and_ a non-colour
`NonColorShapeTokenId` and `TextFallbackTokenId`. Validation is strict: every
colour is finite/normalized RGBA, the catalogue must declare
`bNoColorOnlyState`, every entry must meet a `MinimumContrastRatio` ≥ **4.5:1**
(WCAG AA), and `ProvidesModeSpecificAlternatives` rejects any entry whose
protan/deutan/tritan/achromatic colour merely repeats the default. The actual
RGB values are the recognised Wong colour-blind-safe set (the `0.00, 0.45, 0.70`
blue and `0.90, 0.62, 0.00` orange recur deliberately across roles). Because
each role also has a shape and a text token, no V2 state is ever encoded by
colour alone — the architecture's "widgets pull semantic colour, never raw hex"
rule made structural.

**Photosensitivity filter.** `FV2PhotosensitivityFilter` enforces a hard cap of
**3 flashes per second** — the three-flash threshold from WCAG 2.3.1 / the
Harding test — with per-target rules for RapidFlashing, StrobeEffects,
HighContrastFlicker, LightningVFX, and the KO X-Ray. Each rule derives
`MinFlashIntervalSeconds = 1 / MaxFlashesPerSecond` and is rejected if it
exceeds 3 fps or drops below a 0.33 s interval. `ApplyFilter()` clamps an
authored flash rate down to the cap and scales luminance/contrast deltas by
per-target factors (e.g. strobe luminance × 0.25); the profile's own validator
runs a self-test that an authored **12 fps** strobe is filtered to ≤3 fps. The
filter `bAppliesBeforePostProcess` and `bRequiresContentReviewTag`, and stays
`bGameplayDeterministic`.

**Reduced motion, high contrast, fonts, text scaling.** Each is a real subsystem
with the same profile pattern: `V2ReducedMotionMode.cpp`
(`Accessibility.ReducedMotionMode.V2`, required-target coverage),
`V2HighContrastMode.cpp` (459 lines), `V2FontAccessibilityOptions.cpp` (438
lines, the Atkinson/OpenDyslexic + letter-spacing model), `V2TextScaling.cpp`,
`V2ScreenMagnification.cpp`, and `V2ColorblindSimulation.cpp` (a developer-side
simulation shader for authoring review). Reduced motion is a visual-only
accommodation: the architecture is explicit that enabling it does not disable
ranked play.

## Auditory accessibility

**Visual sound indicators.** `FV2VisualSoundIndicators` turns off-screen audio
into on-screen direction. Three cue types map to fixed shapes — Gunfire →
Chevron, Footstep → Footprint, EnvironmentalHazard → WarningDiamond — and the
geometry is real: `ProjectDirectionToScreenEdge()` normalizes a relative
direction, scales it to the safe-area edge (`0.5 − padding`), and clamps it into
the screen; `BuildRenderItem()` then sets rotation from `atan2`, scales the icon
with loudness and proximity (`0.75 + loudness·0.35 + (1−distanceRatio)·0.20`,
clamped 0.75–1.30), and fades opacity with distance. Every rule must set
`bWorksWhenAudioMuted`, `bNonColorShapeCoding`, a distance ring, and a threat
level; pulse rate is bounded 0.5–6 Hz and the profile shows at most 6
simultaneous indicators. This is the "audio cue → visual cue" promise made
concrete and deterministic.

**Caption streaming.** `buildV2PsycheCaptionStreamingSurface()`
(`apps/v2/psyche-caption-streaming/src/psyche-caption-streaming.ts`) plans a
real-time caption session over **five surfaces** — `in-match-hud`,
`spectator-overlay`, `replay-viewer`, `companion-second-screen`,
`broadcast-observer` — each with its own render target, position, alignment,
priority, and line cap (`SURFACE_RENDERING`). It builds one channel per (surface
× target language), capped at the underlying engine's `maxChannels`, registers
speakers for attribution, and emits a `V2PsycheCaptionSessionPlan`. The
netcode-safety guarantees are explicit fields: `offRollback: true`,
`mayInfluenceRollback: false`, and `deterministicImpact: 'none'` with the policy
string `off-rollback-caption-ui-only` — captions read presentation state and
never the deterministic input stream. Validation is fail-loud rather than
silent: `buildReasonCodes()` returns a non-empty list (which the cert gate
treats as a block) when `matchId` is missing, no target language is supplied,
accessibility mode is disabled, the in-match-HUD surface is absent, or no
speaker is rostered.

```mermaid
flowchart LR
    Match[Match audio + speakers] --> Plan[buildV2PsycheCaptionStreamingSurface]
    Plan --> HUD[in-match-hud]
    Plan --> Spec[spectator-overlay]
    Plan --> Replay[replay-viewer transcript]
    Plan --> Comp[companion-second-screen]
    Plan --> Bcast[broadcast-observer]
    Plan -. offRollback · deterministicImpact none .-> Safe[(no gameplay input)]
```

`@v2/psyche-caption-streaming` composes the shared `@psyche/caption-streaming`
runtime (`libs/psyche/caption-streaming`); audio-event duplication for
hearing-impaired play is handled in `V2AudioFeedbackDuplication.cpp`, and the
closed-caption authoring workflow in `V2ClosedCaptionAuthoringTool.cpp`.

## Screen-reader bridge and the Iris service

`FV2ScreenReaderBridge::BuildDefaultTree()` builds an exportable accessibility
tree (`Accessibility.ScreenReaderBridge.V2`): a root Window node, a MainMenu
list with Play and "Accessibility settings" buttons, a QuestTracker list whose
active objective is a live region, a Notifications live region, and help text.
Nodes carry stable ids, roles, labels, hints, focus order, and action metadata,
and the validator enforces structural integrity — a root must be a `Window`,
every non-root node must reference a registered parent, and the tree must cover
the required roles (Window, Button, Text, List, ListItem, LiveRegion). Platform
bindings are declared for **three** targets: `UIAutomation` (the Windows API
NVDA and JAWS consume), `NSAccessibility` (macOS/iOS VoiceOver), and `TalkBack`
(Android). It also converts quest objectives into nodes
(`BuildNodeFromQuestDescriptor`) so the open-world quest UI is screen-reader
addressable (see
[./open-world-coop-and-special-modes.md](./open-world-coop-and-special-modes.md)).
This is an honest model-and-binding layer: the tree, roles, and focus order are
real and validated; the actual OS-runtime announcement is the platform seam the
bindings target.

The TypeScript service `@v2/iris-accessibility`
(`buildV2IrisAccessibilitySurface`) is the cross-client owner. It composes
`@iris/accessibility` (dyslexia-friendly typography, cognitive-load reduction,
screen-reader bridge, native-UE hooks) and the caption engine from
`@psyche/caption-streaming`, and returns a surface that declares
`controlsScreenReaderBridge`, `controlsDyslexiaCognitiveAssistiveUi`,
`companionAndMainClientBridge`, `nativeUeAccessibilityHooks`,
`certGateBlocksRelease: true`, and `mayInfluenceRollback: false`. Its event
topics include `v2.accessibility.cert-gate.failed` — accessibility failures are
first-class events, and the cert gate is wired to block release. Both services
re-export through
`apps/v2/{iris-accessibility,psyche-caption-streaming}/src/index.ts`.

## VR / AR

VR/AR ships as a validated catalogue, not a runtime module — there is no `V2VR`
C++ module in `V2/ue/Source`. The source of truth is
`V2/balance/data/vr-ar-support.json` (schema `v2.ui.vr-ar-support-data.v1`),
mirrored by `V2/ue/Content/V2/UI/VRARSupport_V2_Contract.json` and validated by
`V2/ue/Tools/check-v2-vr-ar-support.py` (plus `check-v2-vr-camera-rig.py`). The
data describes:

- **Platforms.** PSVR2 (4K-per-eye, 120 Hz, foveated rendering, eye tracking,
  DualSense Edge), Meta Quest 3 (native VR, hand tracking, per-frame
  async-timewarp, cross-buy with PC), Apple Vision Pro (mixed reality,
  passthrough, gaze-and-pinch, spatial Atmos audio), and PC VR (SteamVR / Oculus
  Rift S / Windows MR with per-platform render scale).
- **Comfort.** Three comfort levels, turning vignette, snap-turn, per-player
  comfort selection, minimal HUD, virtual gauge glances, and physical 3D UI
  objects — the VR analogue of the flat HUD.
- **Mixed reality.** Vehicles that drive on the real-world floor, fighting in a
  real room, an AR spectator companion that can track a friend's match on a TV
  or phone screen.
- **Cross-play.** Non-ranked opt-in VR-vs-non-VR, with ranked separating VR
  pools (the input-fairness rule that also governs wheel-vs-gamepad — see
  [./online-backbone-and-competitive-integrity.md](./online-backbone-and-competitive-integrity.md)).
- **Certification.** Per-platform comfort review plus epilepsy and
  motion-sickness compliance for Sony VR TRC, the Meta Quest Store, and the
  Apple Vision Pro App Store.
- **VR accessibility.** Seated mode, a dedicated wheelchair-seated mode,
  one-controller mode, voice-activated menus, and customizable 3D-space subtitle
  positioning.

The ruleset-compatibility block marks racing and (toggleable) fighting as
VR-eligible with motion-sickness considerations and per-family camera modes,
which is how VR connects to
[./racing-and-vehicle-architecture.md](./racing-and-vehicle-architecture.md).
The gate cross-checks the contract, the balance data, an engineering doc, and
the CI workflow, and requires owner modules
`{V2UI, V2OnlineServices, V2Audio, V2Racing, V2Combat}` — so even though there
is no VR runtime in this tree, the support matrix is enforced rather than
asserted.

## Testing and gates

Two layers verify the interface. The UE automation test `V2.UI.Module` runs
headless in the editor context and asserts behaviour, not existence — scale
clamping resolves to specific integers, camera-shake `42 → 40` with multiplier
`0.40`, reduced-motion produces an active variant, the HUD accessibility profile
binds the screen-reader tree id `Accessibility.ScreenReaderBridge.V2` and the
`HUD.Theme.HighContrast` theme, and the caption/subtitle config validates across
subtitles, closed captions, sign language, audio description, and opacity. The
second layer is the 61-strong `check-v2-*` Python gate family (e.g.
`check-v2-colorblind-safe-palette.py`, `check-v2-photosensitivity-filter.py`,
`check-v2-psyche-caption-streaming.py`, `check-v2-iris-accessibility.py`,
`check-v2-vr-ar-support.py`), which cross-reference the C++ owners, the JSON
contracts, the balance data, and the docs. For how these gates fold into the
release pipeline, see
[./telemetry-performance-testing-and-release-gates.md](./telemetry-performance-testing-and-release-gates.md);
for the cert-blocking compliance view, see
[./security-compliance-and-sister-monorepo-integration.md](./security-compliance-and-sister-monorepo-integration.md).

## Related

- [./v2-product-promise.md](./v2-product-promise.md) — what V2 promises players,
  and where accessibility sits in that promise
- [./glossary-and-module-topology.md](./glossary-and-module-topology.md) — the
  `V2UI` module among the rest of the engine 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) —
  the deterministic simulation the interface layer must never disturb
- [./animation-and-input-pipeline.md](./animation-and-input-pipeline.md) — input
  rebinding, adaptive controllers, and the IMC the input-diagram overlay reads
- [./game-modes-training-and-replay.md](./game-modes-training-and-replay.md) and
  [./presentation-av-and-signature-content.md](./presentation-av-and-signature-content.md)
  — tutorial overlays, replay/spectator captions, and signature presentation
- [./racing-and-vehicle-architecture.md](./racing-and-vehicle-architecture.md)
  and
  [./open-world-coop-and-special-modes.md](./open-world-coop-and-special-modes.md)
  — VR-eligible rulesets and the quest UI the screen-reader bridge addresses
- [./online-backbone-and-competitive-integrity.md](./online-backbone-and-competitive-integrity.md)
  — VR/assist pool separation and ranked eligibility
- [./esports-companion-and-ai-services.md](./esports-companion-and-ai-services.md),
  [./live-ops-store-progression-and-community.md](./live-ops-store-progression-and-community.md),
  and
  [./build-cook-assets-data-and-production.md](./build-cook-assets-data-and-production.md)
  — companion-app captions, the notification centre, and how UI contracts are
  cooked
- [./telemetry-performance-testing-and-release-gates.md](./telemetry-performance-testing-and-release-gates.md)
  and
  [./security-compliance-and-sister-monorepo-integration.md](./security-compliance-and-sister-monorepo-integration.md)
  — the gate family and accessibility certification
- The section hub: [../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md)
