# Racing Component, Vehicles & Peripherals

V2 is a fighting game that also ships a full racing genre, and the racing side
is not a bolt-on minigame — it is **seven Unreal C++ modules** that follow the
same "data plus a load plan" discipline as the rest of the project. A race mode
is an `FV2RaceModeDefinition` value (an id, a family, a ruleset, a network
model, a driver-count band, a synthesized Game Feature plugin URL, a map path,
and a set of HUD injections), a vehicle is a `UV2VehicleDataAsset` carrying an
engine / drivetrain / tire / suspension / damage / aero / performance bundle,
and the physics is an analytical per-frame solver that takes those structs and
returns a `FV2RacePhysicsFrameResult`. The modules are `V2Racing`, `V2Vehicles`,
`V2RacePhysics`, `V2RaceTracks`, `V2RaceModes`, `V2VehicleAudio`, and
`V2VehicleVFX` (`V2/ue/Source/`), all seven registered in `V2.uproject` (lines
109–139) and all seven compiled on the on-box engine — the build tree carries
9–11 `.o` objects per module under
`V2/ue/Intermediate/Build/Linux/.../<Module>/`. Their type headers are large and
real: `V2RaceModeTypes.h` alone is 3,970 lines declaring **47 `enum class`es and
114 `USTRUCT`s** (the per-mode content model for pursuit, combat, drift, rally,
bike, futuristic, sports, and crossover racing), and `V2VehicleTypes.h` is 1,565
lines / 18 enums / 42 structs.

The reason racing looks different from combat starts with one engineering
decision: **racing does not run on the rollback envelope.** The frame-perfect
rewind-and-resimulate machine documented in
[./rollback-netcode-and-tag-team.md](./rollback-netcode-and-tag-team.md) is for
1v1 fighting; continuous vehicle physics across vendors is not bit-identical, so
every shipped race ruleset uses a `ClientServerAuthoritative` or `AsyncGhost`
network model instead. The corresponding promise is not "bit-identical across
platforms" but "server-consistent outcomes plus deterministic, reproducible
replay." This page owns the racing module set, the vehicle data model, the
physics solver, the audio/VFX evaluators, the designer and pit-crew systems, the
hardware-peripheral story, and the cook-time ecosystem bridge; the section hub
is [../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md).

## What ships, honestly

The **racing logic core is real, compiled, and tested.** The seven modules build
into the editor, and seven automation specs exercise them
(`V2/ue/Source/V2Tests/Automation/`: `Racing.Module.spec.cpp`,
`Vehicles.Module.spec.cpp`, `RacePhysics.Module.spec.cpp`,
`RaceModes.Module.spec.cpp`, `RaceTracks.Module.spec.cpp`,
`VehicleAudio.Module.spec.cpp`, `VehicleVFX.Module.spec.cpp`).
`FV2RaceCatalog::BuildDefaultRaceModeDefinitions()` constructs **25 canonical
race modes** — `Racing.Module.spec.cpp:54` asserts `RaceModes.Num() == 25` —
each validated, each carrying ≥3 HUD injections, each with a deterministic CRC
signature. The race-lifecycle state machine, the officiating/scoring resolver,
the vehicle data-asset quartet and their validators, the analytical physics
solver, the engine/tire/damage math, the audio mix-frame and VFX-frame
evaluators, and the track data asset are all substantive C++ exercised by those
tests. The TypeScript **racing-ecosystem-bridge** service
(`apps/v2/racing-ecosystem-bridge/`) is also real and composes live sister
libraries; its spec has four cases.

Three honest qualifications, all instances of the V2 **target-artifact
convention** (see [V2 Product Promise](./v2-product-promise.md) and
[Game Modes, Mode Plugins, Training & Replay](./game-modes-training-and-replay.md)):

- **The Game Feature plugins are URLs, not plugins.** `BuildRacePluginURL()`
  synthesizes strings like
  `Plugins/GameFeatures/V2Race_Circuit/V2Race_Circuit.uplugin`
  (`V2RaceCatalog.cpp:34`), and map/widget paths like
  `/Game/V2/Racing/Modes/Circuit/L_Circuit` are convention strings. No
  `V2Race_*.uplugin` directory exists on disk, and there are no `.uasset`
  binaries — the racing tree is logic and a content skeleton, validated
  headless.
- **There is no Chaos vehicle solver.** The monolith says "the Chaos vehicle
  solver runs server-authoritative." It does not: a `grep` for `ChaosVehicles` /
  `UChaosVehicleMovementComponent` across `V2/ue/Source` returns nothing, and no
  racing `Build.cs` lists a Chaos dependency. The physics is a **custom
  analytical model** (see below) — which is the honest and, for a deterministic
  replay budget, arguably better choice; but it is not Chaos.
- **There is no `Source/V2Peripherals/` module.** The monolith places the
  hardware SDK layer there. In reality peripherals live in `V2Input`, a balance
  dataset (`V2/balance/data/hardware-peripherals.json`), and a `V2Tests`
  asset-contract test. The designer's `vehicle-designer.proto` gRPC service is
  also absent, and the share-code is a plain string, not the Base32/HMAC grammar
  described. Each of these is corrected in its section below — honest
  "implemented elsewhere / not present" beats fake "shipped as described."

## The module split

These extend the fighting-game module set catalogued in
[Glossary & Module Topology](./glossary-and-module-topology.md).
Responsibilities and the real dependency edges (from each `*.Build.cs`):

| Module             | Real responsibility (verified)                                                                                                                                                                                                                                                             |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **V2Racing**       | Race-mode registry (`UV2RaceRegistrySubsystem`), the 25-mode catalog, lifecycle state machine, officiating/scoring, HUD-injection specs, and the §117 hub + §119 compliance catalogs. Depends on `V2Core`, `V2Modes`, `V2Netcode`.                                                         |
| **V2Vehicles**     | The `DA_Vehicle` / `DA_VehicleTune` / `DA_VehicleCustomization` / `DA_VehicleDamage` data assets, `UV2VehicleChassisComponent` (drivetrain tick), engine-RPM/tire/drivetrain/damage math, the from-scratch designer, pit-crew, telemetry, and launch-roster catalogs. Depends on `V2Core`. |
| **V2RacePhysics**  | The arcade-sim handling spectrum, the per-frame analytical solver, off-road suspension, bike-lean, anti-grav hover, pod-magnet, drafting, nitrous, weather grip, and the determinism + physics-LOD configs. Depends on `V2Core`, `V2Vehicles`.                                             |
| **V2RaceTracks**   | `UV2RaceTrackDataAsset` (sectors, checkpoints, player + AI racing lines, zones, reverse support, replay-pose recording) and the authoring component. Depends on `V2Core`, `V2RacePhysics`, `V2Vehicles`.                                                                                   |
| **V2RaceModes**    | The per-mode Game Feature plugin descriptor registry (`UV2RaceModeRegistrySubsystem`), the eight-step activation plan, and the enormous per-mode content model (3,970-line header). Depends on `V2Core`, `V2RacePhysics`, `V2RaceTracks`, `V2Racing`, `V2Vehicles`.                        |
| **V2VehicleAudio** | `UV2VehicleAudioSubsystem`: per-RPM-bin engine notes, turbo/blow-off, tire screech, Doppler, and ambience-zone mixing into a `FV2VehicleAudioMixFrame`. Depends on `V2Audio`, `V2Core`, `V2RacePhysics`, `V2Vehicles`.                                                                     |
| **V2VehicleVFX**   | `UV2VehicleVFXSubsystem`: tire smoke, sparks, debris, motion blur, anti-grav glow evaluated into a `FV2VehicleVFXFrame`, plus the deep VFX catalog. Depends on `V2Core`, `V2RacePhysics`, `V2Vehicles`, `V2VFX`.                                                                           |

```mermaid
flowchart TB
    Core[V2Core] --> Vehicles[V2Vehicles]
    Vehicles --> RacePhysics[V2RacePhysics]
    RacePhysics --> RaceTracks[V2RaceTracks]
    Vehicles --> RaceTracks
    Core --> Racing[V2Racing]
    Modes[V2Modes] --> Racing
    Netcode[V2Netcode] --> Racing
    Racing --> RaceModes[V2RaceModes]
    RacePhysics --> RaceModes
    RaceTracks --> RaceModes
    Vehicles --> RaceModes
    RacePhysics --> VehicleAudio[V2VehicleAudio]
    Audio[V2Audio] --> VehicleAudio
    RacePhysics --> VehicleVFX[V2VehicleVFX]
    VFX[V2VFX] --> VehicleVFX
```

The DAG is acyclic by construction: `V2Vehicles` defines the data,
`V2RacePhysics` consumes it, `V2RaceTracks` consumes both, and `V2RaceModes`
sits at the top composing everything. `V2VehicleAudio` and `V2VehicleVFX` are
leaves that read physics output without feeding back into it — the same
"presentation never mutates simulation" rule that combat enforces.

## Race modes as data: the catalog and registry

`FV2RaceCatalog::BuildDefaultRaceModeDefinitions()`
(`V2Racing/Private/V2RaceCatalog.cpp:237`) is a flat factory that builds 25
definitions via a `MakeRaceMode(...)` helper. The canonical ids span the design
sections the monolith describes but are richer than its 17-node diagram
suggests: `Race.Circuit`, `Race.Sprint`, `Race.Drag.QuarterMile`, `Race.Drift`,
`Race.TimeTrial`, `Race.Eliminator`, `Race.SpeedTrap`, `Race.Knockout`,
`Race.Outrun`, `Race.RaceDayTournament`, `Race.CustomRoom`,
`Race.Pursuit.Evade`, `Race.CopsVsRacers`, `Race.Combat.Blur`, `Race.DeathRace`,
`Race.PowerPlay`, `Race.CanyonDuel`, `Race.Rally.Stage`, `Race.Bike.Street`,
`Race.PodRacer.AntiGrav`, `Race.Crossover.GetOutAndFight`, `Race.VehicleSoccer`,
`Race.VehicleStunt`, `Race.CrashBreaker`, and `Race.TrackmaniaTimeTrial`. Each
definition carries a `FV2RaceRuleset` whose `ScoringModel` is one of eleven
`EV2RaceScoringModel` values — `FinishOrder`, `BestElapsedTime`, `DriftScore`,
`SpeedTrapAggregate`, `EliminatorSurvival`, `PursuitEscape`, `CombatTakedown`,
`TournamentPoints`, `CanyonLeadDistance`, `GoalScore`, `StuntComboScore`,
`CrashDamageScore` — and the catalog wires sensible specifics: drag sets
`bRequiresPerfectLaunch` with `BestElapsedTime` scoring, drift uses
`DriftScore`, `Race.VehicleSoccer` uses `GoalScore` with `MaxDrivers == 8`
(4v4).

HUD is data, not layout code. `BuildDefaultHUDInjectionsForMode()`
(`V2RaceCatalog.cpp:181`) always emits a `Timer` (slot `Slot.TopCenter`,
priority 120), a `PositionTower`, and an `ObjectiveTracker`, then branches on
the scoring model — `DriftScore → DriftMeter`, `GoalScore → GoalScoreboard`,
`StuntComboScore → StuntMeter`, `CrashDamageScore → CrashDamage`,
`BestElapsedTime/SpeedTrapAggregate → SectorSplits`,
`PursuitEscape → PursuitHeat` — and appends `PowerUpInventory` + `VehicleDamage`
when combat is allowed and a `PowerPlayPrompt` when power-plays are on. That is
why the test can assert "drift mode exposes the drift HUD layer" without a
single widget asset existing: the injection is a `FV2RaceHUDInjectionSpec` with
a `FSoftClassPath` pointing at a convention widget path. These HUD layers are
the racing entries that the HUD system in
[./ui-hud-vr-ar-and-accessibility.md](./ui-hud-vr-ar-and-accessibility.md)
consumes.

### Lifecycle and officiating, worked end to end

`UV2RaceRegistrySubsystem` (`V2Racing/Public/V2RaceRegistrySubsystem.h`) is the
runtime. The lifecycle is an enforced state machine — `IsLegalTransition()`
(`V2RaceRegistrySubsystem.cpp:381`) only allows
`Registered/Lobby → Staging → Countdown → Racing → FinalLap → Finished → Officiating → Results`,
with `Aborted` reachable from any live state. A worked example, exactly as
`Racing.Module.spec.cpp` drives it:

```mermaid
sequenceDiagram
    participant C as Caller
    participant R as UV2RaceRegistrySubsystem
    C->>R: BuildRaceStartSnapshot(req: Circuit, 8 drivers, bOnline=false)
    R-->>C: false — "requires online racing services"
    C->>R: BuildRaceStartSnapshot(req with bOnline=true, bRanked=true)
    R-->>C: snapshot{State=Staging, 8 participants, bReplayDeterministic}
    C->>R: AdvanceRaceState(Countdown) … Racing … FinalLap … Finished
    C->>R: AdvanceRaceState(Officiating) … Results
    C->>R: OfficiateRaceSnapshot(finishedSnapshot)
    R-->>C: report{Classification sorted, Incidents=[RedLightPenalty]}
```

Two real behaviours fall out of that flow. First, **online modes fail loud when
services are absent**: `BuildRaceStartSnapshotFromDefinitions` rejects an
offline request for an online-required mode with the message "requires online
racing services" (`Racing.Module.spec.cpp:176`) — a fail-closed gate, not a
silent downgrade. Second, **officiating is scoring-aware**: for a `FinishOrder`
circuit it ranks lower elapsed time first (Driver.B at 184 000 ms beats Driver.A
at 186 000 ms), and for a `DriftScore` race it ranks higher score first
(Driver.A at 120 000 beats Driver.C at 101 000), with a red-light penalty
surfaced as an incident. The whole catalog hashes to a deterministic CRC
(`BuildCatalogSignature`, `V2RaceCatalog.cpp:286`) so a content drift shows up
as a changed signature in CI.

`V2RaceModes` adds a second registry, `UV2RaceModeRegistrySubsystem`, that turns
each definition into a `FV2RaceModePluginDescriptor` (`MakePluginFromRaceMode`,
`V2RaceModePluginCatalog.cpp:86`) carrying the synthesized
`GameFeaturePluginURL`, the `RequiredModules`, and an `EV2RaceModePluginState`
(`Unregistered → Registered → Loading → Active → Suspended/Failed`).
`BuildActivationPlan` produces the eight ordered `EV2RaceModeActivationStep`s —
`ValidateRequest`, `LoadRequiredModules`, `ActivateGameFeature`,
`RegisterTrackRules`, `InjectRaceHUD`, `OpenTrackMap`, `StartRaceState`,
`MarkReady`. The plan and the module-load are real C++; the Game Feature plugin
the plan would activate is the target-artifact URL.

## Vehicles: data assets and the chassis component

A vehicle ships as four `UPrimaryDataAsset` subclasses
(`V2Vehicles/Public/V2VehicleDataAssets.h`): `UV2VehicleDataAsset` (the base
spec), `UV2VehicleTuneDataAsset`, `UV2VehicleCustomizationDataAsset`, and
`UV2VehicleDamageDataAsset` — the `DA_Vehicle` family the monolith names. The
base asset composes a stack of validated structs: a `FV2VehicleEngineRPMModel`
(idle/redline/peak-torque RPM, `MaxTorqueNm`, aspiration, per-RPM-bin sound ids,
turbo `BoostPressureKpa` + `BoostSpoolDelaySeconds`, and a
`TSoftObjectPtr<UCurveFloat>` torque curve), a `FV2VehicleDrivetrainModel`
(layout across FWD/RWD/AWD/4×4/ bike-chain/hover/hover-magnet, gear ratios,
`ShiftTimeMs`, a `PerfectShiftWindowMs` of 45 ms, clutch-kick multiplier), a
`FV2VehicleTireModel` (dry/wet/dirt grip, lateral stiffness, slip-angle peak,
heat/wear rates), plus mass, collision, aero, suspension, damage, and
performance-envelope structs. Every struct has an `IsValid…(OutErrors)`
validator and the asset's `BuildPerformanceRating()` rolls a single number out
of the envelope.

`UV2VehicleChassisComponent` (`V2VehicleChassisComponent.h`) is the runtime that
brings a data asset to life: `ConfigureFromVehicleData()` copies the models in,
`ApplyTuneData()` layers a tune, `TickDrivetrain(Delta, Throttle, Brake)` steps
RPM and wheel speed, `ShiftToGear()` handles the box, and
`CalculateAvailableWheelTorque()` / `CalculateCurrentGrip(Wetness, Dirt)` expose
the derived numbers. The math underneath is genuinely domain-specific rather
than CRUD: `FV2VehicleTireModel::CalculateSurfaceGrip` lerps dry→wet by wetness
then that result→dirt by coverage (`V2VehicleTypes.cpp:389`), and the engine's
`CalculateTorqueAtRPM` interpolates the curve. This is the data the EV cook-time
bridge and the designer both manipulate.

## Race physics: an analytical per-frame solver

`UV2RacePhysicsComponent::SimulateFrame()` is the entry point
(`V2RacePhysicsComponent.cpp:16`). It does not own an integrator; it delegates
to `UV2RacePhysicsBlueprintLibrary::SimulatePhysicsFrame()`
(`V2RacePhysicsBlueprintLibrary.cpp:197`), which composes the result from a set
of small, named, closed-form functions: a normal force from the suspension
(`CalculateNormalForce`), a surface grip from tire × contact patch × the
handling profile's `TractionScale`, a yaw torque, a hover force, a stepped
bike-lean angle, and a pod-magnet centering force. The handling personality is a
`FV2RaceHandlingTuning` selected from nine `EV2RacePhysicsHandlingProfile`s
(`Arcade`, `Simcade`, `Simulation`, `Drift`, `OffRoad`, `Rally`, `Bike`,
`AntiGrav`, `PodRacer`) plus a 0–100 `ArcadeSimDial` — the continuous arcade↔sim
spectrum the design calls for.

The yaw-torque formula is a fair example of the model's honesty —
`CalculateYawTorque` (`V2RacePhysicsTypes.cpp:101`) is:

```
yaw = (steer + counterSteer) · SteeringResponse · max(0, grip) · speedFactor · assistMul
      − YawDamping · speedFactor · 0.10
```

where `speedFactor = clamp(speedKph / 160, 0.15, 1.60)`, `counterSteer` is a
negative feedback term scaled by the auto-counter-steer assist, and `assistMul`
softens torque when stability assist is on. It is a real steering response with
speed sensitivity and an assist seam, not a constant. The same shape recurs in
drafting (`CalculateDraftDragScale`, `V2RacePhysicsTypes.cpp:242`: a slipstream
that starts at 42 m, peaks at 7.5 m, and removes up to 24% drag), in the bike
lean, the hover spring, and the pod-magnet centering. The exotic chassis types
each get their own state struct — `FV2OffroadSuspensionState`,
`FV2BikeLeanState` (max lean 58°), `FV2AntiGravHoverState` (target height 180
cm, magnet strength, damping), `FV2PodRacerMagnetState` — so a hovercraft and a
superbike use the same solver with different inputs.

Crucially, `V2RacePhysics` also carries a `FV2RaceDeterminismConfig` (seed 1337,
`FixedStepHz = 60`, `bQuantizeFloatingPoint`, and a
`BuildDeterministicFrameHash` that `HashCombine`s seed/frame/input/step into a
non-negative int32) and a `FV2RacePhysicsLODConfig` whose `ResolveLODMode`
returns `Full / ReducedFidelity / PoseInterpolationOnly` by distance and
on-screen flag. This is the data spine behind the replay-determinism gate and
the server-authoritative LOD model: the server runs full physics for all
vehicles; the client LOD only changes local visual fidelity, never sync. One
honest nuance — the determinism config exposes
`bRollbackEligibleUpToEightPlayers`, but **no shipped race mode in the catalog
selects a rollback netcode model**; the flag is a forward-looking data field,
and the live promise remains client-server with prediction, consistent with
[./rollback-netcode-and-tag-team.md](./rollback-netcode-and-tag-team.md).

## Damage model

Damage is five `EV2VehicleDamageTier` steps — `Clean`, `Scuffed`, `Damaged`,
`Wrecked`, `Totaled` — each a `FV2VehicleDamageTierModel` with a decal preset,
bend-deformation scalar, part-fall-off chance, steering pull, engine-power-loss
percent, brake-failure and transmission-seize chances, and a repair cost. The
performance consequence is computed, not cosmetic: `GetEnginePowerScale`
(`V2VehicleTypes.cpp:187`) returns `1.0` when the ruleset is arcade and
`bCosmeticOnlyArcadeDamage` is set, otherwise
`clamp(1 − EnginePowerLossPct, 0, 1)` for the active tier. `Totaled` flips
`bTotaledTriggersRetireOrGetOutAndFight`, which is the hook into the
racing×fighting crossover (`Race.Crossover.GetOutAndFight`) — a totaled car can
retire the racer or dump them out to fight on foot.

Damage is also where licensing meets gameplay.
`FV2RacingManufacturerDamagePolicySpec` gates `LicensedLuxuryPermission` to
`CosmeticOnly` while `OriginalIPPermission` allows `FullDamage`, and
`FV2RacingVehicleLicenseContractSpec` records manufacturer-signed contracts and
a `DamagePermission`. These live in the §119 `FV2RacingComplianceCertCatalog`,
which also carries region variants (a `bChinaPublisherSKUAdjustsCopVisuals`
flag, kph/mph display unit), a content-safety policy (no impaired-driving
depiction; "incapacitate not kill" outside Death Race), the anti-cheat gate ids
(impossible-time detection, the replay-determinism gate, valid tuning ranges),
and the cert/accessibility specs. The region-variant companion doc the catalog
points at, `V2/docs/regions/racing-variant.md`, does exist. Compliance detail
belongs to
[./security-compliance-and-sister-monorepo-integration.md](./security-compliance-and-sister-monorepo-integration.md).

## Audio and VFX subsystems

Both presentation subsystems are pure evaluators. `UV2VehicleAudioSubsystem`
registers per-vehicle `FV2VehicleEngineAudioProfile`s and ambience zones, then
`EvaluateVehicleMixFrame(VehicleId, turbo, tire, doppler, RPM, throttle, boost)`
returns a `FV2VehicleAudioMixFrame` — the per-RPM-bin engine note blend, turbo
spool / blow-off, tire screech, and Doppler shift resolved into one frame. The
engine model's five RPM-bin sound ids (`IdleRPMBinSoundId` …
`RedlineRPMBinSoundId`, plus an optional `BlowOffValveSoundId`) come straight
from the vehicle data asset, so audio is authored on the same struct that drives
physics. `UV2VehicleVFXSubsystem` mirrors this:
`EvaluateVehicleVFXFrame(smoke, spark, debris, motion, glow, airborne)` returns
a `FV2VehicleVFXFrame`, and the subsystem also holds the
`FV2RacingVFXDeepCatalog`. Neither subsystem ships particle or wave assets —
they resolve parameters that an authored asset would bind to — which is
consistent with the broader
[presentation pipeline](./presentation-av-and-signature-content.md).

## Vehicle Designer, Pit Crew, and telemetry

`V2VehicleTypes.h` carries the whole §120 designer suite as validated structs.
`FV2CustomVehicleDesignerSpec` lists the authored components (chassis
silhouette, engine-bay layout, suspension mounts) and a set of slider-based
`FV2CustomVehicleGeometryControlSpec`s that feed an autosculpt subdivision
surface. The balance gate is real and specific:
`FV2CustomVehicleBalanceBudgetSpec` sets a `TotalStatBudget` of 1000, a
`MaxTopSpeedPenaltyPer100KgKph` of 8.0, and a
`bBudgetLinterBlocksOutOfRangeBuilds` flag — the "heavier chassis slows top
speed, bigger engine raises torque and mass" tradeoffs the design promises.
`FV2CustomVehicleSaveShareGallerySpec` sets 10 save slots per user and gates
ranked eligibility to the designer-approved subset while leaving casual/private
lobbies always eligible.

The pit-crew minigame is genuinely deterministic, not a `Math.random()` fake:
`FV2PitCrewActionSpec::ResolvePitStop(StepTimingHits, BaseSecondsPerStep)`
(`V2VehicleTypes.h:1330`) takes a vector of per-step timing hits and returns a
`FV2PitStopResult` — a hit step costs the base time, a missed step costs double,
and a flawless run is the perfect stop. Mechanic specialty cuts pit time 30%,
other specialties 10% (`FV2PitCrewMechanicMinigameSpec`). Driver telemetry
(`FV2DriverTelemetryDashboardSpec`), auto-classified driving styles
(Aggressive/Defensive/Drafter/Reckless/Conservative/SlipstreamMaster/DriftSpecialist),
and a heat-map spec round out the profile surface that
[./telemetry-performance-testing-and-release-gates.md](./telemetry-performance-testing-and-release-gates.md)
and
[./live-ops-store-progression-and-community.md](./live-ops-store-progression-and-community.md)
build on.

Two corrections to the monolith's "service contract" here. The promised gRPC
service `libs/proto/v2/racing/vehicle-designer.proto` is **absent**, and the
share-code is not a "Base32-encoded 12-char HMAC over vehicle hash + watermark +
nonce." The actual implementation is human-readable:
`SaveSlot.ShareCode = FString::Printf(TEXT("V2-%s-%s"), VehicleId, SlotId)`
(`V2VehiclesBlueprintLibrary.cpp:355`). The originality-shields review the
monolith cites is real (`V2/docs/decisions/originality-shields-launch-gate.md`
exists), but the cryptographic share grammar and the gRPC façade are
spec-described, not shipped.

## Hardware peripherals — where they actually live

There is no `V2Peripherals` module. The peripheral story is split across three
real places. The **input layer is `V2Input`** — `V2InputTypes.h` declares
`EV2HardwarePeripheralClass` (`SteeringWheel`, `PedalSet`, …) alongside the rest
of the fighting-game input model documented in
[./animation-and-input-pipeline.md](./animation-and-input-pipeline.md). The
**vendor catalogue is data**: `V2/balance/data/hardware-peripherals.json` is the
shipped source of truth, enumerating wheels from Logitech, Thrustmaster,
Fanatec, Hori, MOZA, Cammus, Asetek SimSports, and Simucube; pedals, shifters,
handbrakes, button-boxes, sim-rigs (SimVibe/ButtKicker bass shakers),
fight-sticks, and the adaptive controllers (PlayStation Access, Xbox Adaptive
Controller, Logitech Adaptive Gaming Kit, Quadstick). It also encodes the
force-feedback model (per-vehicle authored profile; per-corner suspension,
per-tire grip, per-collision impact, per-curb rumble;
gain/dynamic-range/linearity/damping/spring/friction tuning UI; direct-drive
torque scaling; a community profile gallery), a first-launch calibration wizard
with load-cell brake and pedal-curve calibration, and the **ranked-pool
separation** (wheel+pedals vs gamepad in separate tournament pools, gamepad pool
with more assists by default). The **C++ cert surface is a subset**:
`EV2RacingWheelVendor` in `V2RaceTypes.h` lists only the five primary vendors
used by `FV2RacingCertWheelSupportSpec`, while the balance JSON covers eight
wheel makers. Validation runs through `V2Tests` (`HardwarePeripherals.spec.cpp`
and the `V2.Input.HardwarePeripherals.AssetContract` automation the JSON names
at its tail). So the capability the monolith promises is real; the file layout
it asserts is wrong.

## The cook-time ecosystem bridge

The one piece of racing that runs as a TypeScript service rather than UE C++ is
`apps/v2/racing-ecosystem-bridge/`. `buildV2RacingEcosystemBridgeExport()`
composes four sister-monorepo libraries to produce a cook-time manifest: it
models the **driver as an articulated body** through `@galatea/kinematics` +
`@galatea/whole-body-control` (mass matrix, gravity-compensation torque,
center-of-mass support-polygon containment), configures an **EV powertrain**
through `@saraswati/ev` (`PowertrainConfigurator` → motor, gear ratios, regen,
drivetrain efficiency, estimated cost), and evaluates the **track world**
through `@maya/genesis-terrain` + `@maya/genesis-urban` (streaming-LOD and
road-network coverage). The output is a status
(`ready`/`needs-attention`/`blocked`), an issue list, and a `cookManifestText`.

The bridge's defining property is a hard boundary: its
`V2_RACING_ECOSYSTEM_BRIDGE_ROLLBACK_POLICY` is
`authoring-and-content-cook-only-no-live-race-frame-rpc`, it sets
`offRollback: true` / `mayInfluenceRollback: false` /
`rejectsLiveRaceFrameRpc: true`, and `validateRequest` throws if
`calledFromLiveRaceFrame` is set. In other words, this composition can shape
vehicles and tracks at cook time but is structurally forbidden from touching a
live race frame — the same discipline that keeps presentation out of simulation,
applied at the service boundary. It is the racing entry point into the
sister-monorepo integration covered by
[./security-compliance-and-sister-monorepo-integration.md](./security-compliance-and-sister-monorepo-integration.md)
and the build/cook pipeline in
[./build-cook-assets-data-and-production.md](./build-cook-assets-data-and-production.md).

## How it connects to neighbouring systems

Racing is deliberately a peer genre that reuses the fighting backbone rather
than forking it. Combat pickups, Death Race weaponization, and Get-Out-and-Fight
all route into the GAS layer in
[./combat-system-gas-frame-data-and-determinism.md](./combat-system-gas-frame-data-and-determinism.md);
race HUD layers are injected through the system in
[./ui-hud-vr-ar-and-accessibility.md](./ui-hud-vr-ar-and-accessibility.md); race
modes are registered, loaded, and lifecycle-driven by the same discipline as the
fighting modes in
[./game-modes-training-and-replay.md](./game-modes-training-and-replay.md);
matchmaking, ranked MMR, anti-cheat, and the autolog rivalry surface live in
[./online-backbone-and-competitive-integrity.md](./online-backbone-and-competitive-integrity.md);
free-roam convoys, heists, and demolition derby are the open-world racing modes
in
[./open-world-coop-and-special-modes.md](./open-world-coop-and-special-modes.md);
and the AI driver personalities, cop AI, and the racing AI director connect to
[./esports-companion-and-ai-services.md](./esports-companion-and-ai-services.md).
The shared roster, currency ledger, store, and Battle Pass that make the
crossover economically coherent are in
[./live-ops-store-progression-and-community.md](./live-ops-store-progression-and-community.md).
For the design source this page reorganizes and corrects, see the racing
sections of [../V2_ARCHITECTURE.md](../V2_ARCHITECTURE.md).
