bt

package module
v1.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: MIT Imports: 6 Imported by: 0

README

bt-go

Go Reference

A small, composable behavior tree library for Go.

Install

go get github.com/ratlabs-io/bt-go@v1.5.0
import "github.com/ratlabs-io/bt-go"
// package name is bt → bt.NewEnv, bt.NewSequence, …

Core model

Concept Role
Behavior Any node: Tick(env) → Success | Failure | Running
Env Per-tick environment (not a context.Context)
Blackboard Hierarchical KV store for agent/world state
context.Context Cancel/deadline only — env.Context()
Halt Abort cleanup when a parent preempts or the runner cancels
Env vs context.Context
Concern API
Cancel / deadline env.Context()
Agent state env.Blackboard() or Set/Get/GetAs[T]

Do not put health/targets in context.WithValue. Use the blackboard.

env := bt.NewEnv(parentCtx)
env.Set("health", 100)
h, ok := bt.GetAs[int](env, "health")
Reactive vs memory
Constructor Style
NewSequence / NewSelector Reactive — restart at child 0 each tick
NewMemorySequence / NewMemorySelector Resume last Running child

Selector is priority order (earlier = higher). Preempted Running children are Halted.

Parallel
Constructor Execution
NewParallel Sequential ticks (default, deterministic)
NewConcurrentParallel One goroutine per child

Policies: RequireOne, RequireAll, SuccessOnOne, SuccessOnAll.

Halt and abort hooks
branch := bt.NewAbortHook(longRunningSubtree, func(env bt.Env) {
    // stop pathing, clear target, …
})
// When a higher-priority Selector branch wins, Halt runs OnAbort.

TreeRunner.Run Halts the tree when env.Context() is cancelled. In-flight Tick bodies are not interrupted — long actions should watch env.Context().Done().

Quick start

tree := bt.NewSequence(
    bt.NewNamed("Greet", bt.NewAction(func(env bt.Env) bt.RunStatus {
        fmt.Println(bt.MustGet[string](env, "greeting"))
        return bt.Success
    })),
)
env := bt.NewEnv(context.Background())
env.Set("greeting", "Hello")
tree.Tick(env)

Examples:

Node catalog

Leaves: NewAction, NewCondition

Composites: NewSequence, NewMemorySequence, NewSelector, NewMemorySelector, NewParallel, NewConcurrentParallel, NewBinarySelector, NewSwitch, NewConditional

Decorators: NewInverter, NewRepeater, NewUntilSuccess, NewUntilFailure, NewNamed, NewObserving, NewAbortHook

Runner: NewTreeRunner + WithTickRate / WithCallbacks

Typed data: GetAs[T], MustGet[T]

Debug: NewTreeVisualizer, NewStatusRecorder, NewObserving

Development

go test ./...
go test ./... -race
go run ./examples/hello
go run ./examples/agent

See CHANGELOG.md for release history.

License

MIT — see LICENSE.

Documentation

Overview

Package bt is a composable behavior tree library for Go.

Import: "github.com/ratlabs-io/bt-go" (package name bt).

A behavior tree is a hierarchy of Behavior nodes. Each tick, a node returns one of Success, Failure, or Running. Leaf nodes (Action, Condition) do work; composites (Sequence, Selector, Parallel, …) combine children; decorators (Inverter, Repeater, Named, Observing, AbortHook, …) wrap a single child.

Environment (Env)

Nodes receive an Env on every Tick. Env is not a context.Context:

  • env.Context() — stdlib context for cancellation/deadlines only
  • blackboard via Set/Get/GetAs — mutable agent/world state

Put agent data on the blackboard, never in context.WithValue.

Abort (Halt)

When a reactive parent preempts a Running child, or TreeRunner cancels, Halt is called on Haltable nodes so they can clean up (see AbortHook).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetAs

func GetAs[T any](env Env, key string) (T, bool)

GetAs reads key from env's blackboard and type-asserts to T. ok is false if the key is missing or the value is not of type T.

func Halt

func Halt(env Env, node Behavior)

Halt calls Halt on node if it implements Haltable; otherwise it is a no-op.

func HaltAll

func HaltAll(env Env, nodes ...Behavior)

HaltAll calls Halt on each node.

func MustGet

func MustGet[T any](env Env, key string) T

MustGet is like GetAs but panics if the key is missing or has the wrong type. Prefer GetAs in production paths; MustGet is for tests and trusted setup.

Types

type AbortHook

type AbortHook struct {
	BaseDecorator
	OnAbort func(env Env)
	// contains filtered or unexported fields
}

AbortHook runs a callback when the node is Halted while still considered active (last tick returned Running). Use it for cleanup when a reactive parent preempts a long-running branch (stop pathing, clear target, etc.).

func NewAbortHook

func NewAbortHook(child Behavior, onAbort func(env Env)) *AbortHook

NewAbortHook wraps child with an abort callback.

func (*AbortHook) Halt

func (a *AbortHook) Halt(env Env)

Halt invokes OnAbort if the child was Running, then Halt the child.

func (*AbortHook) Tick

func (a *AbortHook) Tick(env Env) RunStatus

Tick runs the child and tracks whether it is mid-run.

type Action

type Action struct {
	// contains filtered or unexported fields
}

Action is a leaf node that runs a user-supplied function.

func NewAction

func NewAction(runFunc func(env Env) RunStatus) *Action

NewAction creates an Action from runFunc. runFunc should return Success, Failure, or Running as appropriate. If runFunc is nil, Tick returns Failure.

func (*Action) Tick

func (a *Action) Tick(env Env) RunStatus

Tick executes the action function.

type BaseDecorator

type BaseDecorator struct {
	Child Behavior
}

BaseDecorator holds the child pointer shared by concrete decorators.

func (*BaseDecorator) GetChild

func (d *BaseDecorator) GetChild() Behavior

GetChild returns the decorated child.

func (*BaseDecorator) HaltChild

func (d *BaseDecorator) HaltChild(env Env)

HaltChild aborts the child if it is Haltable. Embedded types may call this from Halt.

func (*BaseDecorator) SetChild

func (d *BaseDecorator) SetChild(child Behavior)

SetChild sets the decorated child.

type Behavior

type Behavior interface {
	// Tick executes one step of the node and returns its status.
	Tick(env Env) RunStatus
}

Behavior is implemented by every node in a behavior tree.

type BinarySelector

type BinarySelector struct {
	Condition Behavior
	IfTrue    Behavior
	IfFalse   Behavior
}

BinarySelector chooses between two branches based on a condition behavior.

If Condition returns Success, IfTrue is ticked; otherwise IfFalse is ticked. Condition statuses other than Success (including Running) select IfFalse. For a boolean leaf, pass a *Condition.

func NewBinarySelector

func NewBinarySelector(condition, ifTrue, ifFalse Behavior) *BinarySelector

NewBinarySelector creates a BinarySelector.

func (*BinarySelector) Tick

func (node *BinarySelector) Tick(env Env) RunStatus

Tick evaluates Condition and runs the matching branch.

type Blackboard

type Blackboard struct {
	// contains filtered or unexported fields
}

Blackboard is a hierarchical, thread-safe key-value store for tree state.

Child blackboards can see parent entries (Get/Has walk upward). Writes and deletes apply only to the local blackboard, so a child can shadow a parent key without mutating it.

func NewBlackboard

func NewBlackboard() *Blackboard

NewBlackboard creates an empty root blackboard.

func NewBlackboardWithParent

func NewBlackboardWithParent(parent *Blackboard) *Blackboard

NewBlackboardWithParent creates a blackboard that falls back to parent on miss.

func (*Blackboard) AllEntries

func (bb *Blackboard) AllEntries() []string

AllEntries returns keys visible from this blackboard, including parents. Local keys shadow parent keys of the same name (counted once).

func (*Blackboard) Clear

func (bb *Blackboard) Clear()

Clear removes all local entries. Parents are unaffected.

func (*Blackboard) Delete

func (bb *Blackboard) Delete(key string)

Delete removes a key from this blackboard only.

func (*Blackboard) Entries

func (bb *Blackboard) Entries() []string

Entries returns keys set on this blackboard (not parents).

func (*Blackboard) Get

func (bb *Blackboard) Get(key string) (interface{}, bool)

Get retrieves a value, checking this blackboard then parents.

func (*Blackboard) Has

func (bb *Blackboard) Has(key string) bool

Has reports whether key exists on this blackboard or any parent.

func (*Blackboard) HasLocal

func (bb *Blackboard) HasLocal(key string) bool

HasLocal reports whether key is set on this blackboard (ignoring parents).

func (*Blackboard) Set

func (bb *Blackboard) Set(key string, value interface{})

Set stores a value on this blackboard only.

type ChildrenProvider

type ChildrenProvider interface {
	GetChildren() []Behavior
}

ChildrenProvider is implemented by nodes that expose multiple children. Used by tooling (visualization) without type-switching every composite.

type Composite

type Composite struct {
	Children []Behavior
}

Composite is embedded by multi-child control nodes. Children are public so callers and tools (e.g. visualizers) can inspect the tree.

func (*Composite) GetChildren

func (c *Composite) GetChildren() []Behavior

GetChildren returns the composite's child nodes.

type Condition

type Condition struct {
	// contains filtered or unexported fields
}

Condition is a leaf that maps a boolean check to Success or Failure. It never returns Running.

func NewCondition

func NewCondition(checkFunc func(env Env) bool) *Condition

NewCondition creates a Condition from checkFunc. If checkFunc is nil, Tick returns Failure.

func (*Condition) Tick

func (c *Condition) Tick(env Env) RunStatus

Tick returns Success when the check is true, otherwise Failure.

type Conditional

type Conditional struct {
	Condition *Condition
	Action    Behavior
}

Conditional runs Action only when Condition succeeds. If the condition fails, Conditional returns Failure without ticking Action. Condition must be non-nil; a nil Action is treated as Failure when selected.

func NewConditional

func NewConditional(condition *Condition, action Behavior) *Conditional

NewConditional creates a Conditional with the given condition and action.

func (*Conditional) Tick

func (c *Conditional) Tick(env Env) RunStatus

Tick checks the condition, then optionally runs the action.

type Decorator

type Decorator interface {
	Behavior
	SetChild(child Behavior)
	GetChild() Behavior
}

Decorator wraps a single child and alters when it runs or what status it reports.

type Env

type Env interface {
	// Context returns the stdlib context used for cancellation and deadlines.
	// It is never used as a value bag for agent state.
	Context() context.Context

	// Blackboard returns the hierarchical store for agent/world state.
	Blackboard() *Blackboard

	// Set stores a value on the blackboard (convenience for Blackboard().Set).
	Set(key string, value interface{})
	// Get reads a value from the blackboard hierarchy.
	Get(key string) (value interface{}, ok bool)
	// Delete removes a key from this blackboard only (not parents).
	Delete(key string)
	// Has reports whether key exists on this blackboard or any parent.
	Has(key string) bool
}

Env is the per-tick environment passed to every node.

It is intentionally not a context.Context. The two concerns are separate:

  • Context() — stdlib context.Context for cancellation and deadlines only
  • Blackboard — mutable agent/world state (hierarchical key-value store)

Do not put agent state in context.WithValue. Use the blackboard (or the convenience Set/Get/Delete/Has methods, which write through to it).

Env does not implement context.Context (has-a, not is-a).

func NewEnv

func NewEnv(parent context.Context, options ...EnvOption) Env

NewEnv creates an Env that uses parent for cancellation/deadlines. A new blackboard is allocated unless WithBlackboard is supplied. If parent is nil, context.Background() is used.

type EnvOption

type EnvOption func(*env)

EnvOption configures an Env at construction time.

func WithBlackboard

func WithBlackboard(bb *Blackboard) EnvOption

WithBlackboard sets the blackboard used by the env. If bb is nil, a fresh blackboard is used instead.

type Haltable

type Haltable interface {
	Halt(env Env)
}

Haltable is implemented by nodes that need cleanup when a parent aborts them without delivering a terminal Success/Failure tick (preemption, cancel, Reset).

Halt must be safe to call when the node is not running (no-op). Composites that track a running child should Halt that child and clear memory.

type Inverter

type Inverter struct {
	BaseDecorator
}

Inverter swaps Success ↔ Failure. Running is unchanged.

func NewInverter

func NewInverter(child Behavior) *Inverter

NewInverter creates an Inverter around child.

func (*Inverter) Halt

func (i *Inverter) Halt(env Env)

Halt aborts the child.

func (*Inverter) Tick

func (i *Inverter) Tick(env Env) RunStatus

Tick runs the child and inverts terminal statuses.

type KeyFunc

type KeyFunc func(env Env) string

KeyFunc derives a case key from the context for Switch selection.

type MemorySelector

type MemorySelector struct {
	Composite
	// contains filtered or unexported fields
}

MemorySelector is a Selector that remembers which child was Running.

Unlike the reactive Selector (NewSelector), once a child returns Running the next Tick resumes at that child and does not re-evaluate higher-priority (earlier) siblings until the remembered child finishes.

If the remembered child fails, evaluation continues with later siblings only (earlier ones are not re-tried until the whole selector returns Failure and memory is cleared). Call Reset to clear memory without ticking; Halt aborts.

func NewMemorySelector

func NewMemorySelector(children ...Behavior) *MemorySelector

NewMemorySelector creates a memory Selector with the given children.

func (*MemorySelector) Halt

func (s *MemorySelector) Halt(env Env)

Halt aborts the remembered child (if any) and clears memory.

func (*MemorySelector) Reset

func (s *MemorySelector) Reset()

Reset clears resume state so the next Tick starts at the first child. It does not Halt the current child; call Halt when aborting mid-run.

func (*MemorySelector) RunningIndex

func (s *MemorySelector) RunningIndex() int

RunningIndex returns the remembered child index, or -1 when idle.

func (*MemorySelector) Tick

func (s *MemorySelector) Tick(env Env) RunStatus

Tick tries children from the remembered index. See type docs.

type MemorySequence

type MemorySequence struct {
	Composite
	// contains filtered or unexported fields
}

MemorySequence is a Sequence that remembers which child was Running.

Unlike the reactive Sequence (NewSequence), once a child returns Running the next Tick resumes at that child and does not re-tick earlier siblings that already succeeded in this run.

Memory is cleared when the sequence returns Success or Failure (including nil-child failure). Call Reset to clear memory without ticking; Halt aborts the current child and resets.

func NewMemorySequence

func NewMemorySequence(children ...Behavior) *MemorySequence

NewMemorySequence creates a memory Sequence with the given children.

func (*MemorySequence) Halt

func (s *MemorySequence) Halt(env Env)

Halt aborts the child at the resume index (if any) and resets memory.

func (*MemorySequence) Reset

func (s *MemorySequence) Reset()

Reset clears resume state so the next Tick starts at the first child. It does not Halt the current child; call Halt when aborting mid-run.

func (*MemorySequence) RunningIndex

func (s *MemorySequence) RunningIndex() int

RunningIndex returns the child index that will be resumed on the next Tick (0 when idle / after a terminal status).

func (*MemorySequence) Tick

func (s *MemorySequence) Tick(env Env) RunStatus

Tick executes children from the remembered index. See type docs.

type Named

type Named struct {
	BaseDecorator
	Name string
}

Named wraps a child with a human-readable label for visualization and logs. Tick is a pure pass-through.

func NewNamed

func NewNamed(name string, child Behavior) *Named

NewNamed creates a Named decorator. Empty name falls back to "Named" in dumps.

func (*Named) Halt

func (n *Named) Halt(env Env)

Halt propagates abort to the child.

func (*Named) Tick

func (n *Named) Tick(env Env) RunStatus

Tick runs the child unchanged.

func (*Named) VisualizeNode

func (n *Named) VisualizeNode() string

VisualizeNode returns the custom name for TreeVisualizer.

type NodeVisualizer

type NodeVisualizer interface {
	VisualizeNode() string
}

NodeVisualizer lets custom nodes supply their own label for tree dumps.

type Observing

type Observing struct {
	BaseDecorator
	// AfterTick is invoked after the child is ticked (including when child is nil → Failure).
	AfterTick TickObserver
}

Observing wraps a child and reports each tick result to AfterTick. Only this node is observed — wrap additional nodes to observe deeper.

func NewObserving

func NewObserving(child Behavior, after TickObserver) *Observing

NewObserving creates an Observing decorator. after may be nil (no-op).

func (*Observing) Halt

func (o *Observing) Halt(env Env)

Halt propagates abort to the child.

func (*Observing) Tick

func (o *Observing) Tick(env Env) RunStatus

Tick runs the child and notifies AfterTick.

type Parallel

type Parallel struct {
	Composite
	// contains filtered or unexported fields
}

Parallel ticks all children each call and aggregates results by policy.

By default ticks are sequential (deterministic order, same stack) — the usual behavior-tree meaning of “parallel”: all children get a chance this frame. Use NewConcurrentParallel for one goroutine per child.

Children share the same Env. Under concurrent mode the blackboard is thread-safe; other shared mutable state in actions must be synchronized.

Every child is ticked on every Parallel.Tick (no sticky completion memory).

func NewConcurrentParallel

func NewConcurrentParallel(policy ParallelPolicy, children ...Behavior) *Parallel

NewConcurrentParallel creates a Parallel that ticks each child in its own goroutine.

func NewParallel

func NewParallel(policy ParallelPolicy, children ...Behavior) *Parallel

NewParallel creates a sequential Parallel node (classic BT parallel).

func (*Parallel) Concurrent

func (p *Parallel) Concurrent() bool

Concurrent reports whether children are ticked in goroutines.

func (*Parallel) Halt

func (p *Parallel) Halt(env Env)

Halt aborts every child.

func (*Parallel) Policy

func (p *Parallel) Policy() ParallelPolicy

Policy returns the aggregation policy.

func (*Parallel) Tick

func (p *Parallel) Tick(env Env) RunStatus

Tick runs all children (sequentially or concurrently) and returns the policy result.

type ParallelPolicy

type ParallelPolicy int

ParallelPolicy defines how a Parallel node aggregates child results.

const (
	// RequireOne succeeds if at least one child succeeds; fails only if all fail.
	RequireOne ParallelPolicy = iota
	// RequireAll succeeds only if all children succeed; fails if any fail.
	RequireAll
	// SuccessOnAll succeeds only if all children succeed; otherwise Running
	// (never Failure — failures are treated as “not yet success”).
	SuccessOnAll
	// SuccessOnOne succeeds if at least one child succeeds; otherwise Running
	// (never Failure).
	SuccessOnOne
)

func (ParallelPolicy) String

func (p ParallelPolicy) String() string

String returns the policy name.

type Repeater

type Repeater struct {
	BaseDecorator
	Count int
	// contains filtered or unexported fields
}

Repeater runs its child a fixed number of successful times. Each Tick advances at most one successful child completion. Failure from the child aborts and resets the counter. count <= 0 means infinite (always returns Running after a successful child tick).

func NewRepeater

func NewRepeater(child Behavior, count int) *Repeater

NewRepeater creates a Repeater. count <= 0 means repeat forever.

func (*Repeater) Halt

func (r *Repeater) Halt(env Env)

Halt resets the counter and aborts the child.

func (*Repeater) Reset

func (r *Repeater) Reset()

Reset clears the success counter so the next Tick starts a fresh series.

func (*Repeater) Tick

func (r *Repeater) Tick(env Env) RunStatus

Tick executes the child and tracks successful completions toward Count.

type RunStatus

type RunStatus int

RunStatus is the result of ticking a behavior node.

const (
	// Success means the node completed its task successfully.
	Success RunStatus = iota
	// Failure means the node failed to complete its task.
	Failure
	// Running means the node is still in progress and should be ticked again.
	Running
)

func (RunStatus) String

func (rs RunStatus) String() string

String returns a human-readable name for the status.

type RunnerOption

type RunnerOption func(*TreeRunner)

RunnerOption configures a TreeRunner.

func WithCallbacks

func WithCallbacks(onSuccess, onFailure, onRunning func()) RunnerOption

WithCallbacks registers hooks invoked after each tick for the returned status. Nil callbacks are treated as no-ops.

func WithTickRate

func WithTickRate(rate time.Duration) RunnerOption

WithTickRate sets how often the tree is ticked. Default is 100ms (10 Hz).

type Selector

type Selector struct {
	Composite
	// contains filtered or unexported fields
}

Selector ticks children left-to-right until one succeeds or is still running.

Semantics (reactive / restart-from-start each tick — classic priority order):

  • Success from any child → Success
  • Running from any child → Running
  • All Failure → Failure

Earlier children have higher priority: every Tick re-evaluates from the first child, so a higher-priority branch can preempt a lower one that was Running. When preemption occurs, the abandoned child is Halted if it implements Haltable. For stick-to-running-child semantics (no preemption), use NewMemorySelector.

func NewSelector

func NewSelector(children ...Behavior) *Selector

NewSelector creates a Selector with the given children, in priority order.

func (*Selector) Halt

func (s *Selector) Halt(env Env)

Halt aborts the last running child and clears tracking.

func (*Selector) Tick

func (s *Selector) Tick(env Env) RunStatus

Tick tries each child until one does not fail. See type docs for status rules.

type Sequence

type Sequence struct {
	Composite
	// contains filtered or unexported fields
}

Sequence ticks children left-to-right until one fails or is still running.

Semantics (reactive / restart-from-start each tick):

  • Failure from any child → Failure
  • Running from any child → Running
  • All Success → Success

Sequence does not remember progress for control flow; each Tick starts at the first child. It does track the last Running child so that if an earlier sibling later fails (or the sequence is Halted), the abandoned child receives Halt. For resume-from-running control flow, use NewMemorySequence.

func NewSequence

func NewSequence(children ...Behavior) *Sequence

NewSequence creates a Sequence with the given children, in order.

func (*Sequence) Halt

func (s *Sequence) Halt(env Env)

Halt aborts the last running child.

func (*Sequence) Tick

func (s *Sequence) Tick(env Env) RunStatus

Tick executes children in order. See type docs for status rules.

type StatusRecorder

type StatusRecorder struct {
	// contains filtered or unexported fields
}

StatusRecorder records the status of nodes as they are ticked. It is a debugging aid, not a tree node itself.

Prefer wrapping ticks you care about:

rec := bt.NewStatusRecorder()
status := rec.Tick(env, root) // records root only

For full-tree status maps, wrap individual leaves or use a custom decorator.

func NewSaveTreeSnapshot deprecated

func NewSaveTreeSnapshot() *StatusRecorder

NewSaveTreeSnapshot is a deprecated alias for NewStatusRecorder.

Deprecated: use NewStatusRecorder.

func NewStatusRecorder

func NewStatusRecorder() *StatusRecorder

NewStatusRecorder creates an empty status recorder.

func (*StatusRecorder) GetStatusMap

func (s *StatusRecorder) GetStatusMap() map[Behavior]RunStatus

GetStatusMap returns the map of recorded node statuses.

func (*StatusRecorder) Tick

func (s *StatusRecorder) Tick(env Env, node Behavior) RunStatus

Tick runs node, records its status, and returns that status. Only the node itself is recorded — not its descendants.

func (*StatusRecorder) Visualize

func (s *StatusRecorder) Visualize(root Behavior) string

Visualize renders root with recorded statuses annotated.

type Switch

type Switch struct {
	KeyFunc KeyFunc
	Cases   map[string]Behavior
	Default Behavior
}

Switch selects a child by a dynamic string key.

KeyFunc is evaluated every Tick. If Cases[key] exists it is ticked; otherwise Default is ticked. If neither matches, Switch returns Failure.

func NewSwitch

func NewSwitch(keyFunc KeyFunc, cases map[string]Behavior, defaultBehavior Behavior) *Switch

NewSwitch creates a Switch. cases may be nil (only Default will run).

func (*Switch) Tick

func (s *Switch) Tick(env Env) RunStatus

Tick selects and runs the matching case or default.

type TickObserver

type TickObserver func(node Behavior, status RunStatus)

TickObserver is called after a watched node finishes a Tick.

type TreeRunner

type TreeRunner struct {
	// contains filtered or unexported fields
}

TreeRunner ticks a behavior tree on a fixed interval until cancelled.

func NewTreeRunner

func NewTreeRunner(tree Behavior, options ...RunnerOption) *TreeRunner

NewTreeRunner returns a runner for tree with optional configuration.

func (*TreeRunner) Run

func (tr *TreeRunner) Run(env Env)

Run ticks the tree at the configured rate until env.Context() is cancelled.

Cancellation stops scheduling further ticks and Halts the tree so Haltable nodes can clean up. A Tick that is already in progress is not interrupted — long-running actions should watch env.Context().Done() themselves.

func (*TreeRunner) RunOnce

func (tr *TreeRunner) RunOnce(env Env) RunStatus

RunOnce ticks the tree once, fires the matching callback, and returns the status. It does not Halt afterward (the tree may still be Running).

type TreeVisualizer

type TreeVisualizer struct {
	// contains filtered or unexported fields
}

TreeVisualizer renders a behavior tree as indented text.

func NewTreeVisualizer

func NewTreeVisualizer(root Behavior) *TreeVisualizer

NewTreeVisualizer creates a visualizer for root.

func (*TreeVisualizer) Visualize

func (tv *TreeVisualizer) Visualize() string

Visualize returns a multi-line text representation of the tree.

func (*TreeVisualizer) WithNodeStatuses

func (tv *TreeVisualizer) WithNodeStatuses(statuses map[Behavior]RunStatus) *TreeVisualizer

WithNodeStatuses enables status annotations from the given map.

type UntilFailure

type UntilFailure struct {
	BaseDecorator
}

UntilFailure ticks the child until it returns Failure. When the child fails, the decorator returns Success (the wait succeeded).

func NewUntilFailure

func NewUntilFailure(child Behavior) *UntilFailure

NewUntilFailure creates an UntilFailure decorator.

func (*UntilFailure) Halt

func (u *UntilFailure) Halt(env Env)

Halt aborts the child.

func (*UntilFailure) Tick

func (u *UntilFailure) Tick(env Env) RunStatus

Tick returns Success when the child fails; otherwise Running.

type UntilSuccess

type UntilSuccess struct {
	BaseDecorator
}

UntilSuccess ticks the child until it returns Success. Failure and Running both yield Running from the decorator.

func NewUntilSuccess

func NewUntilSuccess(child Behavior) *UntilSuccess

NewUntilSuccess creates an UntilSuccess decorator.

func (*UntilSuccess) Halt

func (u *UntilSuccess) Halt(env Env)

Halt aborts the child.

func (*UntilSuccess) Tick

func (u *UntilSuccess) Tick(env Env) RunStatus

Tick returns Success only when the child succeeds; otherwise Running.

Directories

Path Synopsis
examples
agent command
Agent demonstrates reactive vs memory control flow for a simple NPC.
Agent demonstrates reactive vs memory control flow for a simple NPC.
hello command
Hello is a minimal bt-go example: a two-step Sequence that prints a greeting.
Hello is a minimal bt-go example: a two-step Sequence that prints a greeting.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL