Modes, vehicles, tracks, fixed-step physics, and result evidence are versioned contracts. Customization and presentation cannot mutate competitive physics outside the admitted tuning version.
V2 is a fighting game that also ships a full racing genre — not a bolt-on
minigame, but a peer product with its own roster, its own modes, its own online
ladders, and its own engineering discipline. The lineage is explicit in the
design: Most Wanted's Blacklist and police pursuit, Split/Second's environmental
Power-Plays, Blur's pickup combat, Death Race's weaponized cars, GRID's sim
handling and flashback, Carbon's canyon duels and crew progression, NFS
Underground 2's autosculpt-deep customization, and — beyond the street-racing
core — WipEout/F-Zero anti-grav and pod-racer classes. On disk that ambition is
seven Unreal C++ modules under V2/ue/Source/: V2Racing, V2Vehicles,
V2RacePhysics, V2RaceTracks, V2RaceModes, V2VehicleAudio, and
V2VehicleVFX. They follow the same "data plus a load plan" discipline as the
fighting spine: a race mode is an FV2RaceModeDefinition value, a vehicle is a
UV2VehicleDataAsset, and the handling is an analytical per-frame solver that
takes those structs and returns an FV2RacePhysicsFrameResult.
This page is the player-and-systems tour of three of those concerns: the racing component's overview and how it integrates with the fighting backbone; the vehicle framework — physics, tracks, customization; and racing modes plus online. The racing×fighting crossover (fighter-as-driver, get-out-and-fight), the open-world Metro City, heists, demolition derby, and the persistent economy get their own page, ./racing-crossover-open-world-and-ops.md; the registry machinery, the vehicle data model in full, the designer/pit-crew systems, the peripheral story, and the cook-time ecosystem bridge are in the architecture companion, ../architecture/racing-and-vehicle-architecture.md. For the full feature scope this slots into, start at the hub: ../V2_features.md.
What ships, honestly#
The racing logic core is real, compiled, and tested. All seven modules build
into the editor on the on-box engine, and seven automation specs in
V2/ue/Source/V2Tests/Automation/ exercise them with real assertion weight:
Racing.Module.spec.cpp (79 checks), RaceModes.Module.spec.cpp (201),
Vehicles.Module.spec.cpp (74), RacePhysics.Module.spec.cpp (45),
RaceTracks.Module.spec.cpp (43), VehicleVFX.Module.spec.cpp (39), and
VehicleAudio.Module.spec.cpp (24).
FV2RaceCatalog::BuildDefaultRaceModeDefinitions() constructs 25 canonical
race modes — Racing.Module.spec.cpp:54 asserts RaceModes.Num() == 25 —
each validated, each carrying scoring-aware HUD injections and a deterministic
CRC signature. The race-lifecycle state machine, the officiating/scoring
resolver, the vehicle data-asset quartet, the analytical physics solver, the
engine/tire/damage math, and the audio/VFX mix-frame evaluators are all
substantive C++ driven by those tests.
Four honest qualifications, each an instance of V2's target-artifact convention (see the architecture companion):
- The Game Feature plugins are URLs, not plugins.
MakeRaceModesynthesizes each definition'sGameFeaturePluginURLandPrimaryMapPathby convention (BuildRacePluginURL,BuildRaceMapPath); noV2Race_*.uplugindirectory and no race.uassetbinaries exist on disk. The racing tree is logic and a content skeleton, validated headless. - There is no Chaos vehicle solver. The design prose says the Chaos vehicle
solver runs server-authoritative; it does not — a grep for
ChaosVehicles/UChaosVehicleMovementComponentacrossV2/ue/Sourcereturns nothing. The physics is a custom analytical model (below), which for a deterministic replay budget is the honest and arguably better choice. - Audio and VFX resolve parameters, not assets.
UV2VehicleAudioSubsystemandUV2VehicleVFXSubsystemare pure evaluators; they ship no MetaSound waves or Niagara systems — they compute the mix/emitter values an authored asset would bind to. - Racing-specific matchmaking, MMR, and ranked ladders are not in these modules. The catalog carries the network model and a fail-loud online gate; the cross-play queues, separate Racing MMR, and Bronze→Legend ladders the design promises are realized through the shared online backbone, covered in ./online-services-network-and-tournaments.md.
Racing as a peer genre: overview and integration#
V2 racing and V2 fighting share one roster, one online backbone, one cosmetic
shop, one Battle Pass, and one profile + match-history + currency ledger. The
reason the two genres feel different starts with one engineering decision:
racing does not run on the rollback envelope. The frame-perfect
rewind-and-resimulate machine that powers 1v1 fighting (see
../architecture/rollback-netcode-and-tag-team.md)
is not viable for continuous vehicle physics, which is not bit-identical across
CPU vendors under cross-platform float modes. So every shipped race ruleset
selects one of four network models in EV2RaceNetworkModel — Offline,
ClientServerAuthoritative, AsyncGhost, or LocalSplitScreen
(V2RaceTypes.h:29) — and the live promise becomes "server-consistent outcomes
plus deterministic, reproducible replay," not "bit-identical across platforms."
The server runs authoritative physics; the client predicts and smooths only its
local pose and never resimulates; cheat detection runs server-side on the
authoritative state.
The seven modules form an acyclic dependency graph (each edge is verified from a
*.Build.cs). The four this page centers on:
| Module | Real responsibility (verified) | Build.cs deps |
|---|---|---|
| V2Vehicles | The four DA_Vehicle* data assets, UV2VehicleChassisComponent (drivetrain tick), and engine-RPM/tire/drivetrain/damage math (V2VehicleTypes.h, 1,565 lines). |
V2Core |
| V2RacePhysics | The nine-profile arcade↔sim handling spectrum, the per-frame analytical solver, off-road suspension, bike-lean, anti-grav hover, pod-magnet, drafting, nitrous, weather, determinism. | V2Core, V2Vehicles |
| V2VehicleAudio | UV2VehicleAudioSubsystem: per-RPM-bin engine notes, turbo spool/blow-off, tire screech, Doppler, ambience mixed into an FV2VehicleAudioMixFrame. |
V2Audio, V2Core, V2RacePhysics, V2Vehicles |
| V2VehicleVFX | UV2VehicleVFXSubsystem: tire smoke, sparks, debris, motion blur, anti-grav glow evaluated into an FV2VehicleVFXFrame, plus the deep VFX catalog. |
V2Core, V2RacePhysics, V2Vehicles, V2VFX |
V2Vehicles defines the data; V2RacePhysics consumes it; V2VehicleAudio and
V2VehicleVFX are leaves that read physics output without feeding back — the
same "presentation never mutates simulation" rule combat enforces. V2Racing
and V2RaceModes sit above as the mode registries.
The vehicle framework: data, physics, tracks, customization#
The vehicle data spine#
A vehicle ships as four UPrimaryDataAsset subclasses
(V2Vehicles/Public/V2VehicleDataAssets.h): UV2VehicleDataAsset (the base
spec), UV2VehicleTuneDataAsset, UV2VehicleCustomizationDataAsset, and
UV2VehicleDamageDataAsset. The base asset composes a stack of validated
structs — an FV2VehicleEngineRPMModel, an FV2VehicleDrivetrainModel, an
FV2VehicleTireModel, plus mass, collision, aero, suspension, damage, and a
performance envelope — and exposes IsValidVehicleData(OutErrors) and
BuildPerformanceRating(). The data model is rich: a chassis is one of 21
EV2VehicleChassisType archetypes (Compact, Sedan, Coupe, Supercar, Hypercar,
Muscle, Tuner, Truck, SUV, Rally, Buggy, MonsterTruck, SportBike, Cruiser,
PodRacer, Hover … PoliceInterceptor); the drivetrain spans FWD/RWD/AWD/4×4/
bike-chain/hover/hover-magnet; tires draw from 15 EV2VehicleTireCompounds.
The math is genuinely domain-specific, not CRUD. CalculateTorqueAtRPM
(V2VehicleTypes.cpp:227) builds a real torque curve — it lerps 0.62 → 1.0 up
to peak-torque RPM and 1.0 → 0.72 from peak to redline, then multiplies by a
boost factor of 1 + BoostPressureKpa / 220.
FV2VehicleTireModel::CalculateSurfaceGrip (V2VehicleTypes.cpp:389) lerps
dry→wet grip by wetness, then that result→dirt grip by coverage. The drivetrain
carries a PerfectShiftWindowMs = 45 so a clean manual shift earns a bonus.
UV2VehicleChassisComponent is the runtime that brings the asset to life:
ConfigureFromVehicleData(), ApplyTuneData(),
TickDrivetrain(Delta, Throttle, Brake), ShiftToGear(), and the derived
CalculateAvailableWheelTorque() / CalculateCurrentGrip(Wetness, Dirt).
The analytical physics solver#
UV2RacePhysicsComponent::SimulateFrame() delegates to
UV2RacePhysicsBlueprintLibrary::SimulatePhysicsFrame(), which composes the
FV2RacePhysicsFrameResult from small, named, closed-form functions: a normal
force from 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 yaw
torque (V2RacePhysicsTypes.cpp:101) is a fair example of the model's honesty —
a real steering response with speed sensitivity and an assist seam, not a
constant:
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. The handling personality is one of
nine EV2RacePhysicsHandlingProfiles — Arcade, Simcade, Simulation,
Drift, OffRoad, Rally, Bike, AntiGrav, PodRacer — and
BuildHandlingTuning sets each profile's constants (Arcade pins the dial at 15
with SteeringResponse 1.35; Simulation at 88 with 0.82 and four
deterministic substeps). The continuous arcade↔sim dial is real too:
BuildHandlingTuningFromSpectrum lerps every coefficient along a 0–100
ArcadeSimDial, and BuildDefaultAssistConfig gates the assist library (ABS /
TCS / stability / steering / auto-brake / racing line / cornering suggestion /
anti-spin / auto-counter-steer) by that dial, with per-assist ranked eligibility
(MaxRankedTier) so a Tier-3 ranked driver loses the heavier crutches.
The exotic chassis types each get their own state struct and force law: an
off-road suspension that sums static load + spring + damping, a bike lean that
maxes at 58° and lerps toward steer · maxLean · clamp(speed/120), an
anti-grav hover spring (mass·g + heightError·magnet − vVel·damping along the
track normal, target height 180 cm), and a pod-racer magnet that centers on
(leftErr − rightErr)·attraction. Three more closed-form models round out the
feel: drafting (BuildDefaultDraftingModel: a slipstream that starts at 42 m,
peaks at 7.5 m, and removes up to 24% drag), nitrous (CalculateBoostPowerScale
lerps 1.0 → 1.22× over the burst), and weather grip (rain/storm floor 0.55,
snow/ice floor 0.35, with an 0.08 relief for rally/snow/off-road compounds).
Crucially, FV2RaceDeterminismConfig pins RngSeed = 1337, FixedStepHz = 60,
floating-point quantization, and a BuildDeterministicFrameHash — the spine
behind the replay-determinism gate — while
FV2RacePhysicsLODConfig::ResolveLODMode returns
Full / ReducedFidelity / PoseInterpolationOnly by distance and on-screen flag
so the client LOD only changes local visual fidelity, never sync. One honest
nuance: the config exposes bRollbackEligibleUpToEightPlayers, but no shipped
race mode selects a rollback netcode model — it is a forward-looking field.
Damage, licensing, tracks, and customization#
Damage is five EV2VehicleDamageTier steps — Clean, Scuffed, Damaged,
Wrecked, Totaled — and 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, the hook into the racing×fighting
crossover. Damage is also where licensing meets gameplay: the base asset's
bOriginalIP / bAllowsFullDamage flags pair with
FV2RacingManufacturerDamagePolicySpec, which gates LicensedLuxuryPermission
to CosmeticOnly while OriginalIPPermission allows FullDamage — so a
licensed luxury brand never visibly deforms past Scuffed, while original-IP
vehicles run the full five tiers to Totaled.
Tracks live in V2RaceTracks as a UV2RaceTrackDataAsset (sectors,
checkpoints, player + AI racing lines, zones, reverse support, replay-pose
recording); that module and the from-scratch Vehicle Designer, balance-budget
linter, and pit-crew minigame are detailed in the architecture companion. The
surface model the physics reads is EV2RaceSurfaceType (Asphalt, WetAsphalt,
Dirt, Mud, Snow, Sand, Metal, HoverRail), each with a drag scale (mud 1.42, sand
1.55, hover-rail 0.72) so a buggy on sand and a pod on a hover-rail use the same
solver with different inputs.
The engine note and the screen: audio and VFX evaluators#
UV2VehicleAudioSubsystem registers per-vehicle FV2VehicleEngineAudioProfiles
and returns an FV2VehicleAudioMixFrame from EvaluateVehicleMixFrame(...).
The engine character is one of nine EV2VehicleEngineAudioCharacters (Inline-4
turbo, Inline-6 NA, V8 muscle, V12 supercar, Rotary, V-twin cruiser, Boxer,
Electric, AntiGrav), and the math is specific: pitch is
0.78 + normalizedRPM · RedlinePitchLift, a backfire triggers only when the
throttle drop clears 0.65 and RPM is above 4200 (ShouldTriggerBackfire),
and Doppler is a real radial- velocity shift
clamp(c / (c − vRadial), 0.65, 1.45) with c = 34300 cm/s. Critically, the
profile embeds the same FV2VehicleEngineRPMModel that drives physics — audio
is authored on the struct that drives the wheels. UV2VehicleVFXSubsystem
mirrors this, returning an FV2VehicleVFXFrame across 16 EV2VehicleVFXLayers
(tire smoke scaled by slip ratio and surface, sparks on chassis/curb contact,
debris, brake-disc glow, motion blur, anti-grav glow), and holds the
FV2RacingVFXDeepCatalog whose damage-shader spec asserts a five-tier blend
over a 30-frame material transition and gates Death-Race gore behind the
content-tier flag.
Racing modes and online#
Twenty-five modes as data#
Every race mode is one FV2RaceModeDefinition carrying an id, a family, an
FV2RaceRuleset, a synthesized plugin URL and map path, a driver-count band,
and a set of HUD injections. The ruleset is where the genre lives: a
ScoringModel from twelve EV2RaceScoringModel values (FinishOrder,
BestElapsedTime, DriftScore, SpeedTrapAggregate, EliminatorSurvival,
PursuitEscape, CombatTakedown, TournamentPoints, CanyonLeadDistance,
GoalScore, StuntComboScore, CrashDamageScore) plus a NetworkModel, a lap
count, a driver cap, and toggles for combat, power-plays, pursuit AI, flashback,
and perfect-launch. BuildDefaultRaceModeDefinitions (V2RaceCatalog.cpp:240)
wires sensible specifics through a MakeRaceMode(...) factory:
Race.Circuit—FinishOrder, client-server, 12 drivers, 3 laps.Race.Drag.QuarterMile—BestElapsedTimewithbRequiresPerfectLaunch, 4 drivers.Race.Drift—DriftScore, 8 drivers;Race.CanyonDuel—CanyonLeadDistance, 2 drivers.Race.TimeTrialandRace.Rally.Stage—AsyncGhost(race against a ghost, not a live field).Race.CustomRoom— up to 32 players with combat, power-plays, and pursuit all host-toggleable (tagCrossPlay32).Race.Pursuit.Evade/Race.CopsVsRacers—PursuitEscapewith pursuit AI;Race.Combat.Blur/Race.DeathRace—CombatTakedownwith combat enabled.
HUD is data, not layout code: BuildDefaultHUDInjectionsForMode always emits a
Timer, PositionTower, and ObjectiveTracker, then branches on the scoring model
(DriftScore → DriftMeter, GoalScore → GoalScoreboard,
PursuitEscape → PursuitHeat, …) and appends PowerUpInventory +
VehicleDamage when combat is allowed. That is why a test can assert "drift
mode exposes the drift HUD layer" with no widget asset on disk. Three of the 25
— Race.VehicleSoccer, Race.VehicleStunt, Race.TrackmaniaTimeTrial — set
bAvailableAtLaunch = false, an honest post-launch deferral the catalog encodes
rather than hides.
Online, ranked, and anti-cheat#
UV2RaceRegistrySubsystem enforces the lifecycle as a real state machine —
Registered/Lobby → Staging → Countdown → Racing → FinalLap → Finished → Officiating → Results,
with Aborted reachable from any live state. Two behaviors fall out. First,
online modes fail loud: BuildRaceStartSnapshotFromDefinitions rejects an
offline request for an online-required mode with the literal message "requires
online racing services" (Racing.Module.spec.cpp:178) — a fail-closed gate, not
a silent downgrade, and the reason a mode greys out when you are not signed in.
Second, officiating is scoring-aware: a FinishOrder circuit ranks lower
elapsed time first, a DriftScore race ranks higher score first, and a
red-light infraction surfaces as an
EV2RaceOfficiatingDecision::RedLightPenalty incident. The whole catalog hashes
to a deterministic CRC (BuildCatalogSignature) so content drift shows up as a
changed signature in CI.
Anti-cheat is encoded as data in the §119 FV2RacingComplianceCertCatalog →
FV2RacingAntiCheatGateSpec: per-section physics-impossible-time detection (a
sector below the achievable minimum flags), a replay-determinism gate on race
record-writes (Gate.Racing.RecordWrite.ReplayDeterminism), and per-vehicle
tuning-parameter range enforcement (Table.Racing.Tuning.ValidRanges,
bOutOfRangeTuneFlagged). The same catalog carries the wheel-vendor cert spec,
the region variants (kph/mph display, China-SKU cop visuals), and the
content-safety policy ("incapacitate not kill" outside Death Race). The
player-facing online surface this gate protects — cross-play queues, separate
Racing MMR, Bronze→Legend ladders, Autolog rivalries, and the racing esports
circuit — is delivered by the shared online backbone and the esports toolkit,
documented in
./online-services-network-and-tournaments.md
and
./ranked-esports-circuit-and-local-coop.md.
How it connects#
Racing reuses the fighting backbone rather than forking it. Combat pickups, Death-Race weaponization, and the get-out-and-fight transition route into the GAS layer in ./combat-systems-defense-and-game-feel.md; the replay theater, ghosts, and GRID flashback share the mode-registry and replay codec discipline in ./mode-catalog-training-and-replay.md; the crossover, open-world Metro City, heists, derby, and persistent economy are in ./racing-crossover-open-world-and-ops.md; and the shared roster, store, and Battle Pass that make the crossover economically coherent are in ./live-service-dlc-battle-pass-and-companion.md. For the registry internals, the full vehicle data model, the Vehicle Designer and pit-crew systems, the hardware-peripheral story, and the cook-time ecosystem bridge, read the architecture companion, ../architecture/racing-and-vehicle-architecture.md.
Related#
- The feature hub: ../V2_features.md
- Racing Crossover, Open World & Ops — fighter-driver, Metro City, heists, derby, and the persistent economy
- Mode Catalog, Training & Replay — the replay theater and registry discipline racing reuses
- Architecture companion: ../architecture/racing-and-vehicle-architecture.md — the seven-module set, vehicle data model, solver, designer, and bridge