Ground tracks

Leave boot prints, wheel ruts and drag strips on snow and on soft surfaces you declare as data (sand, mud, dust, ash): settings, trail component, services, events, the tracks.slow and tracks.clear hooks.

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

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

Footprints, ruts and ground marks (world.tracks) #

What it is for #

world.tracks keeps every mark left on the ground: boot prints, tyre ruts and drag strips. Snow is the default material: alternating prints and ruts pressed into the snow layer, refilled by snowfall when world.weather is installed. Soft surfaces declared as data (sand, mud, dust, ash) take the contacts that land on them with their own colour, depth, lifetime, ceiling, dust, speed factor and step sound. Marks fade with time and weather and are saved with the game. A game that declares no surface keeps the snow behaviour.

Each contact goes to exactly one place: the declared surface under it (highest priority first); else snow, where there is snow (with world.weather, where it lays snow; without it, only when no surface is declared); else nothing, the ground is hard.

Turn it on #

{ "id": "world.tracks", "config": { "lifetime": 240, "wheelRuts": true } }

It requires game.engine. Optional companions: world.weather (snowfall fills prints, rain and melting clear them, wind, rain and snow wear surface marks faster), world.ground (ground height of prints), and world.terrain, world.biomes and zones, which a surface can be bound to. It conflicts with world.fluids in the same scene.

First example #

<!-- test: kits/game_engine/host/tests/parity.rs::rust_host_matches_the_typescript_traces (fixture world.tracks.surfaces) --> The fixture declares a mud surface bound to a zone, with a colour, opacity: 0.8, depth: 0.9, lifetime: 6, maxMarks: 12 and slow: 0.5, and a sand surface bound to a height band. It creates a player, a vehicle and a sled carrying { "type": "drag", "width": 0.5 }, steps once, then reads surfaces(), surfaceAt(x, z) and marks(). Prints, tyre ruts and a drag strip are left on the declared surface under each entity, and a point on hard ground answers null.

Settings and defaults #

SettingTypeDefaultMeaning
enabledbooleantrueMake and draw marks.
autoContactsbooleantrueMake prints from feet and wheels; false leaves only contacts sent by other kits.
includeNpcsbooleantrueNPCs in range leave prints too.
playerbooleantrueThe player leaves prints.
stridenumber 0.25-1.50.62Metres between two prints.
footWidthnumber0.18Print width, metres.
footLengthnumber0.32Print length, metres.
footSpacingnumber0.12Metres between the centre line and each foot.
wheelRutsbooleantrueVehicles (tagged vehicle) leave ruts behind the rear wheels.
rutSpacingnumber0.9Metres between two rut segments.
wheelWidthnumber0.24Rut width, metres.
gaugenumber0Metres between the two ruts; 0 is 84 % of the vehicle width.
lifetimenumber 10-1800180Seconds a snow print lasts without world.weather.
maxTracksinteger2048Snow prints kept; the oldest goes first.
simulationRangenumber 10-10040Only walkers within this range of the player leave marks.
maxMarksinteger600Marks alive on declared surfaces.
intensitynumber 0-11Strength of marks; 0 leaves none and hides the ones left.
fadenumber 0.05-201Fading speed multiplier.
weathernumber 0-51How much weather speeds up fading of surface marks; 0 is not at all.
surfacesarray (max 32)[]Soft surfaces; also read from the trail_surfaces collection.

A surface is { id, name, layers, biomes, zones, minHeight, maxHeight, maxSlope, priority, color, opacity, depth, lifetime, maxMarks, dust, slow, sound }. Every criterion given must hold; a surface with none covers everything. opacity defaults to 0.6, depth to 0.5, lifetime to 90, dust to true; slow is a speed multiplier (0.7 for deep sand).

Any entity may carry the trail component { type, stride?, width?, gauge? } with type one of feet, wheels, drag or none (none stops the default marks; drag leaves one strip behind the body).

Services, events, hooks #

  • world.tracks (service): marks() lists live surface marks (id, x, y, z, yaw, kind, side, width, length, alpha, color, depth, surface, entity); surfaceAt(x, z) returns the declared surface, snow, or null; surfaces(); emitters(); snapshot(); contact(c); reset() (wipes without asking); clear() (asks tracks.clear, returns the count); fadeRate(); version().
  • world.tracks.settings (service): keys(), get(key), set(key, value) for intensity and fade, for world.bindings.
  • tracks.step (event): { entity, surface, kind, x, z, sound } for each print or drag segment when surfaces are declared; for step sounds. Wheel ruts do not emit it.
  • tracks.cleared (event): { count } after clear().
  • Listened: surface.footstep (an explicit snow contact), surface.tracks.reset, entity.spawned.
  • tracks.slow (hook): { entity, type, surface, factor }; mutable factor (0.05-1); cancellable (the entity is not slowed). Asked when the factor of an entity changes, never while it stays.
  • tracks.clear (hook): { count }; cancellable (nothing wiped, clear() answers 0).

On a surface whose slow is under 1, vehicles driven through vehicle.drive get that multiplier on top speed and acceleration, and the player too when its character kit serves speed factors. Snow does not slow.

Hooks and modding #

A mod may override the config (except surfaces and maxTracks) and add, patch or remove documents of trail_surfaces:

{ "id": "snowshoes", "hook": "tracks.slow", "match": { "type": "feet" }, "set": { "factor": 0.9 } }

Engines #

Snow prints are drawn on the web, Godot, Unity and Unreal from the same contact history. Declared surfaces, their marks, the trail component, slowing and the live settings are web and Rust only for now; the other engines ignore them. Textures bound to the slots trail_foot and trail_wheel replace the drawn print and strip.

When it does not do what you expect #

  • No marks: enabled is false, intensity is 0, the walker is idle, airborne or seated, or it is farther than simulationRange.
  • No print on snow: without world.weather and with a surface declared, snow is not assumed; with it, there is no snow there.
  • Marks never end: lifetime is long and weather is calm; raise fade.
  • A surface never matches: one of its criteria fails, or a higher priority surface wins.

Limits #

It never adds collision geometry. Marks follow ground contacts only: no jump or teleport streaks.

Versions #

Kit 1.4.0; it provides world.tracks 1.3.0 and requires game.engine@^1. Surfaces, the trail component and the settings date from 1.3.0; the hooks from 1.4.0.