gamedev-skills/awesome-gamedev-agent-skills

ai-behavior-trees-utility-ai

Build a production behavior-tree runtime (Blackboard, action/condition leaves, sequence/selector/parallel composites, decorators) and a Utility AI system (response curves — linear, exponential, sigmoid, quadratic — considerations, and action evaluators), pl…

查看源码

使用方法

  1. 复制安装命令,在自己的智能体环境安装前先检查源码包。
  2. 从原始文档核对所需工具、凭据和支持的宿主。
  3. 说明输入材料与期望交付物,并对照来源检查输出。
npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai

开始前需了解

  • 安装不包含模型订阅、API 额度或访问文件的权限。
  • 仓库星数和安装量反映活跃情况,不等于独立质量或安全测试。
仓库原始内容

按源仓库内容呈现,保留标题、案例、代码、表格、链接以及原文引用的演示图片。

Behavior Trees & Utility AI

Two complementary ways to structure NPC decision-making, plus how to combine them. A behavior tree (BT) expresses structured, prioritized, reactive logic as a tree that is "ticked" each step. Utility AI answers "how much do I want each option right now?" by scoring actions with normalized curves and picking the best. Ship believable agents by using a BT for structure and Utility AI where graded trade-offs matter.

This skill is the implementation companion to game-ai (which helps you choose between FSM / BT / steering / pathfinding). Read game-ai to pick a model; read this to build the runtime.

When to use

  • Use to build a reusable BT runtime: a Blackboard, Node base, action/condition leaves,

Sequence/Selector/Parallel composites, and decorators (Inverter, Cooldown, Repeat).

  • Use to build a Utility AI decider: response curves, considerations, and an evaluator that

scores and selects actions (max, softmax, or weighted-random for variety).

  • Use to build hybrid AI — a BT whose leaf delegates the "which attack / which target"

choice to a utility evaluator.

When not to use: to choose between FSM, BT, steering, or pathfinding, and for A/navmesh routing, use game-ai. For Unreal's asset-based BehaviorTree/Blackboard, BTTask/BTService and AIController, use unreal-behavior-trees. For the navmesh agent that moves the NPC, use unity-navmesh or the engine's navigation node.

Core workflow

  1. Pick the model. Structured, prioritized, interruptible behavior → BT. Continuous

"score every option" decisions (targeting, needs, item choice) → Utility. Both → hybrid.

  1. Design the Blackboard first. One typed key/value store per agent is the shared memory that

decouples nodes; leaves read/write it and never hold references to each other.

  1. Write leaves. Conditions return Success/Failure immediately; actions return

Running across frames until they finish. Keep leaves small and side-effect-explicit.

  1. Compose. Selector = OR/fallback (first non-failure wins); Sequence = AND (stop at first

non-success); Parallel for concurrent branches. Wrap with decorators for policy (invert, cooldown, repeat, force-success).

  1. For Utility: enumerate considerations, map each raw fact through a normalized 0..1 curve,

combine (weighted product with compensation, or weighted sum), then select the max — add hysteresis so agents don't flip-flop on ties.

  1. Tick deliberately. Tick the tree/evaluator once per decision step (often slower than

render). Preserve Running state between ticks; verify by drawing the active path and the per-action scores on screen while tuning.

Architecture at a glance

A behavior tree evaluates top-down, left-to-right; each node returns a status up to its parent:

mermaid
flowchart TD
    Root["Selector (root)"] --> Combat["Sequence: Combat"]
    Root --> Patrol["Action: Patrol"]
    Combat --> See["Condition: CanSeePlayer?"]
    Combat --> InRange{"Selector: Reach"}
    Combat --> Attack["Action: Attack (Running)"]
    InRange --> Close["Condition: InAttackRange?"]
    InRange --> MoveTo["Action: MoveToPlayer (Running)"]

Utility AI is a scoring pipeline — every candidate action is scored, then one is selected:

text
facts (distance, health, ammo…)
      │  each fact → a normalized 0..1 response curve (consideration)
      ▼
score(action) = weight · combine(consideration_1 … consideration_n)   # product+compensation or sum
      ▼
select: argmax  ·  or softmax / weighted-random for variety  ·  + hysteresis to avoid jitter

Status is a three-value enum shared by every node — this is the contract that makes the tree composable:

csharp
public enum Status { Success, Failure, Running }

public abstract class Node
{
    public abstract Status Tick(Blackboard bb, float dt);
    public virtual void Reset() { }   // called when a parent abandons this subtree
}
csharp
// Selector = fallback/OR: return the first child that is not Failure.
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.Failure) return s;   // Success or Running stops the scan
        }
        _current = 0;
        return Status.Failure;                    // every child failed
    }
}

The reciprocal Sequence (AND — stop at first non-Success), Parallel, the Blackboard, the leaf base classes, and every decorator are in references/behavior-tree-core.md.

Utility scoring in one snippet

csharp
// 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
    // Product + compensation keeps a single 0 from vetoing while low values still dampen.
    return Curves.CompensatedProduct(new[] { distance01, health01 });
}

The full curve library (linear, quadratic, exponential, logistic/sigmoid, smoothstep), the Consideration/UtilityAction types, and the UtilityEvaluator selection strategies are in references/utility-ai-system.md.

Pitfalls

  • Re-ticking a `Running` action from the root every frame restarts it. Return Running and

resume where you left off; only Reset() a subtree when a parent actually abandons it.

  • Deep trees re-evaluated wholesale each tick waste time and cause thrash. Prefer shallow

trees and conditional aborts (a higher-priority condition can interrupt a lower branch).

  • Un-normalized considerations. If one curve outputs 0..100 and another 0..1, the big one

dominates. Every consideration must return 0..1.

  • Utility jitter on near-ties. Add hysteresis: give the currently-running action a small bonus

so the agent commits instead of oscillating.

  • Allocating nodes, closures, or arrays every tick creates GC spikes. Build the tree once at

spawn; keep per-tick work allocation-free.

References

  • references/behavior-tree-core.md — Blackboard, Node/leaf base classes, action & condition

leaves, Sequence/Selector/Parallel, and the decorator library (full C#).

  • references/utility-ai-system.md — response-curve library, Consideration, UtilityAction,

and the UtilityEvaluator (argmax, softmax, weighted-random, hysteresis).

  • references/practical-examples.md — a guard Patrol→Combat BT, a villager needs-based Utility

AI, and a hybrid agent, as drop-in templates.

  • references/best-practices-and-pitfalls.md — memory management, profiling, avoiding deep trees,

event-driven aborts, and combining Utility AI with BTs (hybrid architecture).

Related skills

  • game-ai — choose between FSM / BT / steering; A* and navmesh pathfinding.
  • unreal-behavior-trees — Unreal's asset-based BT/Blackboard, tasks, decorators, services.
  • unity-navmesh — the NavMeshAgent that carries out "move to" intents.
  • physics-tuning — agent radius, movement, and collision response for the motion layer.
  • tower-defense, fps-shooter, rpg — genres that compose this decision layer.

按任务相关推荐

来自同一仓库

更多 Skills

全部 Skills
gamedev-skills
社区

game-feel

Add "juice" and game feel that makes actions satisfying — screen shake, hit-stop/freeze frames, tweened/eased motion, squash & stretch, knockback, and layered audio-visual feedback — as engine-neutral techniques that pair with the detected engine's tween, particle, and camera APIs. Use when the user mentions game feel, juice, "make it feel good/punchy", screen shake, hit stop, screen freeze, easing, squash and stretch, impact frames, or feedback/polish on hits, jumps, pickups, and deaths.

安装量
16
GitHub Stars
4316
最近更新
10月24日
gamedev-skills
社区

audio-design

Implement game audio practice — bus/mixer architecture and gain in decibels, ducking (sidechain), adaptive/dynamic music via layering and re-sequencing, SFX variation, and beat synchronization. Engine-neutral. Use when the user mentions audio mixing, audio buses, adaptive/dynamic music, ducking, SFX variation, music layers, or syncing gameplay to the beat.

安装量
13
GitHub Stars
4316
最近更新
10月24日
gamedev-skills
社区

performance-optimization

Find and fix game performance problems methodically — measure with the engine profiler first, reason about the frame-time budget, locate the CPU-vs-GPU bottleneck, then apply the right fix: object pooling, draw-call batching, fewer allocations/GC spikes, and asset budgets. Engine- neutral method that pairs with each engine's profiler. Use when the user mentions performance, optimize, low/dropping FPS, frame drops, stutter, lag, profiler, frame budget, draw calls, batching, garbage collection/GC

安装量
13
GitHub Stars
4316
最近更新
10月24日
gamedev-skills
社区

shader-programming

Write game shaders from cross-engine fundamentals — the vertex→fragment pipeline, coordinate spaces, UV math, and common 2D/3D effects (tint, UV scroll, dissolve, outline, fresnel rim, vignette) in GLSL with HLSL equivalents. Use when the user mentions shaders, fragment/pixel shader, vertex shader, UV, GLSL, HLSL, or effects like dissolve, outline, or rim light.

安装量
13
GitHub Stars
4316
最近更新
10月24日