V4 ships six tactical-action cells under one account, one operator roster, one
currency ledger, and one progression record, across nine day-one platforms — and
the moment any of that goes live it inherits three obligations that a tactical
shooter cannot wave off. A competitive ladder rots the day cheating goes
unanswered, so a Search & Destroy round, an RTS 1v1, and a contract
leaderboard run all have to be defended by the same evidence-gated anti-cheat.
A regulator fines, and a platform holder refuses the build, over a deletion
that fails to cascade or a data-safety form that is missing — so a
right-to-be- forgotten request has to reach every place a player's identifiers
landed, including the cloud replays other people are still watching. And a
minor must never be one toggle away from voice chat with a stranger, so the
age gate and the parental surface are computed defaults, not a recommended
setting. The defining choice this page documents is also the first thing to
state honestly: where V2 and V3 reach sideways into the sister monorepos and
compose the shared @themis, @kuanyin, and @aphrodite trust-safety
packages through thin surfaces, V4 reimplements the enforcement seams
natively — as Unreal C++ subsystems and Rust services that live exactly where
the gameplay does. This is the player-and-policy face of that decision; the
engine-internal companion is
../architecture/security-compliance-launch.md,
and the section hub is ../V4_features.md.
What ships, honestly#
The trust-safety and compliance logic is real, domain-specific code, not a policy stub dressed as a feature.
- The compliance brain is a substantive Unreal subsystem.
V4/ue/Source/V4OnlineServices/Private/V4ComplianceSubsystem.cpp(~490 lines) builds 30-day DSAR export cases and 45-day deletion cases, evaluates an under-13 / teen / adult age gate, resolves per-region data-residency rules, emits DSA statement-of-reasons logs, drives an eight-region feature-flag matrix, and self-validates throughValidatePrivacyByDesignCoverageandValidateLaunchCoverage. It is exercised byV4Tests/Private/V4ComplianceTests/ComplianceSpec.cpp. - Anti-cheat is computed, not asserted.
V4/ue/Source/V4Netcode/Private/V4AntiCheatSubsystem.cpp(187 lines) computes behavioral-detection thresholds, a 0–100 trust score, a ten-tier ban ladder, ladder-replay integrity validation, and an appeal validator, tested byV4AntiCheatTests/AntiCheatSpec.cpp. - Moderation and the replay scrubber are real Rust.
apps/v4/online-services/src/lib.rscarries aCaseService(report intake with mandatory clip evidence, the two-stage content scan, speech review, ban issuance, appeals) and a right-to-be-forgottenscrub_deleted_account_from_replaythat mutates pawn tracks and returns a typedReplayScrubResult. Both ride the Axum router insrc/http.rs, and the scrubber is backed by the 388-lineReplayModeSpec.cpp. - A machine-checked gate ties it together.
apps/v4/scripts/src/v4-privacy-by-design-check.mjsreads the C++ source, the Rust source, the legal JSON artifacts, the service manifest, and the docs/TODOs, and fails CI if any DPIA, jurisdiction note, region flag, or scrubber wiring is absent — so the prose on this page cannot drift from the code behind it.
Three honest qualifications. First, the divergence above is not a footnote:
the shared @themis/transparency, @kuanyin, and @aphrodite/* packages are
real and present in libs/, but V4 does not import them. V4 reimplements
identity-aware compliance, residency, age-gating, and anti-cheat in-engine on
purpose, and the only cross-monorepo touchpoints are boundary hooks, not
runtime dependencies — the Rust moderation service accepts a
lilith_rights_match / lilith_persona_policy_match input and cascades a
lilith_rights_takedown_cascade, and the sub-processor registry names
third-party processors (Perspective API, Whisper). Second, V4 owns no cooked
binary content; every Unreal asset is a text .v4asset.json stand-in, including
DA_ComplianceDeep and DA_ModerationPipeline, so "the kernel driver" and "the
shipped restricted build" are configured and validated here but not compiled in
this repository. Third, what is honestly policy rather than code is the
cert obligation set itself — the rating-board matrix, the regulatory SLAs (GDPR
30 days, CCPA 45), and the public portal URLs — the enforcement seams are coded,
the obligations are documented and audited.
Trust & safety#
Reports and sanctions in V4 are identical across all nine platforms — a slur or a snap-aim is not a platform-specific event — and every step from a report to a permanent ban is built to produce an auditable, appealable trail.
Cross-platform reporting and the evidence requirement#
A report is useless to a moderator without context, so V4 attaches it at the
source. CaseService::submit_player_report is fail-closed: it returns
false unless the PlayerReport carries a non-empty report id, reporter,
target, and reason and a GameplayClipEvidence that is actually attached,
has a non-empty cloud_uri, and a non-zero duration_seconds. You cannot file
a report on an empty record — the last segment of gameplay recording rides along
as evidence so a moderator has the moment without the reporter assembling it. A
report advances Submitted → Triaged → (Actioned | Dismissed), and the reporter
is told only that an outcome was reached, never the specific sanction, which is
the coded answer to retaliation and report-farming. Every action resolves to an
appeal at a stable, signed URL: CaseService::appeal_portal_url returns
https://support.v4.game/appeal?sanctionId={id}, and the appeal is reviewed
against the logged evidence by a different reviewer than the one who issued it.
Anti-cheat: layered, evidence-gated, never auto-permanent#
No single layer is trusted alone, and the design constraint that shapes all of
them is that automated detection never issues a permanent ban. The
kernel-mode client is configured by BuildDefaultEACConfig (Easy Anti-Cheat
across Windows, Linux, PS5, XSX, XSS) and ValidateEACConfig rejects any
platform that does not require kernel mode and protect both ranked PvP and
battle royale. Ladder integrity is checked by ValidateLadderReplay, which
refuses a replay that is not ladder-eligible, has zero duration, is missing any
of its three integrity hashes, or — tellingly — whose replay, server-state, and
input hashes are not independently produced (equal hashes are rejected as
forged).
Behavioral detection is a real classifier, not a coin flip. EvaluateBehavior
flags impossible recoil when a sample fired ≥ 20 shots at a recoil-control
score ≥ 0.98, and a wallhack pattern when hidden-target pre-aim count ≥ 3 or
wall-visibility ratio ≥ 0.35, then grades severity 9 (both), 7 (recoil),
or 6 (wallhack). RouteToAntiCheatService sends severity ≥ 8 to
anti-cheat.eac-review and everything else to anti-cheat.live-review —
review queues, not auto-bans. CalculateTrustScore computes
100 − strikes×25 − investigations×10 (clamped 0–100), pools any account below
50 into bLowTrustPool so suspected cheaters matchmake together while a case is
built, and a missing account id collapses straight to 0 / low-trust.
BuildBanTiers lays out the ten-step ladder — Mute (24h/7d/30d), Match ban
(1/7/30d), Cell ban (1/7/30d), and a permanent Account ban — and
ValidateAppeal gates every appeal on a present appeal/sanction/account id and
a statement of at least 24 characters. A permanent ban therefore requires replay
evidence plus telemetry plus manual review, by construction.
Speech moderation and the two-stage content gate#
Speech review composes two real sub-processors. CaseService::review_speech
routes text to Perspective scoring and voice (via a clip id + Whisper
transcript) separately, applies the Lilith persona policy on a match or a
literal slur in either channel, requires human review at a Perspective toxicity
or Whisper abuse score ≥ 70, and recommends an automatic mute at ≥ 90 — so
clear-cut cases mute without waiting on a queue while everything ambiguous
escalates to a person. User-generated content runs CaseService::scan_content,
a two-stage gate that blocks distribution at nudity ≥ 85 or violence ≥ 90,
queues human review at nudity ≥ 60 / violence ≥ 65 or any community report,
and — when a lilith_rights_match fires — appends
lilith_rights_takedown_cascade and queue_appeal. That cross-cell rights hook
is the same gate the community gallery and creator workshop submissions pass
through (detailed on
Content, Creator & Community).
Compliance#
Privacy and platform-regulation obligations are not a launch-week scramble; in
V4 they are computed and gated, and all compliance gates green is a launch
exit criterion verified by ValidateLaunchCoverage.
Age gate, parental controls, and the under-13 restricted build#
EvaluateAgeGate(BirthYear, CurrentYear, bGuardianVerified) is the spine of
youth safety. Under 13 it demands the COPPA family-link flow and, only with a
verified guardian, routes the account to a separate restricted build
(V4.Restricted.Under13) whose flags disable voice, text, UGC, and purchases.
Ages 13–17 resolve Teen; 18+ resolve Adult. The parental surface is
BuildDefaultParentalControlPolicy: a fixed set of per-day time-played caps
({15, 30, 60, 120, 240, 0} minutes, where 0 is "no cap"), a hard under-18
monthly spend ceiling, and — the load-bearing default — voice and text chat
off for under-18 accounts with bParentOptInRequired set, so a minor cannot
click into open comms. Because V4 ships no random-roll or gambling-adjacent
purchase mechanic in any region, the under-18 spend restriction is a tightening
of an already loot-box-free store, not a patch over one.
Data-subject rights, residency, and the replay scrubber#
BuildDsarExportCase mints a 30-day case that exports the account to a JSON
archive at https://support.v4.game/dsar; BuildDeletionCase mints a 45-day
Purge. Both are routed by ResolveDataResidencyRule, which maps a region to
its host and a paired KMS region — EU → eu-central-1 / eu-kms-v4, PRC →
cn-north-1 / prc-kms-v4, US → us-east-1 / us-kms-v4 — so account data is
encrypted and stored in-region. The hardest part of a deletion is the data a
deleted player left in other people's replays, and that is where the
right-to-be-forgotten replay scrubber earns its place.
scrub_deleted_account_from_replay walks a replay's participant pawns, clears
the matching account_id, swaps the visible skin to
Skin.Anonymous.DeletedAccount, marks each track removed, and — if the deleted
account owned the replay — clears the owner, unstars it, and resets retention
to the default 14-day cloud tier. Crucially it retains the match-integrity
frames, so playback stays valid for everyone else while the deleted player is
anonymized. It returns a typed ReplayScrubDecision (Scrubbed / NotFound /
NoAccountFootprint / InvalidRequest), and the same contract has a second
runtime in the Unreal replay plugin
(UV4ReplayCloudArchive::ScrubDeletedAccountFromReplay), detailed on
Modes: Training, Replay, Signature & AI Director.
Per-region flags, DSA reasons, sub-processors, and AI DPIAs#
BuildRegionFeatureFlagMatrix resolves an eight-region matrix in which China
defaults voice chat off and runs a cosmetic-only economy (disabling
VoiceChat.DefaultOn and Economy.RealMoneyAdvantage), while Korea and India
also resolve cosmetic-only and the remaining regions run the full economy —
ResolveRegionFeatureFlags normalizes aliases (DE/FR/ES → EU, GB → UK) so the
runtime default is never a guess. Every moderation action emits a DSA
statement-of-reasons via BuildStatementOfReasons, whose bLogged flag is true
only when actor, target, reason code, evidence id, and the statement text are
all present, and BuildTransparencyReport rolls those into a periodic public
count. BuildSubprocessorRegistryMaintenance encodes the registry's discipline:
refresh on ContractChange, contract review required, and opt-in subscribers in
eight regional topics notified within 30 days. Three AI features each carry a
published, annually refreshed DPIA summary card via BuildDpiaSummaryCards —
AI Auto-Moderation, Behavior Detection, and In-Game Commentary —
backed by V4/legal/dpia-summary-cards.json. The commentary DPIA is the most
careful: its mitigations include watermarking and, for opt-in personal
voice-clone commentary, a double-consent path (player plus friend likeness
consent) checked against a revocation ledger — a documented P3 commitment whose
supporting consent/likeness types live in the replay-mode runtime, not a
fabricated "done."
The privacy-by-design gate#
What keeps this section honest is v4-privacy-by-design-check.mjs. It cross-
checks the compliance asset against the legal JSON (subprocessors.json,
region-feature-flags.json, replay-scrubber-policy.json,
per-jurisdiction-compliance-notes.json — all 50 US states plus EU/UK/BR/JP/KR/
IN/CN), greps the C++ and Rust source for the required tokens
(ScrubDeletedAccountFromReplay, scrub_deleted_account_from_replay,
Skin.Anonymous.DeletedAccount, ValidatePrivacyByDesignCoverage), confirms
the service-manifest.json advertises the matching capabilities, and asserts
the docs and TODOs name them. In-engine, ValidateCompliancePolicyAsset and
ValidatePrivacyByDesignCoverage perform the same audit on live objects: 30-day
DSAR, 45-day delete, the under-13 restricted build, three DPIAs, three residency
rules, the China voice-off / cosmetic-only flags, and the anonymous- skin scrub
default. A compliance claim that is not backed by code does not pass CI, which
is precisely the bar this page is written to.
Where this connects#
- Sideways: Platforms, Operations & Hardware — per-platform certification (Sony TRC, Microsoft XR, Nintendo), the region rating variants, day-one patch, and the live-ops surfaces these gates protect.
- Sideways: Narrative, Extras & Launch — the launch exit criteria this compliance posture is one of, and the AI-commentary and creator extras the DPIAs cover.
- Sideways:
Content, Creator & Community (the
gallery and workshop the two-stage
scan_contentgate moderates) and Modes: Training, Replay, Signature & AI Director (the replay vault the scrubber mutates). - Down to the engine:
../architecture/security-compliance-launch.md
— the
UV4ComplianceSubsystem/UV4AntiCheatSubsysteminternals, the Rust service tier, the 616-line launch-readiness validator, and the honest record of why V4 reimplements the shared trust-safety plane rather than composing it. - The feature hub: ../V4_features.md.