skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
jame581/godotprompter93 installs

beehave

Use when using the Beehave addon — pure-GDScript behavior trees with composites, decorators, leaves, a blackboard, and a visual runtime debugger

How do I install this agent skill?

npx skills add https://github.com/jame581/godotprompter --skill beehave
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    This skill provides documentation and implementation guidelines for using the Beehave behavior tree addon in the Godot engine. No security risks were detected.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

What does this agent skill do?

Beehave

Related skills: ai-navigation for the movement leaves drive, state-machine for core-engine FSM, limboai for a heavier C++ BT+HSM alternative, godot-brainstorming for choosing an AI approach.

Addon: Beehave · version v2.9.2 · Godot 4.1+ · MIT · source: https://github.com/bitbrain/beehave · written in GDScript (no official C# API — this skill is GDScript-only by design).


1. When to use Beehave

ApproachBest for
Core-engine FSM (state-machine skill)Simple agents, < 5 states, no addon
Beehave (GDScript addon)Lightweight BT, GDScript-only projects, fast iteration
LimboAIBT and HSM together, visual editor, C++ performance, C# support (module build)

Choose Beehave when your project is GDScript-only, you want a behavior tree without a custom engine build, and you value a simple node-in-scene-tree authoring workflow. Beehave trees live entirely in the scene tree — every composite, decorator, and leaf is a regular Node child. For a heavier C++/C# solution with HSM integration, use the limboai skill instead. For plain state machines without a BT, use the built-in state-machine skill.

C# note: Beehave has no official C# API (zero .cs files in addons/beehave/). From C# you can call the GDScript API via Godot cross-language interop (GetNode<Node>(...).Call("tick", actor, blackboard)), but Beehave provides no typed C# classes.


2. Install & enable

  1. Godot AssetLib → search "Beehave" → Download → Reload project.
    Or copy the addons/beehave/ folder from the GitHub release into res://addons/beehave/.
  2. Enable the plugin: Project → Project Settings → Plugins → tick Beehave.
    Two autoloads are registered: BeehaveGlobalMetrics and BeehaveGlobalDebugger.
  3. Optional — copy script_templates/ from the addon into the project root for leaf scaffolding templates.

3. Tree composition

A Beehave tree is built from three kinds of nodes, all placed as regular scene-tree children:

RoleNodeBehavior
Tree rootBeehaveTreeTicks the child every frame (or physics/manual); extends Node (not BeehaveNode)
CompositesSequenceComposite, SelectorComposite, SimpleParallelComposite, …Flow control — AND / OR / parallel logic
DecoratorsInverterDecorator, CooldownDecorator, RepeaterDecorator, …Wrap one child to modify its result
LeavesActionLeaf, ConditionLeaf subclassesYour custom game logic

Composite quick reference

ClassLogic
SequenceCompositeAND — all children must succeed; fails on first failure
SequenceReactiveCompositeAND — re-evaluates from first child every tick while running
SelectorCompositeOR — succeeds on first success; fails if all fail
SelectorReactiveCompositeOR — re-evaluates from first child every tick while running
SimpleParallelCompositeRuns two children simultaneously; result follows primary (child 0)
SequenceRandomCompositeShuffled AND — executes children in random order
SelectorRandomCompositeShuffled OR — tries children in random order

Decorator quick reference

ClassEffect
InverterDecoratorFlips SUCCESS ↔ FAILURE; passes RUNNING through
AlwaysSucceedDecoratorForces SUCCESS; passes RUNNING through
AlwaysFailDecoratorForces FAILURE; passes RUNNING through
RepeaterDecoratorRe-runs child until it succeeds repetitions times
LimiterDecoratorCaps child to max_count running ticks, then FAILURE
CooldownDecoratorBlocks re-execution for wait_time seconds after child finishes
TimeLimiterDecoratorGives child wait_time seconds; interrupts if still running
DelayDecoratorWaits wait_time seconds before first executing child
UntilFailDecoratorLoops child until it returns FAILURE, then returns SUCCESS

Minimal scene-tree example

# Scene tree:
#   Enemy (CharacterBody2D)
#     BeehaveTree               ← tick_rate = 1, process_thread = PHYSICS
#       SelectorComposite
#         SequenceComposite     ← "attack if in range"
#           IsInRangeCondition
#           AttackAction
#         PatrolAction          ← fallback

# BeehaveTree exports:
# @export var enabled: bool = true
# @export var tick_rate: int = 1          (1 = every frame; 3 = every 3 frames)
# @export var process_thread: ProcessThread = PHYSICS
# @export var blackboard: Blackboard      (auto-created if not set)
# @export_node_path var actor_node_path   (defaults to parent node)

# Access the tree from code if you need manual control:
@onready var bt: BeehaveTree = $BeehaveTree

func _ready() -> void:
    # Reduce tick cost: evaluate AI every 3 physics frames
    bt.tick_rate = 3
    # Default process_thread is PHYSICS — switch to IDLE if actor uses _process
    bt.process_thread = BeehaveTree.ProcessThread.IDLE

tick_rate note: tick_rate = 1 evaluates every frame; tick_rate = 3 every 3 frames. Increase for distant/background NPCs to save CPU. Default process thread is PHYSICS — if the actor script uses _process instead of _physics_process, set process_thread = IDLE to keep them in sync.


4. The leaf contract

Leaves hold your game logic. Subclass ActionLeaf for multi-tick work or ConditionLeaf for single-frame checks, then override tick(actor, blackboard).

# IsInRangeCondition.gd
class_name IsInRangeCondition
extends ConditionLeaf

@export var detection_range: float = 150.0

func tick(actor: Node, blackboard: Blackboard) -> int:
    # Beehave types `actor` as Node; cast to your concrete type for 2D members.
    var body := actor as Node2D
    var target: Node2D = blackboard.get_value("target")
    if body == null or not is_instance_valid(target):
        return FAILURE
    var in_range := body.global_position.distance_to(target.global_position) <= detection_range
    return SUCCESS if in_range else FAILURE
# AttackAction.gd
class_name AttackAction
extends ActionLeaf

@export var attack_duration: float = 0.5

func tick(actor: Node, blackboard: Blackboard) -> int:
    var elapsed: float = blackboard.get_value("attack_elapsed", 0.0)
    elapsed += get_physics_process_delta_time()

    if elapsed >= attack_duration:
        blackboard.erase_value("attack_elapsed")
        # `actor` is typed Node; guard game-specific methods (or cast to your actor type).
        if actor.has_method("play_attack_animation"):
            actor.call("play_attack_animation")
        return SUCCESS

    blackboard.set_value("attack_elapsed", elapsed)
    return RUNNING

func after_run(actor: Node, blackboard: Blackboard) -> void:
    # Clean up any per-run state when the tree interrupts this action
    blackboard.erase_value("attack_elapsed")

Return codes (defined on BeehaveNode):

  • SUCCESS — action complete / condition met.
  • FAILURE — action failed / condition not met; parent composite decides what to do next.
  • RUNNING — action needs more frames; tree will call tick() again next frame (ActionLeaf only — ConditionLeaf should never return RUNNING).

Optional overrides:

  • before_run(actor, blackboard) — called once before the first tick of a run.
  • after_run(actor, blackboard) — called when the child finishes (SUCCESS/FAILURE) or is interrupted.
  • interrupt(actor, blackboard) — called when the tree interrupts a running node.

5. Blackboard

The Blackboard node is a shared key/value store passed to every tick() call. BeehaveTree auto-creates an internal one if you don't assign an external Blackboard node.

# Share one Blackboard across multiple BeehaveTrees on the same actor.
# Assign the same exported Blackboard node to each tree in the Inspector.

# Read / write from any leaf's tick():
func tick(actor: Node, blackboard: Blackboard) -> int:
    # Write
    blackboard.set_value("target", actor.get_nearest_enemy())

    # Read with default
    var speed: float = blackboard.get_value("move_speed", 200.0)

    # Conditional check
    if blackboard.has_value("stunned"):
        return FAILURE

    # Erase (sets key to null; has_value returns false after erase)
    blackboard.erase_value("temp_flag")

    return SUCCESS

Named namespaces: every method accepts an optional blackboard_name: String parameter (default "default"). Use this to keep separate namespaces on one Blackboard node without name collisions (e.g., per-enemy state vs. shared world state).

Built-in expression leaves: BlackboardSetAction, BlackboardEraseAction, BlackboardHasCondition, and BlackboardCompareCondition let you manipulate the Blackboard entirely via Inspector exports (no GDScript required). Expressions run via Godot's Expression.execute([], blackboard) — so you can call get_value("key") directly in the expression string.


6. Visual debugger

Beehave ships an EditorDebuggerPlugin that adds a 🐝 Beehave tab to the bottom editor panel while your game is running:

  1. Run the project from the Godot editor.
  2. Open the Debugger panel → click the 🐝 Beehave tab.
  3. Select a tree from the list to activate live visualization — active nodes are highlighted each tick.
  4. Optional: click the detach button to float the panel, or set Project Settings → beehave/debugger/start_detached = true to always start detached.

To track per-tree CPU cost in the Performance panel, set custom_monitor = true on the BeehaveTree node. This registers beehave [microseconds]/process_time_<actor_name>-<id> as a Performance monitor.

For a walkthrough of writing custom decorators and conditions, see references/custom-nodes.md.


Implementation checklist

  • addons/beehave/ copied into project; plugin enabled in Project Settings → Plugins
  • BeehaveTree added as a child of the actor; actor_node_path set (or left blank to default to parent)
  • process_thread matches actor's loop: PHYSICS for _physics_process, IDLE for _process
  • tick_rate tuned — increase for background NPCs (e.g., 3) to reduce per-frame cost
  • Every tick() override returns SUCCESS, FAILURE, or RUNNING — never void/null
  • ConditionLeaf subclasses never return RUNNING
  • Per-run state written to the Blackboard, not stored on the leaf node itself (leaf nodes are shared)
  • after_run or interrupt cleans up any Blackboard keys the action wrote
  • External Blackboard node exported and shared when multiple BeehaveTree nodes need the same data
  • Visual debugger checked at runtime to verify tick flow before shipping AI logic

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/jame581/godotprompter/beehave">View beehave on skillZs</a>