Skirmish bots
Usage guide of bots.skirmish: free-for-all bots on foot that keep inside the safe zone, hunt the nearest contestant and shoot in bursts, with settings, the ai.tactical service, events and hooks.
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 #
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 #
<!-- test: kits/bots_skirmish/tests/bots_skirmish.rs::a_target_is_set_checked_and_cleared --> 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.
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 areBot 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 intarget; 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 changeyawandpitch; cancelled, no burst this time and the bot waits itspause.
{ "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: installnpc.behavior(andcombat.ranged), the bots are handed to it at start. - Bots stand still or drift out of the arena: no
zone.shrinkis running androamRadiusaroundcenterdoes 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.