Skip to content

Blackboard

The GoapBlackboard is the agent's unified runtime memory. All data flows through it — sensors write, beliefs read, strategies read/write, post-processes read/write. Each agent has its own blackboard instance.


Key Concepts

  • All keys are SerializableGuid — never strings. Keys are assigned in the GOAP Hub editor and serialized on settings classes.
  • SerializableGuid.Empty is the null/unset sentinel. Always check before using a key.
  • Every Set* call increments ContentRevision, which the planner uses as a cache gate to avoid redundant replanning.

Typed Getters

All getters return a fallback value if the key hasn't been written:

bool    val = blackboard.GetBool(keyId, fallback: false);
float   val = blackboard.GetFloat(keyId, fallback: 0f);
int     val = blackboard.GetInt(keyId, fallback: 0);
string  val = blackboard.GetString(keyId, fallback: "");
Vector3 val = blackboard.GetVector3(keyId, fallback: default);
GameObject obj = blackboard.GetGameObject(keyId, fallback: null);
Reading blackboard values from a MonoBehaviour
using UnityEngine;
using RGS.GOAP.Core;

public class AgentHealthUI : MonoBehaviour
{
    [SerializeField] private GoapAgent _agent;
    [SerializeField] private SerializableGuid _healthKey;

    private void Update()
    {
        float health = _agent.Blackboard.GetFloat(_healthKey, fallback: 100f);
        // Update your UI with the health value
    }
}

Typed Setters

The source parameter is for debug tracking — it shows "who wrote this" in the GOAP Hub inspector:

blackboard.SetBool(keyId, true, "MyStrategy");
blackboard.SetFloat(keyId, 3.5f, "MyStrategy");
blackboard.SetInt(keyId, 10, "MyStrategy");
blackboard.SetString(keyId, "alert", "MyStrategy");
blackboard.SetVector3(keyId, position, "MyStrategy");
blackboard.SetGameObject(keyId, target, "MyStrategy");
blackboard.SetObject(keyId, value, "MyStrategy");  // Boxed fallback for unusual types

Tip

Always pass a descriptive source string. When debugging in the GOAP Hub inspector, you'll see exactly which system last wrote to each key — invaluable for tracking down unexpected values.

Writing to the blackboard from an external game system
using UnityEngine;
using RGS.GOAP.Core;

// Example: An alarm system writes to the blackboard when triggered
public class AlarmSystem : MonoBehaviour
{
    [SerializeField] private GoapAgent[] _guards;
    [SerializeField] private SerializableGuid _alarmActiveKey;

    public void TriggerAlarm()
    {
        foreach (var guard in _guards)
        {
            guard.Blackboard.SetBool(_alarmActiveKey, true, "AlarmSystem");
            // The planner will detect the change via ContentRevision
            // and replan on the next tick — no need to call ForceReplan()
        }
    }
}

Utility Methods

blackboard.HasKey(keyId);       // True if a key has been written at least once
blackboard.ClearAll();          // Reset all stored values
blackboard.ContentRevision;     // Incremented on every write (read-only)

SerializableGuid

The universal key type — a Unity-serializable 128-bit GUID:

public struct SerializableGuid : IEquatable<SerializableGuid>
{
    public uint Part1, Part2, Part3, Part4;

    public static SerializableGuid Empty => new(0, 0, 0, 0);
    public static SerializableGuid NewGuid();
    public string ToHexString();
    public Guid ToGuid();
}

Keys are created in the GOAP Hub and referenced on strategy/sensor settings classes. You never construct them in code — they're serialized by the editor.


GoapKeyType

The type system for blackboard keys:

public enum GoapKeyType
{
    Boolean,
    Float,
    Vector3,
    Integer,
    Object,
    String
}

Regular Keys vs Temporal Keys

The blackboard stores two conceptually different kinds of data.

Regular Keys

  • Written by sensors or code directly (SetBool, SetFloat, etc.)
  • Instant snapshots — most recent write wins
  • No decay, no memory tracking

Temporal Keys

  • Managed by GoapRecollectionSystem
  • Sensors call ReportStimulus() instead of writing directly
  • The system tracks per-entity memory, decays confidence over time
  • An associated ValidityKey (boolean) is automatically set to true when any memory exists and false when all entries expire

Danger

Never write directly to a ValidityKey. The RecollectionSystem owns these keys and will overwrite your value on the next frame. Use ClearStream() to clear a temporal key.


Key Ownership Rules

Before writing to any blackboard key, determine who owns it:

Scenario Correct Action
Key is a ValidityKey (temporal) Use ClearStream() to clear; never write directly
Key is tracked by recollection Use sensor WriteVector3(settings, bb, name, value, target)
Key is regular (non-temporal) Write directly via blackboard.SetXxx()
Key is set by a PostProcess Write via blackboard.SetXxx() with source tag

ContentRevision

Every Set* call increments ContentRevision. The planner uses this as a cache gate:

  • If ContentRevision hasn't changed since the last successful plan, CalculatePlan() returns Unchanged without scheduling a Burst job
  • This prevents redundant replanning when nothing has changed
  • ForceReplan() bypasses this gate

Recollection System (Temporal Memory)

GoapRecollectionSystem provides temporal AI memory with confidence decay. It is the only truly optional agent component — add it when Brain.UsesSpatialMemory = true.

How It Works

  1. Sensors call ReportStimulus(keyId, target, position) to feed observations into memory streams.
  2. Each memory entry decays over Duration (default 5s). The best target is selected via Burst jobs using ConfidenceWeight and DistanceWeight.
  3. SyncToBlackboard() runs at execution order -10, writing the best result and updating the stream's ValidityKey.

API

recollection.ReportStimulus(keyId, target, position);  // Feed observation
recollection.ClearStream(keyId);                       // Clear all entries, reset ValidityKey
recollection.IsDrivingKeyById(keyId);                  // Check if key is a temporal ValidityKey
recollection.IsTracking(keyId);                        // Check if stream exists

MemoryTuning

Configure per-key memory behavior:

Field Type Description
KeyId SerializableGuid The memory stream's data key
ValidityKeyId SerializableGuid The boolean key that tracks "has valid memory"
Duration float Memory lifetime in seconds
ConfidenceWeight float (0–5) How much recency matters in scoring
DistanceWeight float (0–5) How much proximity matters in scoring

See Also

  • GOAPAgent — The component that owns the blackboard instance
  • The Planning Loop — How ContentRevision gates the planner
  • Performance Tuning — Avoiding unnecessary blackboard writes at scale
  • Glossary — Quick definitions for Key, Slot, Temporal Key, ValidityKey, and other terms

What's Next