# Police wanted level in your game (wanted.police) ## What it is for `wanted.police` keeps the police wanted level of an open-world game: the variable `wanted.level`, from 0 to `maxLevel`. The level rises when the player drives a stolen vehicle, enters a police zone while wanted, or runs over a civilian with their vehicle. It drops by one after `decaySeconds` without any officer seeing the player. For each level the kit keeps a number of officers alive (and a police car from level 2), who chase the player and arrest them when close and slow. The kit has no display module: the officers and the car use the models you bind, or capsules and a placeholder car until then. It also serves a small `faction.relations` matrix (police, civilians, player). ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "wanted.police" } gripforge_gamekit_configure { project_id: "gkp_…", id: "wanted.police", config: { "maxLevel": 3, "decaySeconds": 20, "spawnPerLevel": [0, 1, 2, 3] } } ``` It requires `npc.behavior`, `npc.perception` (from `npc.core`), `vehicle.enter` (from `vehicle.enter_exit`), `world.zones` and `game.engine`. Tag the zones that count as police zones `police` (or `police_zone`). Officers come from the `npcs` document with `faction: "police"` (a built-in one is used if there is none). Without `npc.behavior` there are no officers and the game is told. ## First example The level is moved with the service, always inside `0..maxLevel`, and every change says why: ```text wanted.level.add(1) // 1, wanted.changed { level: 1, previous: 0, reason: "heat", max: 3 } wanted.level.raise(5, "riot") // 3, held to the maximum, reason "riot" wanted.level.set(2) // 2, reason "set" wanted.level.clear("amnesty") // 0, wanted.changed then wanted.cleared ``` ## Settings and defaults | Setting | Type | Default | Meaning | |---|---|---|---| | `maxLevel` | integer 1-5 | `3` | number of stars | | `decaySeconds` | number | `20` | seconds out of sight before the level drops by one | | `heat.stolenVehicle` | integer 0-5 | `2` | stars for a stolen vehicle (a borrowed one costs nothing) | | `heat.enterPoliceZone` | integer 0-5 | `1` | stars for entering a police zone while wanted | | `heat.hitPedestrian` | integer 0-5 | `1` | stars for a civilian hit by the player's vehicle | | `chaserSpeed` | number | `1.1` | chaser speed, as a multiple of the player's run speed | | `spawnPerLevel` | integer[] | `[0, 1, 2, 3]` | officers kept alive per level index | Officers appear between 30 and 45 m from the player. A scene can override `heat`, `spawnPerLevel` and `decaySeconds`. ## Services, events, variables - `wanted.level` (service): `add(n, reason?)`, `raise(n, reason?)`, `set(n, reason?)`, `clear(reason?)`, `police()` (the officers alive, chasing or arresting), `max()`. Levels are clamped; a nonsense value is level 0. - `faction.relations` (service): `relation(a, b)` (`ally`, `neutral` or `hostile`), `hostile(a, b)`, `set(a, b, relation)`. The player and the police are hostile while the player is wanted. - Events: `wanted.changed` (`level`, `previous`, `reason`, `max`; reason is `stolenVehicle`, `enterPoliceZone`, `hitPedestrian`, `decay`, `arrested`, `var` for a write of the variable from elsewhere, or the caller's), `wanted.cleared`, `police.arrested` (`entity`, `by`). - Variable: `wanted.level` (guarded: a write from elsewhere is clamped and announced, and asks the hooks first). - Content: action `set_wanted`, condition `wanted_at_least`, NPC behaviours `chase` and `arrest`. ## Hooks and modding | Hook | Payload | What a tap may do | |---|---|---| | `wanted.raise` | `level`, `from`, `reason`, `max`, `entity` | change `level`, or cancel (nobody saw it) | | `wanted.lower` | `level`, `from`, `reason`, `max`, `entity` | change `level`, or cancel (the level stays, or the write is refused) | | `police.dispatch` | `level`, `count`, `alive`, `car` | change `count` (0 to 12), or cancel (nobody answers) | | `police.arrest` | `entity`, `by`, `level` | cancel: the player slips away | All the settings above are moddable. ## When it does not do what you expect - No officers come: `spawnPerLevel` is 0 at that level, `npc.behavior` is missing, or a `police.dispatch` tap cancelled. - The level never goes down: an officer still sees the player, or a `wanted.lower` tap cancels. - Entering a zone adds nothing: the zone is not tagged `police`, or the player is not wanted yet. - Officers are capsules: bind a rigged `police_officer` character asset; the car is the `police_car` asset. ## Limits Heat comes from three sources only; other crimes call `wanted.level.raise`. The arrest holds a slow player within 2.5 m for 2 seconds. ## Versions Kit version 1.5.0 (the guarded variable and the four hooks).