Fighting Game · Features

Racing Component: Vehicles, Modes & Online

A focused page within the Fighting Game Features documentation. The full map and every sibling page live in the Features hub.

6sections13 minread1diagram1table

On this page
classDiagram class RaceModeDefinition { rules laps authorityPolicy } class VehicleDataAsset { class tuningVersion customization } class RacePhysicsFrame { fixedStep inputs contacts } class TrackDefinition { route hazards checkpoints } class OnlineRaceReceipt { result replayRef integrityRef } RaceModeDefinition --> VehicleDataAsset : permits RaceModeDefinition --> TrackDefinition : configures VehicleDataAsset --> RacePhysicsFrame : parameterizes TrackDefinition --> RacePhysicsFrame : constrains RacePhysicsFrame --> OnlineRaceReceipt : produces

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 modesRacing.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. MakeRaceMode synthesizes each definition's GameFeaturePluginURL and PrimaryMapPath by convention (BuildRacePluginURL, BuildRaceMapPath); no V2Race_*.uplugin directory and no race .uasset binaries 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 / UChaosVehicleMovementComponent across V2/ue/Source returns 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. UV2VehicleAudioSubsystem and UV2VehicleVFXSubsystem are 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 EV2RaceNetworkModelOffline, 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:

text
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.CircuitFinishOrder, client-server, 12 drivers, 3 laps.
  • Race.Drag.QuarterMileBestElapsedTime with bRequiresPerfectLaunch, 4 drivers.
  • Race.DriftDriftScore, 8 drivers; Race.CanyonDuelCanyonLeadDistance, 2 drivers.
  • Race.TimeTrial and Race.Rally.StageAsyncGhost (race against a ghost, not a live field).
  • Race.CustomRoom — up to 32 players with combat, power-plays, and pursuit all host-toggleable (tag CrossPlay32).
  • Race.Pursuit.Evade / Race.CopsVsRacersPursuitEscape with pursuit AI; Race.Combat.Blur / Race.DeathRaceCombatTakedown with 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 FV2RacingComplianceCertCatalogFV2RacingAntiCheatGateSpec: 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.