Pedestrian crowd
Usage guide of npc.pedestrian: ambient civilians on the sidewalks of a road network, fleeing fast vehicles, hit and knocked down by cars; settings and defaults, the pedestrian.ai service, the npc.hit event, the spawn and hit hooks, per-scene crowds.
A crowd of pedestrians for your city (npc.pedestrian) #
Civilians who walk the sidewalks, run from fast vehicles and can be hit by them. The NPC documents, behaviours and perception they are built on are described in the NPC guide. Readable offline: gripforge docs npc-pedestrian, or the MCP tool gripforge_docs (topic npc-pedestrian).
What it is for #
npc.pedestrian fills a city with ordinary npc.core NPCs (faction civilian, behaviours wander, flee and idle), placed on the sidewalk nodes of world.roads once world.ready fires, and keeps count of them alive (a replacement is placed 20 seconds after one is removed). It turns vehicle danger into behaviour: a vehicle faster than 20 km/h within fleeRadius makes the civilians around it flee; a vehicle that sweeps through one, or a vehicle.collided with one, hurts it (speed x 5 health), throws the body and panics everyone within fleeRadius. It does not drive vehicles, run police or score anything: other kits read the npc.hit event for that. Its presentation module draws the blood of a hit pedestrian (droplets and ground stains) when bloodEffects is on.
Turn it on #
gripforge_gamekit_install { project_id: "gkp_…", id: "npc.pedestrian" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "npc.pedestrian",
config: { "count": 20, "fleeRadius": 10 } }
It requires npc.behavior (so npc.core), world.roads and game.engine. The model comes from the asset slot pedestrian (a rigged character, several allowed, picked at random); until one is bound a capsule is drawn.
First example #
<!-- test: kits/game_engine/host/tests/parity.rs::rust_host_matches_the_typescript_traces --> The fixture npc.pedestrian.hooks of that test plays five pedestrians on eight sidewalk nodes and these rules, which a game or a mod declares as data:
{ "id": "curfew", "hook": "pedestrian.spawn", "match": { "reason": "replace" },
"if": [ { "var": "city.curfew", "op": "==", "value": true } ], "cancel": true, "reason": "curfew" }
{ "id": "truce", "hook": "pedestrian.hit",
"if": [ { "var": "city.truce", "op": "==", "value": true } ], "cancel": true, "reason": "truce" }
{ "id": "soft_bumpers", "hook": "pedestrian.hit",
"if": [ { "var": "city.soft", "op": "==", "value": true } ], "mul": { "damage": 0.5 } }
While city.curfew is true no replacement pedestrian is placed; while city.truce is true a vehicle hurts nobody and nobody panics; with city.soft the damage of a hit is halved.
Settings and defaults #
| Setting | Type | Default | Meaning |
|---|---|---|---|
count | integer, 0 to 64 | 12 | pedestrians kept alive |
walkSpeed | number, 0.5 to 4 | 1.5 | walking speed, m/s |
fleeSpeed | number, 1 to 10 | 4 | running speed when fleeing, m/s |
fleeRadius | number, 2 to 30 | 8 | metres around a fast vehicle (or an impact) within which civilians flee |
vehicleImpacts | boolean | true | continuous car and pedestrian hit detection, knockdown and recovery |
bloodEffects | boolean | false | stylized droplets and temporary ground stains on impacts |
bodyLifetime | number, 1 to 30 | 8 | seconds a pedestrian killed by a hit stays visible |
localPopulation | boolean | false | keep the crowd around the controlled player or vehicle in a large world |
populationRadius | number, 40 to 300 | 100 | metres of the local crowd |
recycleRadius | number, 80 to 600 | 180 | beyond this distance a pedestrian is moved nearer the player |
All of them are open to mods, except bloodEffects, which stays the game's own choice. A scene can override count and fleeRadius in its layer for this kit; leaving a scene removes its crowd and entering the next one places a new crowd.
Services, events, hooks #
pedestrian.ai(service):pedestrians()the ids of the living pedestrians,panic(at, radius, from?)makes the civilians around a point flee and answers how many.npc.hit(event):{ npc, entity, by, speed, position, direction, lethal, blood }, a vehiclebyhit a civilian atspeedm/s;bloodis true whenbloodEffectsis on and the impact is at least 3 m/s. A wanted-level kit uses it as a heat source.vehicle.speed,vehicle.collided,world.ready,npc.despawned(events listened to).pedestrian.spawn(hook):{ reason, x, y, z }before a pedestrian is placed;reasoniscrowd,replaceorrecycle; cancellable.pedestrian.hit(hook):{ npc, by, speed, damage }before an impact is applied, at most once a second for the same pair;damageis mutable; cancellable (no damage, no knockdown, no panic).
Hooks and modding #
Rules like the ones above can be added by a game or a mod; a mod can also change the settings listed as moddable (for example a smaller count). A value out of range is clamped or refused by the kit validation.
Engines #
The crowd logic is the same Rust code on the web, natively and in the engine wrappers; the model, animation and blood are drawn by each engine from the npc.impact state and the npc.hit event.
When it does not do what you expect #
- No pedestrians: the world has no road network or no sidewalk nodes (the log says
world.roads has no sidewalk nodes),npc.behavioris not installed, orcountis 0. Without a model bound to thepedestrianslot a capsule is drawn and the project is not reported playable. - Pedestrians never run: the vehicle is slower than 20 km/h, farther than
fleeRadius, or does not publishvehicle.speed. - A pedestrian is never hit:
vehicleImpactsis off, the speed is below the impact threshold, or apedestrian.hittap cancels it. - A killed pedestrian comes back: the kit replaces it after 20 seconds to keep
countalive.
Limits #
The crowd lives on the sidewalk nodes of world.roads; it does not cross roads by itself, enter buildings or react to anything other than vehicles. Wanted levels, police and scoring belong to other kits.
Versions #
Kit 1.7.0; service pedestrian.ai 1.0.0. 1.7.0 added the pedestrian.spawn and pedestrian.hit hooks.