Build with Yuka Kit

Building game AI

Keep game ownership explicit while composing deterministic Yuka Kit primitives.

Create an entity manager and brain registry per game world rather than using global state. Each frame, update the game-owned observations first, then call stepAI with the frame delta. This keeps combat FSM updates, steering, and brain arbitration in a predictable order.

import {
  BrainRegistry,
  ChaseEvaluator,
  createBrain,
  createCombatVehicle,
  createEntityManager,
  createVehicle,
  manage,
  setHealthPct,
  setTargetPosition,
  stepAI,
} from 'yuka-kit';

const manager = createEntityManager();
const brains = new BrainRegistry();
const player = createVehicle({ speed: 4 });
const enemy = createCombatVehicle({ speed: 3 }, { target: player });
const brain = createBrain(enemy, [new ChaseEvaluator()]);
manage(manager, enemy);
brains.register('goblin-01', brain);

// Refresh target and health observations from the game before stepping AI.
setTargetPosition(enemy, player.position);
setHealthPct(enemy, enemy.health / enemy.maxHealth);
stepAI(manager, deltaSeconds, brains);

Use TacticalCombatAgent and BossTacticalAgent to decide intents. The game executes those intents; it remains responsible for damage, spawning, collision, animation, and presentation. This separation keeps gameplay authored locally while allowing decision behavior to be tested independently.

Brain lifecycle

Registering a different brain under an existing entity ID terminates the old brain, including its active subgoals, before replacing it. Registering the same brain under that ID again is a no-op. unregister and reset terminate the brains they remove.

BossBrain requires at least one phase. Health thresholds must be finite numbers between zero and one, in strictly descending order. Invalid phase configuration throws before the owner receives any brain or phase tags.

GOAP snapshots must agree with their progress: active plans need a remaining action, completed plans have consumed all actions, and failed plans carry no plan progress. Already-satisfied goals may complete with an empty plan. Invalid snapshots are rejected before an existing executor is changed.

Intent boundary

TacticalCombatAgent and BossTacticalAgent return command-neutral AgentIntent values such as move-to, move-away, action, transfer-map, stop, and wait. Treat that return value as a proposal, validate it in your game's authority layer, then execute it there. The library never applies damage, spawns an actor, changes a map, or plays an animation on its own.