Accessibility, localization, account policy, and certification are inputs to the build and rollout—not documentation added after gameplay is complete. Each supported platform and locale earns its applicable evidence.
A fighting game ships in front of three audiences a marketing page never
mentions: the platform cert reviewer who can refuse to publish, the regulator
who can fine, and the parent who controls the account. V2 treats all three as
first-class engineering, not paperwork bolted on at the end. This page covers
the cluster that makes V2 shippable and lawful in every territory it launches
in — the parental-controls / age-gating / time-played feature set, the
accessibility surface, the localization, voice-over, and region-rating
pipeline, and the production / platform-compliance layer that wraps them.
The unusual thing about V2's implementation, as everywhere in this codebase, is
how much of it is real, validated Unreal C++ and TypeScript rather than a
policy PDF: parental controls are a self-validating USTRUCT feature set with a
contract spec, the 22-locale launch catalogue is built in code, the eight region
SKUs are real data assets asserted at boot, and the compliance obligations that
are genuinely policy (the rating-board matrix, the cert checklists) compose
shared Oshun / Aphrodite / Themis services rather than being re-invented. Where
a piece is a documented obligation or a provider-gated seam, this page says so
in code. The section hub is ../V2_features.md.
What ships, honestly#
The boundary between "shipped and tested" and "documented obligation" runs cleanly through this cluster.
- Parental controls are a validated C++ feature set.
FV2ParentalControlsFeatureSet(V2OnlineServicesTypes.h:10619) bundles five sub-configs — age-gate policy, parental dashboard, time-played reports, spending limits, legal disclosures — each with its ownIsValidConfig, built byBuildDefaultParentalControlsFeatureSet()(V2OnlineServicesBlueprintLibrary.cpp:10068) and pinned by the specV2.Online.ParentalControls.AssetContract(§68), which asserts the negative case: removing theUS.COPPAprofile fails validation. - Localization is real C++ data, not just strings.
FV2LocalizationVoiceOverFeatureSetenumerates 22 launch-locale configs (BuildDefaultLocalizationVoiceOverFeatureSet,V2UIConfigAsset.cpp:4868) and is validated in theV2.UI.Modulespec. TheV2/loc/workspace directory the repository surfaces table lists is planned — not yet created; the canonical localization data lives in C++ plus theContent/Localization/V2/contract layer. - Region rating variants are real data assets, asserted at boot. Eight
DA_RegionVariant_*.uassetfiles exist underV2/ue/Content/V2/Regions/, andUV2RegionVariantBootSubsystem::EvaluateBootAssert()refuses a build whose staged SKU stamp does not match the loaded variant (§54.2). - Accessibility is a first-class, tested surface — covered in depth by the architecture companion ../architecture/ui-hud-vr-ar-and-accessibility.md; this page summarizes its player-facing shape and the one rule that governs it.
- The compliance seams are coded; the obligations are documented. Age
verification, consent, and PII handling compose
@aphrodite/*,@themis/*, and@oshun/*through thinapps/v2/surfaces; the rating-board matrix, the per-region SLAs, the DRM removal-plan window, and the platform TRC/XR/lotcheck checklists are cert obligations those seams satisfy. See ../architecture/security-compliance-and-sister-monorepo-integration.md.
Parental controls, age gating & time-played (§68)#
One feature set, five configs, one validator#
The whole parental surface hangs off FV2ParentalControlsFeatureSet, whose
IsValidFeatureSet() (V2OnlineServicesTypes.cpp:10601) requires a stable
FeatureSetId == "ParentalControls.V2" and then delegates to all five
sub-validators — a single failure anywhere fails the set. The build-default is
concrete data, not a flag soup, and the spec reads the runtime values back.
Age gating per region law#
FV2AgeGatePolicyConfig (:10438) carries a RegionProfiles array and a
HasRequiredRegionProfiles() check that demands all five legal regimes be
present — US.COPPA, EU.GDPRK, KR.GameRatingBoard, CN.MinorStandardSku,
and AU.NZ.RatingAck. The booleans encode the source's region rules exactly:
bBootTimeAgeConfirmation (the gate runs at boot),
bPlatformAccountAgePassThrough (it trusts the platform account's age first),
bCoppaUnder13NoChatUgcMatchmakingWithoutConsent,
bGdprKUnder16PerMemberState,
bKoreaMinorOvernightPlayBlockedWithoutParentApproval,
bChinaMinorStandardSkuOnly, bChinaIdentityVerificationRequired, and
bAustraliaNzRatingAckScreens. The China minor daily limit is a hard integer:
ChinaMinorDailyPlayLimitMinutes = 60, and the validator rejects any value
other than 60, so the one-hour cap can never silently drift. The spec asserts
each of these and then proves the failure path by removing US.COPPA.
The runtime decision — what content a given account actually sees — is a
backend concern, and V2 does not hand-roll it. @v2/aphrodite-age-gate
(apps/v2/aphrodite-age-gate/src/) composes @aphrodite/age-verification
through buildV2AphroditeAgeGateSurface(): it controls gore tier, adult
fatalities, and region-conditional cinematics (controlsGoreTier,
controlsAdultFatalities, controlsRegionConditionalCinematics), uses the
mature-game age-gate profile and explicitly rejects the adult-content
profile (usesMatureGameAgeGateProfile, adultContentAgeGateProfileRejected),
keeps 2257 / performer-protection workflows out of game content gating, and
hands minor-account decisions to platform family controls
(parentalControlHandOffRequired). The Aphrodite brand is never shown to
players, it emits v2.age-gate.decision.created /
v2.content.gore-tier.changed topics, and it is mayInfluenceRollback: false —
a content gate, off the deterministic path. The CI gates
check-v2-aphrodite-age-gate.py and check-v2-age-gate-fitness-audit.py pin
it.
The parental dashboard#
FV2ParentalDashboardConfig (:10483) is the PIN-gated control surface. Two
coverage predicates make it real: HasRequiredPlatformIntegrations() requires
the four console family systems — SonyFamilyManagement,
MicrosoftFamilySafety, NintendoParentalControls, SteamFamilyView — and
HasRequiredChildControls() requires all nine toggles the source promises:
OnlinePlay, VoiceChat, TextChat, UgcVisibility, CustomContentDownload,
CosmeticShopSpendingLimit, DailyPlaytimeLimit, WeekendsOnlyMode, and
BedtimeAutoShutoff. On top of those, bParentPinGated,
bPerChildGoreTierMildOffOverride, and bPerChildFinisherDisableOverride let a
parent set per-child gore tier (the
EV2GoreTier { Off, Mild, Standard, Extreme } ladder from V2VFXTypes.h:22)
and disable finishers for one child without touching another's account.
check-v2-parental-controls.py gates the surface.
Time-played reports#
FV2TimePlayedReportConfig (:10511) is the wellness half. Its
PlaytimeNudgeAfterConsecutiveHours = 2 is the break-nudge threshold (the
validator rejects a non-positive value), and the booleans build the weekly
report: bWeeklyPerAccountEmail and bInGameDashboard are the two delivery
channels; bHoursPerMode, bHoursPerFighter, bPeakPlaytimeHour, and
bComparisonToPriorWeek are the breakdown; bParentVisibleForChildAccounts
exposes a child's report to the parent; and bOptionalBreakNudgePopup is the
in-session nudge. This is the same responsible-play posture that
@v2/lakshmi-responsible-play-spend-insight carries on the spend side.
Spending limits and legal disclosure#
FV2SpendingLimitConfig (:10549) sets real default caps on premium currency —
DefaultDailyPremiumCurrencyCapMinor = 1000, weekly 5000, monthly 15000,
plus a KoreaMinorDailyPremiumCurrencyCapMinor = 1000 — and the validator
enforces the ordering (daily ≤ weekly ≤ monthly, all positive), so a
misconfigured cascade fails the build. bParentSetPerChildLimits,
bPinGatedLimitChanges, bPerRegionMaximumLimits, and
bKoreanMinorAccountLimits cover the parent-set, PIN-gated, per-region, and
Korean-minor rules. FV2LegalDisclosureConfig (:10587) closes the loop with
the disclosures law requires of a real-money game that deliberately has no
loot boxes: bLootBoxAbsenceStatementInStoreListing and
bLootBoxAbsenceStatementInSettings (the explicit no-surprise-mechanics
statement), bInGamePurchasesLifetimeSummary and …Last30DaysSummary,
bPlatformRefundFlow, bHealthSafetyWarningScreen, and
bPhotosensitivityWarningBundled. Per-feature data consent — telemetry, voice
processing, behavioural profiling — is a separate seam,
@v2/aphrodite-consent-surfaces, which composes @aphrodite/consent-engine,
requires consent receipts when a feature is enabled, defaults missing opt-ins to
privacy-preserving fallbacks, and stays off rollback.
Accessibility#
Accessibility is the largest single surface in V2's interface layer, and it is
genuine C++ with WCAG-anchored constants — the colour-blind palette (17
indicator roles × 5 modes, ≥ 4.5:1 contrast), the photosensitivity filter (a
hard 3-flash/ second cap), visual sound indicators, the camera-shake slider, the
screen-reader bridge, reduced motion, high contrast, fonts, text scaling, and
caption streaming. Everything reads from one self-normalizing struct,
FV2UIAccessibilitySettings (V2UITypes.h:9135), and a 3,894-line
V2.UI.Module automation test plus a 61-strong check-v2-* Python gate family
verify the behaviour, not the existence. Because that whole stack is
documented end-to-end in the architecture companion
../architecture/ui-hud-vr-ar-and-accessibility.md,
this page states only the load-bearing rule and the service ownership.
The determinism boundary. Accessibility accommodations are
presentation-only and must never alter the deterministic simulation — V2 is a
rollback-netcode fighter, so a visual setting that changed one frame of hit-stop
would desync a match. The camera-shake slider may only attenuate authored
intensity, never amplify it, and is marked bTournamentSafe. The policy that
separates "I changed how the game looks" from "I changed how the game plays" is
EV2AccessibilityRankedEligibility: visual accommodations (reduced motion,
colour- blind palette, high contrast) keep ranked eligibility, while motor
assist macros that change outcomes (auto-combo, auto-block/parry/tech, easy
fatalities) flip a per-tier ranked flag and route the player into
assist-eligible queues — the same mechanism the combat and local-co-op pages
describe.
Service ownership. Two TypeScript surfaces own the cross-client and
companion side: @v2/iris-accessibility composes @iris/accessibility
(dyslexia typography, cognitive-load reduction, screen-reader semantics,
native-UE hooks) and declares certGateBlocksRelease: true with the event topic
v2.accessibility.cert-gate.failed — accessibility failure is a first-class,
release-blocking event. @v2/psyche-caption-streaming plans a real-time caption
session across five surfaces (in-match HUD, spectator overlay, replay viewer,
companion second-screen, broadcast observer) with offRollback: true. The
documented VPAT-style report lives at V2/docs/accessibility/. Live OS
screen-reader announcement (NVDA, JAWS, VoiceOver, TalkBack) is reached through
a real, validated tree-export model whose actual OS-runtime hookup is the
platform integration seam.
Localization, voice-over & region rating variants (§54.2)#
The launch-locale catalogue, in code#
V2's localization is not a .po file pile — it is a validated data structure.
BuildDefaultLocalizationVoiceOverFeatureSet() (V2UIConfigAsset.cpp:4868)
constructs 22 FV2LaunchLocaleConfig entries (V2UITypes.h:10237)
representing the source's 18 languages with regional variants split out: English
(US/GB), French (FR/CA), Spanish (ES/419), Portuguese (BR/PT), German, Italian,
Polish, Russian, Turkish, Arabic, Hebrew, Japanese, Korean, Chinese (Hans/Hant),
Thai, Vietnamese, and Indonesian. Each entry carries a ScriptId that selects a
real font-fallback chain — Script.CJK → Font.NotoSansCJK, Script.Arabic →
Font.NotoNaskhArabic, Script.Hebrew → Font.NotoSansHebrew, Latin → the
Atkinson/OpenDyslexic-led chain — so a missing glyph never renders as tofu. RTL
locales (Arabic, Hebrew) set bRtlLayout, bRtlUiMirroring, and
bRtlFocusNavigationMirroring together; calendar systems are per-locale
(Hijri, Hebrew, JapaneseEra, KoreanDangi, Buddhist); and the QA flags
(bStringLengthCapValidation, bTextExpansionQaGate, bCulturalReview,
bSubtitleTimingQa, bVoiceLineLipSyncQa) record the per-locale pipeline. The
V2.UI.Module spec asserts the set IsCompleteFeatureSet(), that the
externalized string root is V2/ue/Content/Localization/V2/, and that region
variants and the typography/formatting/workflow sub-configs all validate.
Voice-over plan#
FV2VoiceOverLocalizationPlan (V2UITypes.h:10317) splits the locales by VO
status. Nine locales ship per-fighter voice banks at launch
(LaunchVoiceOverLocaleIds: en-US, fr-FR, es-ES, pt-BR, de-DE, it-IT, ja-JP,
ko-KR, zh-Hans), guarded by MinimumLaunchVoiceOverLocaleCount = 8; the
remaining 13 are SubtitleOnlyPatchLocaleIds with
bRemainingLocalesSubtitleOnlyWithPatchPlan — the documented VO patch plan from
the source. bPerFighterVoiceBankAtLaunch, bIterationPickupProcess,
bPickupSessionDiffsTracked, and bLipSyncRetimingPerLocale model the
composition → recording → pickup → per-locale lip-sync pipeline, and per-fighter
banks hot-swap on patch. Spectator chat and commentary localization at runtime
is a separate, presentation-only service: @v2/iris-realtime-translation
composes @iris/voice to deliver translated chat, subtitles, and broadcast
overlays — never feeding rollback state.
Region rating variants and the boot assert#
Per-region content rules are stored as URV2_RegionVariant data assets — eight
real .uasset files under V2/ue/Content/V2/Regions/
(DA_RegionVariant_{US,EU,DE,JP,KR,AU,NZ,BR}.uasset) — described by
FV2RegionVariantRule (V2UITypes.h:10355): a VariantId, RegionId,
RatingBoardId, a BuildPipelineSkuTag, a ContentPolicy, and a
RequiredContentAdjustments list. Tools/stage-region-rating-config.py writes
the SKU stamp at cook time, and at boot
UV2RegionVariantBootSubsystem::EvaluateBootAssert()
(V2RegionVariantBootSubsystem.cpp:8) refuses to proceed unless the staged
region and SKU tag match the loaded variant — a German USK-18 build can never
boot wearing the global SKU. The spec V2.UI.RegionVariantBoot.AssetContract
pins the expectation table that mirrors V2/legal/rating-boards.json: DE
(SKU.DE.USK18.GoreRestricted, gore-restricted, fatalities substituted), JP
(SKU.JP.CEROZ, dismemberment reduced, X-Ray alternate), KR (SKU.KR.GRAC19,
chat filter, loot-box disclosure), AU/NZ (R18 rating-ack screens), and BR
(SKU.BR.DJCTQ18, Portuguese-BR VO). Editor/local builds carry no stamp and are
not asserted. A large JSON-contract layer under Content/Localization/V2/
(locale-fallback chain, RTL mirroring, CJK layout, plural forms, pseudo-loc,
continuous-localization CI, TTS fallback for missing VO) plus ~30 check-v2-*
localization gates back the spec.
Production & platform compliance#
The studio-production story — multi-studio org chart, mocap booking, SAG-AFTRA
compliance, VO casting, composer pipeline, IP/NIL/licensing — is a documented
obligation in the source, but its data plane is real services. The mocap
pipeline ships as @v2/aja-studio-mocap-pipeline (Vicon/markerless capture
path) and @v2/aja-markerless-capture-pipeline, and every capture clears
consent before ingest through @v2/aja-consent-nil-ledger, which wires Aja
capture consent to the Themis NIL ledger — a revocation blocks future processing
for dependent clips. LiveLink export to the engine runs through
@v2/aja-bellona-livelink-export. The rights manifest verified at cook (no
asset ships without cleared rights or original-IP status) and the
per-jurisdiction publicity-rights review are the policy obligations these seams
enforce.
Platform certification is where policy becomes a gate.
FV2PlatformComplianceChecklistPolicy (§72.21.1.14, built by
BuildDefaultPlatformComplianceChecklistPolicy() and pinned by
V2.Online.PlatformComplianceChecklist.AssetContract) requires coverage of
PlayStation TRC, Xbox XR, and Nintendo lotcheck, carries machine-
readable evidence records (bExportsMachineReadableStatus), and excludes
proprietary platform text (bExcludesProprietaryPlatformText) so the checklist
can live in a public repo without leaking NDA'd cert language. The rating-board
matrix (ESRB M, PEGI 18, CERO Z, USK 18, ACB R18+, GRAC, DJCTQ 18, OFLC R18)
lives in V2/legal/rating-boards.json, and check-rating-descriptors.py /
check-v2-region-rules.py gate it. The deeper compliance program —
GDPR/CCPA/DSA data-subject rights, PII strip-at-ingest, per-region residency,
the DRM removal- plan window — composes Oshun/Themis services and is detailed in
the security/ compliance architecture companion and the launch sibling page.
How it connects#
The through-line is the same one the rest of V2 follows: encode the decision
in a validated value type, encode the enforcement in a validator and a CI
gate, and compose shared platform services for anything that must resolve
consistently across every Oshun product. Parental controls, the locale
catalogue, and the compliance checklist are all self-validating C++ structs
pinned by contract specs that would fail on a stub; the region SKUs are real
data assets the engine asserts at boot; the age-gate, consent, accessibility,
translation, and mocap-consent surfaces are real TypeScript that compose
@aphrodite/*, @iris/*, @psyche/*, and @themis/* and stay off the
rollback path; and the genuinely-policy parts — the cert checklists, the rating
obligations, the studio org chart, the DRM window — are documented and audited
rather than fabricated as code. The section hub is
../V2_features.md.
Related#
- Racing Crossover, Open World & Ops — the racing component's parallel accessibility/auto-throttle assists and the live- ops surfaces this platform layer wraps
- Balance Ops, Privacy, Wellness & Launch — the telemetry/PII program, the responsible-play spend insight, the data-subject-rights UI, and the launch-readiness gate
- Online Services, Network & Tournaments
— the
V2OnlineServicesmodule the parental-controls and compliance-checklist feature sets live in - UI / HUD, VR / AR & Accessibility — the architecture companion for the full accessibility, settings, and VR/AR stack summarized here
- Security, Compliance & Sister-Monorepo Integration — identity, consent, residency, DSR, and the cert-blocking compliance posture
- The section hub: ../V2_features.md