# 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](guide:npcs). 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 ```text 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 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: ```json { "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 vehicle `by` hit a civilian at `speed` m/s; `blood` is true when `bloodEffects` is 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; `reason` is `crowd`, `replace` or `recycle`; cancellable. - `pedestrian.hit` (hook): `{ npc, by, speed, damage }` before an impact is applied, at most once a second for the same pair; `damage` is 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.behavior` is not installed, or `count` is 0. Without a model bound to the `pedestrian` slot 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 publish `vehicle.speed`. - A pedestrian is never hit: `vehicleImpacts` is off, the speed is below the impact threshold, or a `pedestrian.hit` tap cancels it. - A killed pedestrian comes back: the kit replaces it after 20 seconds to keep `count` alive. ## 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.