Race circuit

Build a closed race circuit from a spline: arc-length sampling, road collider, ground, village and props, race_tracks documents, settings and the racetrack.build hook.

Source: module-kits:kits/world_racetrack/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs world-racetrackMCP tool: gripforge_docs { "topic": "world-racetrack" }

Race circuits in your game (world.racetrack) #

What it is for #

world.racetrack builds a closed circuit from a spline: the road and its collider, the landscape around it, and replaceable props such as houses, palms and rocks. It samples the circuit by distance so the race, the AI, the minimap and the renderer all share one centre line. It serves world.ground to vehicles and world.racetrack to race logic. The engine draws the circuit from this data.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "world.racetrack" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "world.racetrack",
                              config: { "trackId": "harbour_loop", "buildings": "library" } }

It requires physics.rigidbody, physics.port and game.engine. Without a race_tracks document, the built-in Coral circuit is played. A scene whose world names this kit builds the circuit its document names.

First example #

<!-- test: kits/game_engine/host/tests/world_racetrack.rs::a_project_without_tracks_plays_the_coral_circuit --> In a project without tracks, the service answers with the Coral circuit:

{ "op": "call", "service": "world.racetrack", "method": "track", "args": [] }

It returns the document with id coral_circuit; samples returns 512 arc-length samples, and world.ground.defaultSpawn gives a spawn that nearest finds on the road, at distance 0. A saved game records trackId and resolution.

Settings and defaults #

SettingTypeDefaultMeaning
trackIdstringcoral_circuitrace_tracks document to build.
buildingsstringproceduralprocedural, library or none.
scenerystringcoastalcoastal art set or library prop scatter.
resolutioninteger512Arc-length samples of the centre line, 64 to 4096.
shouldernumber5Collision shoulder added to the road width, metres.
groundMarginnumber55World bounds beyond the farthest point, metres.
ceilingnumber80Top of the world bounds, metres.
spawnTnumber-0.015Track fraction of the default spawn.
maxBuildingsinteger128Upper bound of race_buildings instances.
scatterobjectcount 64, offset 7, spacing 4Library prop scatter: count, distance from the road edge, row step.
villageobjectsee belowDefault village when race_buildings is absent (buildings: library).

village has houses (26), start (-0.034), spacing (0.0092), setback (9), jitter (3), clearance (6), width (7.4), widthJitter (1.4) and cafeEvery (3). Everything except resolution and maxBuildings is moddable.

Services, events and data #

  • world.racetrack (service): track, length, samples, sample(t, lateral) (point at fraction t, wrapped, shifted sideways), nearest(x, z) (fraction, distance and signed lateral offset), village.
  • world.ground (service): bounds, inside, defaultSpawn, and the height on the road.
  • world.ready (event): the road, ground and props exist; payload { track }. It fires again when another circuit is built.
  • race_tracks (collection): { id, name, width (8 to 30 m), laps (1 to 9), points (4 to 64 [x, z]), boostPads, crates, elevations?, regions? }. The length must be 80 to 4000 metres.
  • race_buildings (collection): { id, slot, position, yaw, width } with slot race_house_a or race_house_b.

Asset slots: race_house_a, race_house_b, race_palm, race_rock, race_crate, race_grass_texture, race_track_texture.

Hooks and modding #

racetrack.build (hook): asked once per build, with scene, track, buildings and scenery; a mod may change the last three (an unknown track id keeps the original). It is not cancellable. A mod can also add race_tracks and race_buildings documents and set the moddable settings.

{ "id": "no_buildings_in_time_trial", "hook": "racetrack.build",
  "if": [{ "var": "race.mode", "op": "==", "value": "time_trial" }], "set": { "buildings": "none" } }

When it does not do what you expect #

  • The circuit is refused: the width is under 8 m, the length outside 80 to 4000 m, or elevations does not match the points.
  • The wrong circuit is built: trackId is unknown, so the first document is used.
  • No houses appear: buildings is none, or a lot in a bend is closer than clearance.
  • Props show as boxes: no Library model is bound to the slot.

Limits #

The kit builds geometry and data; it holds no race rules (laps, positions, items belong to the race kits). It does not render: the circuit is drawn by the engine.

Versions #

Kit 1.7.0 adds the racetrack.build hook and declares the moddable settings and collections. 1.6.0 attaches the kit to game.engine scenes.