Skip to content

Bots

A compact recipe for adding a computer opponent. Full details in the Bots & behavior trees reference.

bots:
- id: chaser
name: "Chaser"
zoneId: play_area # home zone: spawns inside, stays inside
count: 1 # one chaser at game start
speedMps: 2
tunable:
- { key: speedMps, label: "Speed (m/s)", min: 0.5, max: 8, step: 0.5 }
- { key: count, label: "Chasers", min: 1, max: 10, step: 1 }
behavior:
kind: chase_nearest

That’s a working opponent: it spawns into its home zone at game start, heads for the nearest player every tick, and the GM can slide its speed or scale the pack with the count knob.

Switch behavior on the bot’s own state with a selector of guarded sequences, ending in wander as a safe fallback:

behavior:
kind: selector
children:
- kind: sequence
children:
- { kind: state_equals, key: it, value: true }
- { kind: chase_nearest, where: { key: it, value: false } }
- kind: sequence
children:
- { kind: state_equals, key: it, value: false }
- { kind: flee_nearest, where: { key: it, value: true } }
- { kind: wander }

Source: apps/wage-engine/src/games/tag/game.yaml. Because the bot reads the same it state humans do, your existing tag rule already controls it.

Trees only read state. To change a bot’s mind, write its state from a rule. Bots vs Humans flips a behavior string by health:

- id: bot_retreat_when_low
when:
kind: and
children:
- { kind: compare, who: { byTeam: red }, op: lte, left: { ref: same.state.health }, right: 30 }
- { kind: state_equals, who: same, key: behavior, value: chase }
do:
- { kind: set_state, target: same, key: behavior, value: retreat }

…and the tree dispatches on behavior:

behavior:
kind: selector
children:
- { kind: sequence, children: [ { kind: state_equals, key: behavior, value: chase }, { kind: chase_nearest, where: { key: human, value: true } } ] }
- { kind: sequence, children: [ { kind: state_equals, key: behavior, value: retreat }, { kind: flee_nearest, where: { key: human, value: true } } ] }

Source: apps/wage-engine/src/games/bots_vs_humans/game.json.

Pin humans to their team so joiners never land on the bot team:

teamAssignment: { humanTeamId: blue, botTeamId: red }