ASentinel / Accelerated Accelerated · 14 modules

AshForge Sentinel · the whole tool, one course

Build a patrol, read the run,
and know that dead is not broken.

Sentinel authors behaviour trees and then lets you watch them run. The authoring half is small; the debugging half is where the tool earns its keep, and it rewards knowing which of its four instruments answers which question.

Application  AshForge Sentinel Prerequisites  none Format  one course, 14 modules Time  ~85 min

What it is

A behaviour-tree editor with a live runner. You compose regions and selectors, then scrub through a recorded run.

Modules 1–5 are building one, 6–9 are the contract, 10–14 are diagnosis.

The one that saves an evening

Dead is not broken. A node that never fires is usually correct — and telling that apart from a real fault is what the four instruments are for.

Modules 10–14, and the worked diagnosis at the end is the fastest way in.

Why this is one course

Sentinel is a focused tool. Its content is 14 things worth knowing, not three escalating tiers — the old split implied the later material needed the earlier, and it does not. Read straight through, or jump to the module that matches your problem.

01

Getting oriented

Three regions

Read The editor ~2 min

Once the welcome panel is out of the way, the window settles into three areas. You will spend this tutorial in two of them.

Look at01

What is on screen
  1. The node palette runs down the left, with a search box at the top.
  2. The canvas sits in the middle, holding a single Root node.
  3. The Blackboard is on the right.

Done whenYou can name all three without looking.

Leave alone01b

The Blackboard, for now

It is the most interesting panel in Sentinel and it is also the one most likely to mislead you on day one, because what it appears to promise and what it actually does are two different things.

Tutorial two is about exactly that. Until then you can build a complete, working guard without touching it.

02

Reading a tree

Selector means or

Read Templates ~6 min

Building a tree from an empty canvas is a poor first exercise, because the interesting part of a behaviour tree is not the nodes themselves but the order in which they are tried. It is far easier to read a working one first.

Do this

Load the Patrol Guard template

  1. Open the Templates menu in the toolbar. There are five: Aggressive, Defensive, Pack Hunter, Patrol Guard and Elite Combatant. they run roughly in order of complexity
  2. Choose Patrol Guard, which is five nodes built around a single idea. the smallest template that still has something to teach
  3. Check the status line under the toolbar. It should read “Loaded the 'Patrol Guard' template — tweak it, then Save or Test in Crucible.” Sentinel confirms most actions there and nowhere else
Root Selector Sequence Patrol CanSeePlayer Investigate try first else and then
Root Composite Condition Action

Figure 01 — Patrol Guard Five nodes as Sentinel draws them, and the whole lesson sits in the Selector.

A Selector tries its children in order and stops at the first one that succeeds. So this guard asks whether it can see the player. If it can, the Sequence carries on to Investigate and the Selector is satisfied, which means it never reaches Patrol. If it cannot, the Sequence fails and the Selector falls through to Patrol instead.

Key
That is the one idea worth taking away from this tutorial. Selector means or, and Sequence means and. Every other structure in Sentinel is built out of those two, so once you can read them you can read any tree in the tool.
02b

The five node types

Node typeSucceeds whenUse it for
Selectorany one child succeeds Fallbacks. Try this, otherwise that.
Sequenceevery child succeeds Steps that must all happen, in order.
Parallelaccording to its policy Doing two things at once.
Conditionthe world says so Gates, such as CanSeePlayer or HealthLow.
Actionthe behaviour finishes Doing something: Patrol, Attack, Wait.
03

Your first edit

Change one thing

Build Palette ~4 min

At the moment the guard investigates the instant it sees anyone, which reads as slightly inhuman. Making it hesitate first is a small change, and it is a good excuse to use the palette and the connection system for the first time.

Drill03

Add a Wait node
  1. Type wait into the palette's Search nodes… box.
  2. Drag + Wait onto the canvas.
  3. Connect it by dragging from a node's right-hand slot into another node's left-hand slot.
  4. Place it between CanSeePlayer and Investigate, inside the Sequence.

Done whenThe Sequence reads: see the player, pause, then investigate.

Now read it back03b

What you just changed

See the player, and pause, and investigate. Otherwise, patrol.

That is a different character from the one you loaded a few minutes ago, and it took a single node. Most of the personality in a behaviour tree lives in decisions this small.

If stuck
If a connection will not take, you are most likely dragging from a left slot to another left slot. Connections always run out of a right slot and into a left slot, with the parent on the left and the child on the right.
Save
Press Save… now and give the tree a name, before you experiment any further. There is still no safety net, and this is the first point in the tutorial where you have work worth losing.
04

Crucible and the debug bar

Watch it run

Run 3 agents ~3 min

Reading a tree tells you what it should do. Running it tells you what it does, and the two part company more often than you would like.

Drill04

Test in Crucible
  1. Set Agents in the toolbar to 3.
  2. Press Test in Crucible, the suite's testing lab. It drops live 3D agents into an arena and drives them with your tree.
  3. Watch for the fallback firing: agents who cannot see anyone should patrol, and the ones who spot the player should stop, pause for your Wait, then investigate.

Done whenYou have seen both branches happen at least once.

Drill04b

Read the trace
  1. Back in Sentinel, find the debug bar along the bottom: Stats, Heatmap and Analytics, plus a timeline scrubber.
  2. Open Stats to see how often each node fired.
  3. Drag the scrubber to step through the run tick by tick.

Done whenYou can point at the node that fired least and say why.

Key
A node that fired zero times is the most useful thing on that screen. It means a branch was never reached, which at this stage almost always means a wiring mistake rather than a design decision — and it is much easier to see in Stats than by staring at the canvas.
Later
That rule needs one qualification, which the advanced tutorial covers: a node can also read zero because the scenario you ran never called for it. Reading a run properly means asking whether the branch should have been reached before you go hunting for a broken connection.
05

Export

Ship it

Ship Info & Export ~2 min

Two steps, and the order matters more than it looks.

Do this

Set a version, then export

  1. Open Info… and set a version number. the version is written into the exported file, so it has to exist first
  2. Press Export…, which writes a versioned .behavior.json. this is the file the game actually loads
Order
Set the version before you export rather than after. Exporting first and versioning afterwards leaves you with a file whose contents disagree with the number you meant it to carry.
06

What actually gets exported

Four fields, and nothing else

Read .behavior.json ~8 min

Export a behaviour and open the file in a text editor. Every node in it looks like this, and only like this.

{
  "id":       "n7",
  "kind":     "Condition",
  "task":     "CanSeePlayer",
  "children": null
}

Four fields: an identity, a structural kind, the name of a task, and its children. There is no radius here, no target, and nothing describing how far this guard can see. CanSeePlayer is a word the game already knows. Sentinel is choosing which words to say and in what order, and the game decides what they mean.

Key
Sentinel authors a contract and the game fulfils it. Your tree is a script of task names and control flow. Everything behind those names — what counts as seeing someone, how patrolling works, what “in range” means — lives in the game's code rather than in your file.
exports fulfils In Sentinel tree shape task names blackboard declarations you author this .behavior.json kind · task · children blackboard[ ] two version numbers the contract In the game what each task DOES reads/writes the variables every actual decision someone else built this

Figure 01 — the division of labour Everything you can do in Sentinel lives in the left panel. Everything that makes a character behave lives in the right one.

07

The panel you were told to ignore

The Blackboard declares

Build 5 types ~10 min

Open a behaviour and look at the Blackboard on the right. Press + Add variable and you get a row: a name, a type dropdown, a default value, and a cross to remove it. Five types are available — Bool, Int, Float, String and Vector3.

Expect

This is the part that trips everyone up. Nothing in the editor connects a variable to a node. You cannot make a Condition test alarmRaised, and no Action can write to it. Declaring a variable does not change what your tree does inside Sentinel, and it never will.

That is not a missing feature so much as the wrong side of the line. Which line becomes clear as soon as you ask what the declaration is for.

It is the state half of the contract. When your behaviour ships, the game needs to know which variables this tree expects to exist, what type each one is, and what value it starts at. Declaring alarmRaised : Bool = false tells the runtime to allocate that variable, initialise it to false, and let the tasks use it.

The most useful way to read the panel is as a function signature. You are not writing the body; you are declaring what the body will be handed.

Do this

Declare the guard's state

  1. Load Templates → Patrol Guard again, then add three variables: alarmRaised as a Bool defaulting to false, lastSeenAt as a Vector3 defaulting to 0,0,0, and patrolSpeed as a Float defaulting to 1.5. one of each shape, so you can see how the types survive export
  2. Save, then export, then open the .behavior.json in a text editor. the file is the only place the declaration becomes visible
  3. Find your three variables in the blackboard array, names, types and defaults intact, sitting alongside the tree rather than inside it. that separation is the shape of the handoff
08

Control flow

What you really own

Build Decorator Parallel ~8 min

If the meaning of every task lives in the game, what genuine authoring power is left to you? Control flow. Selector and Sequence from tutorial one, and two more worth knowing.

Drill03

Decorator, and the Inverter
  1. Drag + Decorator from the palette. It defaults to Inverter.
  2. Note that it takes exactly one child. Try to give it two and the second connection will not take.
  3. An Inverter flips its child's result: success becomes failure, and failure becomes success.

Done whenYou can explain why that is more useful than it sounds.

Why it matters03b

Building a condition you weren't given

There is no CannotSeePlayer in the palette. The conditions available are CanSeePlayer, HealthLow, HasTarget and IsInRange, and that is the whole list.

Wrap CanSeePlayer in an Inverter and you have just built its opposite, without anyone having to add it to the vocabulary.

Try it
Add a Sequence under the Selector, above the Patrol branch. Give it an Inverter wrapping CanSeePlayer, then a Wait. The guard now pauses when it cannot see anyone, which reads as a nervous sentry rather than a metronome.
03b

Parallel, and why to be sparing with it

+ Parallel runs its children simultaneously rather than in order. It is the right choice when a behaviour genuinely overlaps — walking a route while scanning — rather than forcing two things into an artificial sequence.

Use it sparingly all the same. A Selector or a Sequence tells a reader exactly what happens next, whereas a Parallel says “several things, and the outcome depends on a policy”. It is the node most likely to make your tree hard to debug when you reach tutorial three.

09

Versioning

Two version numbers

Read Info & export ~6 min

Every exported behaviour carries two version fields. They do quite different jobs, and only one of them is yours.

FieldWhat it meansWho sets it
behaviorVersion Your version of this particular behaviour. Bump it when you change the tree. You, under Info…
primitiveSetVersion The version of the vocabulary itself — the set of task names Sentinel knows about. Stamped for you at export

The second one is doing real work. When Crucible loads a behaviour whose primitive set is newer than the one it supports, it says so out loud:

Primitive set v2 is newer than supported v1; unknown tasks will no-op.
Heed it

That warning is the difference between a bug you can see and a bug you cannot. Without it, a tree using a task the runtime does not recognise would simply do nothing — in one branch, intermittently — and you would go looking at your tree structure, which would be perfectly fine.

When you see that warning, stop and check versions before you debug anything else.

Habit
Set behaviorVersion under Info… before exporting rather than after. The value is written into the file at export time, so bumping it afterwards leaves you with a file whose contents disagree with what you intended.
10

Setup

Something worth debugging

Run 16 nodes 3 agents ~8 min

A five-node tree cannot teach you to debug, because you can hold all of it in your head at once. Sixteen nodes and three agents is the point at which you have to start measuring instead of reading.

Drill01

Load Elite Combatant and read its shape
  1. Open Templates → Elite Combatant. Sixteen nodes.
  2. Notice that its composites have names: Brain, Survive, Engage, Close or Strike, Search.
  3. You can rename any node, and at this size that is the difference between a diagram and a wall.

Done whenYou can describe the tree without scrolling it.

The shape01b

Child order is a priority list

Brain is a Selector, and its children run in order: Survive, then Engage, then Search, then a fallback. Fleeing outranks fighting, and fighting outranks looking.

That ordering is the personality. Move Survive below Engage and you have written a fanatic, without touching a single task name.

Do this

Run it with a swarm

  1. Set Agents to 3 and press Test in Crucible. one agent shows you a path; three show you a distribution
  2. Crucible opens and Sentinel connects to it over a local debug socket. the connection is what makes the capture automatic
  3. Wait for the status line to report the capture. the run is not reviewable until it says so
[INFO] (LiveDebug) Connected to Crucible live debug on 127.0.0.1:45599.
Live run finished — 53 tick(s) captured. Scrub or Play to review.

You now have a trace: every tick, for every agent, the status of every node, plus the blackboard values as they stood at that moment.

If it fails
If the live connection does not come up, the status line says so and adds “You can still 'Load Trace' once the run finishes.” The socket is a convenience. The trace file is the source of truth, and nothing downstream depends on the connection having worked.
11

The debug bar

Four instruments, in order

Measure Stats Heatmap Analytics ~12 min

Numbers first, then shape, then summary, then the moment. Reaching for them in that order saves you from forming a theory before you have any evidence.

02a

Stats — the numbers, on the nodes

Press Stats. Every node gains a line showing evaluations, successes, failures and running ticks.

Survive     53×  ✓0   ✗53  ↻0
HasTarget   53×  ✓53  ✗0   ↻0
Brain       53×  ✓18  ✗0   ↻35
Flee             · not reached

Those four rows already tell you the story of the run. Survive was checked on every tick and failed on every one, which means nobody got hurt. HasTarget succeeded every tick, so the enemy was visible throughout. Brain spent two-thirds of its life running rather than finishing, which is exactly what a Selector does while its chosen child is mid-action.

02b

Heatmap — where the pressure is

Press Heatmap and node headers tint by evaluation count, relative to the busiest node in the run. Because the scale is relative there is always something hot, so the brightness itself tells you little. What you are looking for is the shape: which spine of the tree the agent actually lived in, and which limbs stayed cold.

02c

Analytics — the summary that names suspects

ReadingThis run
Final outcomes3 success · 0 failure
Ticks and duration53 · 5.5 s
Nodes16
Dead branches6, never reached
Busiest nodeBrain, 53 evaluations

Below that sits a per-node table with success, failure and running percentages. The agent dropdown in the debug bar switches which agent you are inspecting, and when one agent out of three behaves differently, that dropdown is where you find it.

12

A correction to tutorial one

Dead is not broken

Unlearn 6 of 16 ~8 min

Tutorial one told you that a node which never fired is a wiring bug. That was a useful simplification for a five-node tree. Here is what is actually true.

This run reported six dead branches out of sixteen nodes — in the template that ships with the tool, on a run where all three agents succeeded. Flee was never reached because nobody's health ever dropped. Search and Investigate were never reached because the target stayed visible the whole time.

None of those branches is broken. They are insurance that this particular run did not need.

Key
A dead branch is only a bug if the scenario should have reached it. The question is never simply whether a node fired; it is whether it fired given what actually happened. Which means the dead-branch count is unreadable on its own — you have to know what the run was supposed to exercise before the number means anything.
no yes never ✓ did ✓ branch never fired should this run have reached it? correct — not a bug check the gate condition or scenario wiring below

Figure 01 — diagnosing a silent branch The whole flow hinges on the second box, and that is the one question the tool cannot answer for you.

13

The scrubber

Scrubbing to the moment

Narrow Blackboard, live ~6 min

This is where tutorial two pays off, and it is the only place in Sentinel where the contract you declared becomes something you can watch.

Drill04

Step through the run
  1. Drag the scrubber to walk the run tick by tick, or press Play to animate it.
  2. As you move, the graph shows each node's status at that instant.
  3. Watch the status bar, which shows the blackboard as it stood on that tick.

Done whenYou can stop on any tick and say what the agent believed.

The technique04b

Find the tick, then read the variables

Find the tick where behaviour diverged from what you wanted, then read the blackboard at that tick rather than at the end.

Most complaints of the form “the AI is being stupid” turn out to be a variable that was not what you assumed it was.

Tick 54/54 · Success    BB: distance=1.8  health=100  tar…

That is the contract from tutorial two, filled in. You declared distance and health, the game wrote them, and the trace recorded them. Nowhere else in Sentinel do blackboard variables carry live values, which is the practical reason declaring them carefully is worth the effort.

14

Putting it together

A worked diagnosis

Diagnose 4 steps ~6 min

Suppose your guards refuse to flee, however badly hurt they get. Work it in this order.

In order

From the silent node upward

  1. Open Stats and ask whether Flee is reached at all. If it reads not reached, the branch never ran. there is no point examining a node that never executed
  2. Look at its gate. HealthLow shows 53× ✓0 ✗53: evaluated on every tick and never once successful. a gate that never opens explains everything beneath it
  3. Take the fork. Either health genuinely never dropped, which is a scenario problem and means you fix the test rather than the tree; or it did drop and the condition disagreed, which is a contract problem, because the game's definition of “low” is not yours. these two look identical from the canvas and completely different in the data
  4. Scrub to a tick where the agent was hurt and read health in the blackboard. that single number tells you which of the two you have
Notice
What never happened in that sequence: you did not stare at the tree. Three of those four steps are instrument readings and the fourth is a single number, which is the whole difference between debugging and guessing.
Quirk
Root itself reports not reached with zero evaluations, in every run without exception. The trace records the nodes that Root drives rather than Root itself, so there is nothing wrong. Do not chase it.

Course complete

What you now know

Check yourself

  • Selector is or and Sequence is and. Everything else composes from those two.
  • Templates are the fastest way into a new tree, so read a working one before building your own.
  • Connections run out of a right slot and into a left slot, parent to child.
  • A node with zero fires in Stats usually means a wiring mistake — provided the run you watched should have reached it.
  • Save manually and often, because nothing in the tool will remind you.
  • Set the version before exporting, since it is written into the file.
  • A node compiles to four fields — id, kind, task and children — and nothing else travels with it.
  • Task names are vocabulary the game implements. Sentinel chooses the words; the game defines what they mean.
  • The Blackboard declares state for the runtime. It has no effect inside the editor, and that is by design rather than by omission.
  • An Inverter gives you conditions the palette does not ship, and takes exactly one child.
  • Parallel is powerful and costs you legibility, so reach for it last.
  • primitiveSetVersion is checked on load. Heed the warning before you start debugging your tree.
  • Name your composites. At sixteen nodes it stops being optional.
  • A Selector's child order is a priority list, and that ordering is the character.
  • Stats, then Heatmap, then Analytics, then the scrubber: numbers, shape, summary, moment.
  • Each node reads N× ✓a ✗b ↻c, and not reached means zero evaluations.
  • Dead branches are only bugs if the run should have reached them. Six of sixteen were dead here and every agent still succeeded.
  • Blackboard values are live in the scrub bar, which is the one place the contract becomes visible.
  • Diagnose upward from the silent node to its gate, and check the gate's success count before you touch anything.

That is Sentinel. It is the smallest tool in the suite with the richest debugging story — most of the value is in modules 10 onward, and they are worth revisiting the first time a tree does something you did not expect.