# Civilian traffic (traffic.system) ## What it is for `traffic.system` makes civilian cars drive around a city. Each car follows the road graph of `world.roads` in its right-hand lane, picks a direction at every junction (straight on first, then a random turn, a U-turn only at a dead end), waits when another car holds the crossing, brakes for the player, pedestrians and cars ahead, and overtakes a stopped obstacle by the left. Cars far from the player are moved back near it, so a small pool looks like a busy street. The cars are driven through `vehicle.drive`; the kit has no display module and draws nothing. ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "traffic.system" } gripforge_gamekit_configure { project_id: "gkp_…", id: "traffic.system", config: { "density": 0.8, "maxVehicles": 10 } } ``` It requires `vehicle.drive`, `world.roads`, `spawn.entities` and `game.engine`. The road graph is the `lanes()` of the world when it has them, otherwise a grid rebuilt from `roadNodes()` by joining aligned neighbours. A world without roads gets no cars. Traffic car models are the assets `traffic_vehicles` (picked at random), then `vehicle_variants`, then `vehicle_default`. ## First example The number of cars on the road is `density` times `maxVehicles`, capped at 64: | Config | Cars | |---|---| | `{}` (defaults) | 3 | | `{ "density": 1 }` | 6 | | `{ "density": 0 }` | 0 | | `{ "density": 0.5, "maxVehicles": 10 }` | 5 | | `{ "density": 1, "maxVehicles": 500 }` | 64 | Every car is an entity of kind `vehicle` tagged `traffic` and `civilian`, announced by `traffic.spawned`. ## Settings and defaults | Setting | Type | Default | Meaning | |---|---|---|---| | `density` | number | `0.5` | Fraction of `maxVehicles` kept on the road (0 to 1). | | `maxVehicles` | integer | `6` | Traffic cars alive at once (0 to 64). They count against the vehicle limit of `vehicle.drive`: leave room for the player's cars. | | `speed` | number | `9` | Cruise speed, m/s (2 to 30). | | `obeySignals` | boolean | `true` | Stop before a crossing another car holds. | | `spawnRadius` | number | `70` | Cars appear at most this far from the player, metres (20 to 300). | | `despawnRadius` | number | `140` | Cars farther than this are recycled near the player (40 to 600). | A scene can set its own `density`, `speed` and `obeySignals` (in `layers["traffic.system"]` of the scene): leaving a scene removes its cars, entering the next one rebuilds the graph from its roads and fills it again. ## Service methods Service `traffic.vehicles`: - `vehicles()`: the ids of the traffic cars. - `setDensity(n)`: change the density, clamped to 0 to 1 (a non-number changes nothing). It is kept in the save. - `stopAll()`: halt every car. `resume()`: let them go again. ## Events and hooks - `traffic.spawned { entity }`: a car appeared. - `traffic.blocked { entity, by }`: a car was held by the same obstacle for three seconds. - The kit listens to `vehicle.collided` (the cars involved are held for a while), `vehicle.destroyed` (a wreck leaves the pool and is replaced after a delay), `vehicle.entered` (a car the player takes leaves the pool) and `world.ready`. - Hook `traffic.spawn`: asked once per spawn attempt, with `{ reason, from, to, x, y, z, yaw, archetype, variant, speed, count }`. `reason` is `fill` (the pool is below its target) or `replace` (a wreck or stolen car is replaced). Mutable: `speed`, the cruise speed of that car (a slow truck, a hurried taxi; kept in the save). Cancellable: no car appears, as for a failed spawn; a fill is tried again two seconds later on another lane. ```json { "id": "slow_fill", "hook": "traffic.spawn", "match": { "reason": "fill" }, "set": { "speed": 5 } } ``` ## Hooks and modding All six settings are moddable. A mod can slow some cars or forbid a spawn with the `traffic.spawn` hook; it cannot change the lane, the place or the look, which are already drawn. ## Engines Web, native player, Godot, Unity and Unreal run the same lane graph, waypoint driving, crossing hold, braking and recycling. The `traffic.spawn` hook runs on the web and in the native player. ## When it does not do what you expect - No car at all: `density` is 0, the world has no roads, or `vehicle.drive` has no room (`maxVehicles` of that kit is reached). - Fewer cars than expected: the pool is `density` times `maxVehicles`; raise either. - Cars stop at a crossing: another car holds it, or a collision holds them for a while. Set `obeySignals` to `false` to drive through. - A car the player takes is no longer traffic: it leaves the pool and a replacement appears after a delay. ## Limits The kit does not spawn pedestrians and draws nothing: the cars only follow the lane graph and react to what is in front of them. ## Versions Kit version 1.3.0 (the `traffic.spawn` hook and moddable settings); 1.2.0 attached traffic to the scenes; 1.1.0 added the Godot, Unity and Unreal deliveries; first runtime in 1.0.0.