# Skirmish bots (bots.skirmish) ## What it is for Bots on foot for a free-for-all: each one is an NPC of `npc.core` with its own team and health, tagged as a contestant. They head for the safe zone (`zone.shrink`) when the edge closes on them, hunt the nearest contestant they see (the player or another bot), strafe at mid range and shoot in bursts through `combat.ranged` after a reaction delay. Battle royale bots, deathmatch fodder, arena rivals. It requires `npc.behavior`, `combat.ranged`, `combat.health` and `game.engine`. `zone.shrink` is optional (bots keep inside the running storm zone; without it, inside `roamRadius` around `center`) and so is `match.knockout` (bots wait for its countdown). The bot model is the asset `bot_character`, a rigged character with idle, run and shoot clips. ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "bots.skirmish" } gripforge_gamekit_configure { project_id: "gkp_…", id: "bots.skirmish", config: { "count": 7, "reaction": 0.8, "aimError": 0.1 } } ``` ## First example Bots are listed, a target is set and checked through the `ai.tactical` service: it is refused for the bot itself, a ghost, a non-string or a stranger, unchanged on refusal, and cleared with null. ```text ai.tactical.target(a) -> null ai.tactical.setTarget(a, b) -> true ai.tactical.target(a) -> b ai.tactical.setTarget(a, a) -> false setTarget(a, "ghost") -> false setTarget(a, 3) -> false ai.tactical.setTarget(a, null) -> true ai.tactical.target(a) -> null ``` ## Settings and defaults | Setting | Default | Meaning | |---|---|---| | `count` | 11 | Bots spawned when the game starts (0 to 64) | | `tags` | `["contestant"]` | Tags every bot carries (`match.knockout` and `zone.shrink` watch `contestant`) | | `center` | `[0, 0]` | `[x, z]` the bots spawn and roam around | | `spawnRadius` | 60 | Bots spawn at random within this radius of `center` | | `roamRadius` | 80 | The area bots keep inside when no `zone.shrink` is running | | `health` | 100 | Health of each bot | | `speed` | 5 | Walking speed (m/s); they run at 1.6 times this towards the zone | | `sight` | 58 | How far a bot sees a target | | `engage` | 36 | Closer than this a bot strafes and shoots; farther it closes in | | `zoneMargin` | 12 | A bot this close to the zone edge runs to its centre | | `reaction` | 1.2 | Seconds between seeing a new target and the first shot | | `burst` | 0.35 | Seconds a bot holds the trigger | | `pause` | 1 | Seconds between two bursts | | `aimError` | 0.06 | Yaw error of a bot shot (radians, random ±) | | `think` | 0.25 | Seconds between two choices of a target | A game or a mod may change every setting except `tags` and `center`. ## Services - `bots()` lists the bots as `{ entity, name, target }` (names are `Bot 01`, `Bot 02`…). - `target(bot)` reads a bot’s target (null when none); `setTarget(bot, entity | null)` sets or clears it and answers whether it was accepted. - `spawnBots(n?)` spawns bots on demand (without it the bots are spawned once, when the game is ready). ## Events | Name | Detail | |---|---| | `bots.spawned` | The bots are in the game; payload `{ bots }`, the list of their entities. | | `bots.targeted` | A bot changed its target; payload `{ bot, target }` (an empty target means none). | ## Hooks and modding A game or a mod taps a hook with a document of its `hooks` list, without touching the kit: - `bots.target`: before a bot hunts the nearest contestant it sees; payload `{ bot, target, distance }`; a tap may name another contestant in `target`; cancelled, the bot keeps no target and roams until its next choice. - `bots.fire`: before a bot starts a burst at its target (once per burst, not per shot); payload `{ bot, target, yaw, pitch }` with its aim, error included; a tap may change `yaw` and `pitch`; cancelled, no burst this time and the bot waits its `pause`. ```json { "id": "blind_bots", "hook": "bots.fire", "cancel": true, "reason": "lights out" } ``` ## When it does not do what you expect - No bot appears and the log warns `needs npc.behavior`: install `npc.behavior` (and `combat.ranged`), the bots are handed to it at start. - Bots stand still or drift out of the arena: no `zone.shrink` is running and `roamRadius` around `center` does not match the map; set both. ## Limits - Bots are NPCs of `npc.core`: their movement, health and shooting come from the kits above; this kit only chooses where they go, whom they hunt and when they fire. They do not form teams, drive vehicles or use cover. - Bots and their targets are saved with the game: a load does not spawn a second team. Targets web and native players. ## Versions 1.0.0 (2026-10-10): first release, with the hooks `bots.target` and `bots.fire`.