audio-design
Engine-neutral game audio technique: bus layout, volume sliders in decibels, loudness, ducking music under dialogue, adaptive…
Engine-neutral behavior tree and utility AI code for NPCs in any language: Blackboard, reactive composites, decorators and response-curve scoring. Use when an enemy keeps chasing after losing sight, restarts its action every frame or flip-flops between choices. Not for FSMs,
Claude Code
$ npx -y skills add gamedev-skills/awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai --agent claude-code
Codex
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai -a codex -y
Cursor
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai -a cursor -y
Gemini CLI
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai -a gemini-cli -y
GitHub Copilot
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai -a github-copilot -y
OpenCode
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai -a opencode -y
Windsurf
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai -a windsurf -y
name: ai-behavior-trees-utility-ai description: > Engine-neutral behavior tree and utility AI code for NPCs in any language: Blackboard, reactive composites, decorators and response-curve scoring. Use when an enemy keeps chasing after losing sight, restarts its action every frame or flip-flops between choices. Not for FSMs, steering or pathfinding (`game-ai`) or Unreal BT, EQS and StateTree (`unreal-behavior-trees`).
A behavior tree (BT) gives an agent ordered, interruptible priorities; Utility AI scores every option and picks the most wanted one. The code is plain C# so it ports to any engine; the non-obvious part is the lifecycle contract (who resets what, and when), which is where almost every BT bug lives.
**Not this skill:** choosing FSM vs BT, steering, A*, flow fields and perception belong to `game-ai`. Unreal's `BehaviorTree`/`Blackboard` assets, `BTTask`/`BTService`, EQS and StateTree belong to `unreal-behavior-trees`. The agent that physically moves (`NavMeshAgent`, `NavigationAgent3D`) belongs to the engine navigation skill.
1. **Read what exists.** Find the current AI code, its tick site and how it reads the world. If the project already ships a BT plugin (Godot LimboAI or Beehave, Unity Behavior, NodeCanvas), extend it instead of adding a second runtime. 2. **Pick the default shape: BT outside, utility inside.** The BT decides engage, flee or patrol; a utility node inside the engage branch picks how. Use utility at the top only when every top-level behavior is a graded trade-off (needs-driven villagers), because it is harder to debug and prone to thrashing. 3. **Design the Blackboard first.** Perception writes facts (`targetPos`, `health01`, `distToPlayer`); leaves read them. Nodes never hold references to each other. 4. **Choose memory or reactive per composite.** Priority selectors at the top are reactive so a higher branch can preempt; a `Sequence` whose first child is a guard condition must be a `ReactiveSequence`, or the guard stops being checked once the action runs. 5. **Normalize every utility input to 0..1** through a curve before combining; multiply with compensation so a 0 still vetoes. 6. **Tick on a decision cadence** (5-15 Hz for most NPCs) from an accumulator, staggered across agents. Movement and animation still run every frame. 7. **Prove it with a headless tick test** (below): script the Blackboard, tick N times and assert the status sequence and reset counts. Then draw the running leaf and per-action scores on screen while tuning.
Every node returns `Success`, `Failure` or `Running`. Parents reset a child as soon as it returns a terminal status and when they abandon it while `Running`; the tree resets a terminal root. `Reset()` must be idempotent and must clear only execution-local state (timers, reservations), never persistent state such as a cooldown deadline.
// Selector = fallback/OR: return the first child that is not Failure.
// `Current` (from Composite) remembers a Running child so the next tick resumes there.
public sealed class Selector : Composite
{
public override Status Tick(Blackboard bb, float dt)
{
for (; Current < Children.Count; Current++)
{
var s = Children[Current].Tick(bb, dt);
if (s == Status.Running) return Status.Running; // resume here next tick
Children[Current].Reset(); // terminal child can re-enter cleanly
if (s == Status.Success) { Current = 0; return Status.Success; }
}
Current = 0;
return Status.Failure; // every child failed
}
}This is the memory variant: it cannot be preempted. `Sequence`, `ReactiveSelector`, `ReactiveSequence`, `Parallel`, the decorators and `BehaviorTree` follow the same contract in `references/behavior-tree-core.md`.
// A consideration maps one raw fact to 0..1 through a response curve.
float Score(Blackboard bb)
{
float distance01 = Curves.InverseLerp01(bb.Get<float>("distToPlayer"), 20f, 2f); // near = 1
float health01 = Curves.Sigmoid(bb.Get<float>("health01"), k: 8f, mid: 0.4f); // hurt = low
// A 0 in any factor still vetoes the action; compensation stops each extra
// consideration from dragging every score toward 0. No allocation per call.
return Curves.Compensate(distance01 * health01, count: 2);
}Selection: argmax with an inertia bonus of about 0.05 for the running action is the default; softmax (temperature about 0.2) when designers want variety without silly picks.
Run this shape in the project's test runner (Unity Test Framework, GdUnit4, xUnit) before tuning by eye; `Assert` stands for the framework's assertion. A probe leaf counts ticks and resets, so lifecycle bugs show up as numbers.
sealed class Probe : Leaf
{
public int Ticks, Resets; readonly int _after; readonly Status _end;
public Probe(int after, Status end = Status.Success) { _after = after; _end = end; }
public override Status Tick(Blackboard bb, float dt) => ++Ticks >= _after ? _end : Status.Running;
public override void Reset() { Ticks = 0; Resets++; }
}
// Guard lost mid-action: the running action must be aborted, not resumed.
var bb = new Blackboard(); var chase = new Probe(after: 3);
var seq = new ReactiveSequence().Add(new Condition(b => b.Get<bool>("sees"))).Add(chase);
bb.Set("sees", true); Assert(seq.Tick(bb, 0.1f) == Status.Running);
bb.Set("sees", false); Assert(seq.Tick(bb, 0.1f) == Status.Failure && ch<img src="docs/assets/awesome-gamedev-agent-skills-banner.png" width="820" alt="awesome-gamedev-agent-skills — game-dev skills for AI coding agents.
Engine-neutral game audio technique: bus layout, volume sliders in decibels, loudness, ducking music under dialogue, adaptive…
Builds and tunes game cameras, engine-neutral with Godot and Cinemachine 3 mappings: 2D follow with deadzone and look-ahead,…
Plans, generates or sources, and validates consistent game art: style guides, sprites, pixel art, tilesets, icons and textures,…
Builds engine-neutral branching dialogue with Ink, Yarn Spinner or a small JSON graph runner: lines, choices, conditions,…
Designs engine-neutral enemy and NPC AI: picks FSM, behavior tree, utility or GOAP, and builds perception, steering and A*…
Adds engine-neutral juice to a working mechanic: trauma-based screen shake, hit-stop, eased tweens, squash and stretch, and…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.