# Save Blackboards and StateTrees

> A guard remembers whom it chased and how alert it was, and a door's StateTree is back in the state it was in after a load, travel and streaming: attach the...

Product: Rolly Save 1.0.0 | Sheet: guide | Updated: 2026-10-31 | HTML: https://rolly-docs.pages.dev/save/guides/save-ai/

## Attach the AI handlers to your AI pawns

1. Open the Save Rule that matches your AI pawns, or the pawn's Rolly Save component (see [Choose what saves](https://rolly-docs.pages.dev/save/guides/choose-what-saves/)).
2. Under **Handlers**, add an entry and pick **Blackboard** under Engine State in its class menu for a Behavior Tree's blackboard, and another with **StateTree** for StateTree components (see [Attach engine state handlers](https://rolly-docs.pages.dev/save/guides/engine-state/#attach-engine-state-handlers)).
3. Expand the entry to set what it saves; every setting has a default that works without a change.

![AI handlers in a Save Rule](https://rolly-docs.pages.dev/save/_files/Images/RuleEditor_AI.png "DA_Guards in the rule editor with its Montages, Blackboard and StateTree entries open, and the StateTree entry's Apply Timing menu with Before Begin Play disabled and the reason in its tooltip.")

| Handler | Attach it to | It saves |
|---|---|---|
| Blackboard | AI pawns whose AI controller runs a Behavior Tree | The keys of the controller's blackboard, then restarts the Behavior Tree with them |
| StateTree | AI pawns, and any actor with StateTree components, such as a door | Whether each tree runs, its parameters, the states it is in, and a tree your game set with Set State Tree |

- Attach both to the **pawn**. An AI controller never saves itself, so a rule that matches controllers saves nothing of them; the handlers read the pawn's controller.
- **Apply Timing** is After Begin Play by default. The values are set on a tick after the pawn's Begin Play, once its AI is ready (see below), never inside the load's own calls. **When Asked** waits for Apply Saved Values; Before Begin Play is not offered (TimingNotOffered).
- Only the server or a standalone game sets AI state, since AI runs there.

## Choose which Blackboard keys save

The Blackboard handler saves every key of the controller's blackboard but **SelfActor**, which the controller sets from the pawn.

- **Keys** saves only the keys it lists, such as TargetActor; empty saves every key.
- **Not Saved Keys** leaves keys out, such as those your controller sets again when it possesses the pawn.
- Bool, Int, Float, Name, String, Vector and Rotator keys save their values; an Enum key saves its enumerator's name, so an update that renumbers the enum keeps the value; a Class key saves its class; an Object key saves an actor by its save ID, the local player's pawn included, which the load finds again in the new world, or an asset.
- An Object key whose actor is in a level that is not loaded at the load is empty.
- **Restart Logic** (on) restarts the Behavior Tree once the values are set, so it decides again from them. A tree that sets keys as it starts sets them again then, over the saved values. While a tree restarts no observer of the blackboard is told of the loaded values; an AI controller that runs no tree, and watches keys with its own observers, hears each loaded value either way. Off, the running tree goes on and its decorators hear the keys that changed.
- A blackboard saves at most 1,024 keys; a setup warning names the actor past the limit (TooMany).

## Make sure the AI is ready

The Blackboard handler is ready once the pawn's controller has a blackboard, which it gets when it runs its Behavior Tree. The StateTree handler is ready once each saved tree that was running runs again. Rolly Save checks at the apply, then when the pawn gets a controller, each followed by the next tick. An AI that is still not ready keeps its values waiting, and the Message Log says why, once per pawn class and handler per load (AINotReady); **Apply Saved Values** for the pawn sets them later.

- **Placed pawns** get their AI Controller Class as their level starts with **Auto Possess AI** at its default, Placed in World, also in a level that streams in later.
- **Pawns your game spawns** get no controller with the default Auto Possess AI: your game possesses them, such as with Spawn Default Controller, or Auto Possess AI is Spawned or Placed in World or Spawned.
- **Spawn Missing Controller** (on) gives a pawn that a load spawned again its AI Controller Class, since it comes back without one. A pawn whose AI Controller Class is None gets none, and the Message Log says so (ControllerNotSpawned). Off, its values wait until your game possesses it and calls Apply Saved Values.
- **Run the Behavior Tree in On Possess or Begin Play** of the controller. A controller that runs it later, such as after a cutscene, waits with AINotReady: set Apply Timing to When Asked and call Apply Saved Values once the tree runs.
- A pawn your game possessed during play that the level places without a controller, such as one with Auto Possess AI Disabled, waits with AINotReady until your game possesses it and asks.

### Blueprint

In the controller, after **Run Behavior Tree**, call **Apply Saved Values** with the controlled pawn. The AI handlers set the values on the next tick, outside the Behavior Tree's own calls, so it is safe to call from a task; for the same reason it returns false when only AI values wait, so do not read false as a new game for an AI pawn.

On a load that opens its map, the records of When Asked AI handlers are read at Apply Saved Values, once the local players have their pawns, so a key that names the player's pawn finds it. A placed pawn's controller possesses it as the map's actors initialize, before the load reads their records: an ask in On Possess there is asked again as the world begins play. Until the ask, the pawn saves as usual and a save keeps its handler's saved values.

### C++

```cpp
#include "Game/RollySaveSubsystem.h"

void AMyGuardController::OnPossess(APawn* InPawn)
{
	Super::OnPossess(InPawn);
	RunBehaviorTree(GuardTree);
	// With Apply Timing When Asked on the Blackboard handler of the guards' Save Rule.
	URollySaveSubsystem::Get(this)->ApplySavedValues(InPawn);
}
```

## Save StateTrees

The StateTree handler saves each StateTree component of the actor and, for a pawn with **Include AI Controller** on, of its AI controller, such as a StateTree AI component.

- It saves whether the tree runs; a tree saved stopped is stopped after a load.
- **Save Parameters** (on) saves the parameters set on the component (their override ticked) and sets them again, marked as set, so the tree's defaults do not replace them. The engine gives every other parameter the tree's default whenever it reads them, so a load puts those back to their defaults.
- **Save Active States** (on) saves the states the tree is in, through linked subtrees and linked StateTree assets. After a load the tree starts again with the saved parameters and enters the saved states; their tasks start again.
- A tree your game set with Set State Tree comes back; a component on its tree from the editor keeps the tree an update gives it. For the controller of a pawn your game spawns, that streams in or that a load spawns again, the tree its AI Controller Class's StateTree component holds in its class defaults counts as the editor's; a controller that gives its component a tree in its own code saves that tree with every save.
- **Components** narrows the StateTree components it takes by name, class or component tag.
- One actor saves at most 256 StateTree components. A path is entered again when it holds at most 8 states in each linked level, the engine's own limit, and at most 8 linked levels, Rolly Save's: a tree nested deeper starts at its root after a load (HandlerValueSkipped).

**Start the tree before the handler applies.** A StateTree component with **Start Logic Automatically** starts at Begin Play, before the handler applies. A tree your game starts later waits with AINotReady: set Apply Timing to When Asked and call Apply Saved Values after Start Logic.

**StateTree AI components on spawned pawns.** The AI schema's tree needs the pawn, which a controller spawned for a pawn in play does not have at its own Begin Play, so Start Logic Automatically cannot start it there. Untick it and call Start Logic in the controller's On Possess.

## Keep keys and parameters a save can hold

- A **Struct** key saves the members of its struct that have **SaveGame** ticked, as every struct Rolly Save saves (a Blueprint struct: each variable's advanced options).
- A StateTree parameter of a struct type saves all its members.
- A struct whose code writes its own bytes cannot be saved inside a key or parameter: the save leaves it out and succeeds, the Message Log says so once per session (KeyLeftOut, ParameterLeftOut) and each save's Issues list it. Use a struct of plain variables, or list the key in Not Saved Keys, or untick Save Parameters.

## Change AI after release

The AI handlers set their values a tick after the load reported, so the lines below go to the log as warnings, not into the load's Issues.

- **Keys by name and type.** A load sets the keys the controller's blackboard has under the saved name and type, whatever asset it is. When the blackboard is another asset than the saved one, and neither's parent, the log says so (BlackboardChanged) with how many keys were set. A key the blackboard no longer has keeps its default, with HandlerTargetMissing; the next save drops it.
- **States by ID.** A state an update removed or moved is not entered: the tree stays where it starts, with HandlerTargetMissing. Parameters match by their ID, so a renamed parameter keeps its value.
- A value no key takes, as an edited or damaged save can hold, is skipped with HandlerValueSkipped; a record with more entries than a save holds sets the first ones, with HandlerEntriesDropped.

## What is not saved

- Where a Behavior Tree was: it restarts from its root with the saved keys.
- Task memory, StateTree evaluators and global tasks, which start again.
- Instance-synced keys: each pawn saves its own, and the last pawn loaded wins.
- States of linked StateTree overrides your game added during play.
- Mass StateTrees.
- The AI controller's own variables: save them on the pawn, or in a Save Handler of your own (see [Save what is not a variable](https://rolly-docs.pages.dev/save/guides/save-handlers/)).

## See AI state while you test

- **Effective Settings** of a pawn's Rolly Save component lists the AI handlers with what they find: "Blackboard · the blackboard of BP_GuardController", naming the pawn's AI Controller Class, and "StateTree · 1 StateTree component on BP_GuardController", counting the trees on the pawn and, with Include AI Controller, on its controller. A handler that finds nothing, such as Blackboard on a controller, shows a warning icon with "finds nothing" and why.

![Effective Settings of an AI pawn](https://rolly-docs.pages.dev/save/_files/Images/EffectiveSettings_Handlers.png "BP_Guard_1's Effective Settings: Save Physics Velocity, Save Physics Sleep and Save Level Instance State subdued as not used, and the Montages, Blackboard and StateTree lines with what each finds, their settings from DA_Guards.")

- The **Save Inspector** names a pawn's AI records by the pawn and handler, such as `/Game/Maps/Tavern:BP_Guard_1 › StateTree`. A StateTree's parameters show as a property bag, "2 values" of type Property Bag, whose values can be read but not changed there: export the save as JSON, change the value and import it, or change it in your game and save again. Running Game's Waiting Records name AI values that wait "for its AI controller", "for its blackboard" or "for its StateTree to run".

![A StateTree record](https://rolly-docs.pages.dev/save/_files/Images/Inspector_StateTree.png "BP_Guard_1's StateTree record in the Save Inspector: the tree on its controller, running, its Parameters bag open with Alertness and Route, and its two active states.")

- The Gameplay Debugger's **RollySave** category shows, for the pawn you look at, each AI handler with whether the last load restored it or what it waits for, and what it holds now: the blackboard with how many keys saved and whether the last load restarted its tree, and each StateTree with whether it runs and the states it is in. Without an actor, a line counts the handlers the last load restored and those that wait, for Begin Play, for AI and When Asked.

![The RollySave category for an AI pawn](https://rolly-docs.pages.dev/save/_files/Images/Debugger_EngineState.png "The RollySave category for BP_Guard_1: its Montages, Blackboard and StateTree handlers restored at the last load, each with what it shows now, then the game's Handlers line.")
