Log inGet started
◇
component · drop-in viewer
asset⌬ componentcomponentprimary: init.luau·originates fromworld b49f5634-1…

DriveGame

The Nürburgring car controller. It sits on the car root `nring_car`, which is the body of the scene's PlayerPrototype, so every joining player gets their own car.

byzero-proxy @ DESKTOP-DB3UJOJ·posted 4mo ago
What it does

DriveGame

The Nürburgring car controller. It sits on the car root nring_car, which is the body of the scene's PlayerPrototype, so every joining player gets their own car.

On the car this player owns it runs the pure-Luau vehicle physics (nring.physics, 240 Hz fixed step), lap and sector timing, the HUD (nring.hud) and settings panel, engine / tyre / wind audio, and poses the car's wheels, lights and cockpit through nring.carvis. Other players' cars are posed by replication; this component only voices their engine from the synced rpm / throttle fields.

Controls come from the nring_drive input map (keyboard, gamepad and touch for every control) and nring_shift while the manual gearbox is selected. The camera is the player camera's NringChaseCam behaviour.

Per-player best lap and settings are kept in runtime_data.player, the world lap record in runtime_data.world (nring/record).

Edit mode does nothing: the car template sits still in the editor.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

DriveGame: the Nürburgring car controller. Lives on the car root (`nring_car`), which the scene's PlayerPrototype clones for every joining player. The clone this peer owns is driven here: pure-Luau vehicle physics at 240 Hz (nring.physics, a port of esc5221/drive-game), lap timing, the HUD, engine audio and the car's visual pose. Other players' clones are posed by replication; this component only voices their engine from the synced rpm. Input comes from the `nring_drive` input map (keyboard, gamepad and touch for every control) and, with the manual gearbox, `nring_shift`. The camera is the player camera's NringChaseCam behaviour, which reads the local car through nring.gamestate.

Audio

flash(text: string, seconds: number?) → void

argtypedescription
textstring
secondsnumber?

stepTo(cur: number, target: number, rate: number, dt: number) → number

argtypedescription
curnumber
targetnumber
ratenumber
dtnumber

updateInput(dt: number) → void

argtypedescription
dtnumber

applyControls( ) → void

setView(v: string) → void

argtypedescription
vstring

invalidateRun( ) → void

a reset, a rewind or a restart spoils the lap and the BTG run in progress

recover(reason: string?) → void

argtypedescription
reasonstring?

rewindSteps(snapshots: number) → number

step the car back `snapshots` rewind slots; returns how many it went back

argtypedescription
snapshotsnumber

rewindJump( ) → void

one tap (HUD button, or Reset pressed and let go quickly): back 3 s, or back on track when there is nothing to rewind

updateRewind(dt: number) → boolean

held Reset: the car runs backwards through the ring at 1.5x until released. Returns true while the physics is paused for it.

argtypedescription
dtnumber

applyBrakeAssist( ) → void

braking assist: never faster into a corner than the racing line's target speed (which already carries its braking curve), looking a moment ahead for the brake to build

setManual(manual: boolean) → void

argtypedescription
manualboolean

setTc(on: boolean) → void

argtypedescription
onboolean

setAbs(on: boolean) → void

argtypedescription
onboolean

setQuality(q: string) → void

argtypedescription
qstring

othersOnMap( ) → void

snapshot( ) → void

showMenu(open: boolean) → void

argtypedescription
openboolean

refreshMenu( ) → void

initMapProj( ) → void

addLoop(name: string, clip: ?, volume: number, spatial: boolean) → void

argtypedescription
namestring
clip?
volumenumber
spatialboolean

setupAudio(spatial: boolean) → void

argtypedescription
spatialboolean

setIfChanged(src: ?, field: string, key: string, value: number, eps: number) → void

argtypedescription
src?
fieldstring
keystring
valuenumber
epsnumber

band(x: number, a: number, b: number) → number

argtypedescription
xnumber
anumber
bnumber

updateEngineAudio(rpm: number, throttle: number) → void

three engine layers crossfaded by rpm, each pitched from its own recording

argtypedescription
rpmnumber
throttlenumber

oneShot(clip: ?, volume: number, pitch: number?) → void

argtypedescription
clip?
volumenumber
pitchnumber?

updateAudio(dt: number) → void

argtypedescription
dtnumber

localName( ) → string

loadSaved( ) → void

saveGhost(store: ?, key: string, lap: ?) → void

best-effort save of a ghost lap (a large value; a refusal is logged, not fatal)

argtypedescription
store?
keystring
lap?

lapCompleted(r: ?) → void

argtypedescription
r?

ghostRef( ) → void

the ghost this player races: their best, or the track record holder's

updateGhostLap( ) → void

record the lap being driven, refresh the live delta, pose the ghost car

setGhostMode(mode: string) → void

argtypedescription
modestring

setLineMode(mode: string) → void

argtypedescription
modestring

setBrakeAssist(on: boolean) → void

argtypedescription
onboolean

setTimeOfDay(key: string) → void

time of day / weather: a per-player look preset (nothing synced)

argtypedescription
keystring

paceNote( ) → void

colourSector(i: number, t: number?, valid: boolean) → void

argtypedescription
inumber
tnumber?
validboolean

sectorTick(r: ?) → void

argtypedescription
r?

boardRows(prefix: string) → void

laps, nring/btg/<id> for Bridge to Gantry), so two players finishing at

argtypedescription
prefixstring

refreshBoard( ) → void

boardPosition(prefix: string, t: number) → number

where a time places on a board, counting everyone else's best (the write of this player's own new row may not have landed yet)

argtypedescription
prefixstring
tnumber

postToBoard(t: number) → void

argtypedescription
tnumber

btgTick(s0: number) → void

passing under the bridge starts the clock (interpolated back to the line)

argtypedescription
s0number

btgFinish( ) → void

the lap line is the gantry: stop the clock. Call before distAccum is zeroed (the anti-shortcut check reads it).

buildSummary(r: ?, prevBest: number?) → void

argtypedescription
r?
prevBestnumber?

titleSnapshot( ) → void

showTitle( ) → void

startCountdown( ) → void

restartLap( ) → void

countdownTick(dt: number) → void

start lights: one light every 0.9 s, all five out together after a random hold

argtypedescription
dtnumber

revOnTheLine(dt: number) → void

argtypedescription
dtnumber

updateMusic(dt: number) → void

argtypedescription
dtnumber

updateTags( ) → void

startDriver( ) → void

lapInvalid( ) → void

awake( ) → void

writeRoot( ) → void

adaptQuality(frameDt: number) → void

argtypedescription
frameDtnumber

update(engineDt: number) → void

argtypedescription
engineDtnumber

onCallback(id: string, _data: any) → void

argtypedescription
idstring
_dataany

onDestroy( ) → void

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

Showing up to 3 levels deep. Open a part to see what it holds further down.

34+items
▣
module · born here
❒asset
# nring_look The Nürburgring Drive environment look in one idempotent call, `apply()`, made from the main scene's `onEditLoad` and `onLoad`. Call it again after `renderer.setQualityTier(...)` or `setPreset(...)`. ## Presets (time of day / weather) ```lua local look = require("art.env.nring_look") look.setPreset("morning") -- unknown names fall back to "golden" look.apply() -- the next apply() uses the preset look.preset() --> "morning" ``` `M.PRESET_ORDER = { "golden", "midday", "morning", "overcast" }` and `M.PRESET_LABELS` (menu text) drive a picker. Each entry of `M.PRESETS` is a complete look: sun (azimuth/elevation/intensity/colour), sky fill, display exposure, bloom, vignette, grade, PhysicalAtmosphere, HeightFog, ProceduralSky (clock, turbidity, gradient), volumetric cloud preset (`clouds = nil` = clear sky), shadow-softness factor and optional sun shafts. `apply()` writes every field of every part, so switching presets back and forth leaves nothing of the previous one behind. Presets are a local look: nothing is replicated. - **golden** (default) — sun 24° from the WNW, warm; evening-blue dome warming to the horizon, lit cumulus, soft-edged shadows, warm haze. - **midday** — sun 58° from the SSW, neutral white; deep blue sky, white cumulus, crisp short shadows, light blue distance haze. - **morning** — sun 9° from the E, peach; clear sky, mist lying in the valleys (HeightFog dense at 360 m, gone by ~500 m) with sun shafts (VolumetricLighting) where the tier allows. - **overcast** — a full grey cloud deck, sun at 1.0 vs fill 1.9 (soft, nearly shadowless), grey dome, cool desaturated grade, grey haze. Each preset's grade is baked into its own LUT texture: `art/env/nring_grade_lut.texture` (golden), `nring_grade_lut_midday`, `_morning`, `_overcast`. After changing a grade run `look.bakeGradeLut("<preset>")` (or `"all"`) in edit mode. `M.SUN`, `M.GRADE`, ... still name the golden values. ## Quality tiers (`M.TIERS`) High: clouds, GTAO high, SSR, contact shadows, TAA, 96 MB shadow budget, sun shafts (24 steps), and a camera shutter motion blur (120°, 8 taps) in play only. Medium: smaller clouds, GTAO medium, FXAA, 12-step shafts. Low: no clouds, AO, SSR, contact shadows, shafts or motion blur; FXAA, 16 MB coarser shadows, 250 m caster cutoff. A clear-sky preset (morning) spends the cloud budget on shafts, so no preset costs more than golden at the same tier. ## Parts - **Light:** the scene's `sun` and `ambient`. `ProceduralSky` has `syncSunToLight` off, so its clock never overwrites the sun; it is the reflection environment and, with clouds, the backdrop behind them. - **Air:** `env_atmosphere` (PhysicalAtmosphere: aerial perspective, plus its own sky when there are no clouds), `env_fog` (HeightFog), `env_clouds` (VolumetricSky v4). In edit mode `bakeCloudsForEdit()` bakes the clouds once (the component only bakes from `update()`). - **Film:** `env_post` (PostProcess): ACES display at the preset's exposure, bloom, the preset's grade LUT, vignette. Every `env_*` entity is spawned `temporary`, so scene saves never duplicate them. References the look was matched against: `design/references/nring_look/`.
▲ 0↑ born
▣
module · born here
❒asset
# nring A module script.
▲ 0↑ born
▦
texture · born here
❒asset
▲ 0↑ born
▦
texture · born here
❒asset
▲ 0↑ born
◐
material · born here
❒asset
# [name] One-paragraph description of what surface look this material produces and where it's intended to be used. ## Shader Name the shader bound in `mat.yaml::shader` (e.g. `@builtin/shaders/standard` or a custom shader path). ## Inputs - `floats.<name>` — value, units, valid range. - `colors.<name>` — what colour channel/term it drives. - `textures.<name>` — what map slot it fills. Add more `floats:` / `colors:` / `textures:` keys as the shader exposes them. ## Usage ```luau Material.Apply(entityId, "[name]") ```
▲ 0↑ born
▦
texture · born here
❒asset
▲ 0↑ born
▦
texture · born here
❒asset
▲ 0↑ born
▦
texture · born here
❒asset
▲ 0↑ born
◐
material · born here
❒asset
▲ 0↑ born
◐
material · born here
❒asset
▲ 0↑ born
◐
material · born here
❒asset
▲ 0↑ born
◐
material · born here
❒asset
▲ 0↑ born
backing path · DriveGame.component

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported on this asset or on the parts this page shows. Parts it leaves out are not counted here.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.