Blackboard code examples

Page overview

This page presents more code examples using blackboards. The aim is to familiarize you with different ways you may create and access blackboard data and share the data between various entities.

Writing, removing and reading

This code sample demonstrates writing data to blackboards and various ways of accessing and modifying it.

  • C++

  • C#

Blackboard testBlackboard;

testBlackboard.SetValue("floatValue", 1.5f);
float val = testBlackboard.GetValue<float>("floatValue");

testBlackboard.SetValue("customStruct", UserDefinedStruct{}); //you can use your own data types!
UserDefinedStruct structVal = testBlackboard.GetValue<UserDefinedStruct>("customStruct");

testBlackboard.RemoveValue("customStruct");
assert(!blackboard.ContainsKey("customStruct"));

if(sharedBlackboard->TryGetValue("customStruct", structVal))
{
  //this line won't be reached
}
Blackboard testBlackboard = new Blackboard();

testBlackboard.SetValue("floatValue", 1.5f);
float val = testBlackboard.GetValue<float>("floatValue");

testBlackboard.SetValue("customStruct", new UserDefinedStruct()); //you can use your own data types!
UserDefinedStruct structVal = testBlackboard.GetValue<UserDefinedStruct>("customStruct");

testBlackboard.RemoveValue("customStruct");
Assert.IsFalse(sharedBlackboard.ContainsKey("customStruct"));

if(sharedBlackboard.TryGetValue("customStruct", out structVal))
{
  //this line won't be reached
}

Shared blackboards

Apart from their individual private blackboards, entities can gain access to shared blackboards, identified by string keys. These blackboards can be used in various ways, see this page to learn more.

  • C++

  • C#

AIEntity entity_1;
AIEntity entity_2;

//shared blackboards are passed as std::shared_ptr<Blackboard>
std::shared_ptr<Blackboard> sharedBlackboard = std::make_shared<Blackboard>();

//the same blackboard can be added under different names to different entities
entity_1.AddSharedBlackboard("shared_alias_1", sharedBlackboard);
entity_2.AddSharedBlackboard("shared_alias_2", sharedBlackboard);

entity_1.GetSharedBlackboard("shared_alias_1")->SetValue("intValue", 1);
int value = entity_2.GetSharedBlackboard("shared_alias_2")->GetValue<int>("intValue");
assert(value == 1);
AIEntity entity_1 = new AIControlledEntity();
AIEntity entity_2 = new AIControlledEntity();

Blackboard sharedBlackboard = new Blackboard();

//the same blackboard can be added under different names to different entities
entity_1.AddSharedBlackboard("shared_alias_1", sharedBlackboard);
entity_2.AddSharedBlackboard("shared_alias_2", sharedBlackboard);

entity_1.GetSharedBlackboard("shared_alias_1").SetValue("intValue", 1);
int value = entity_2.GetSharedBlackboard("shared_alias_2").GetValue<int>("intValue");
Assert.IsTrue(value == 1);

Global shared blackboards

Sometimes you might not want to destroy some of your shared blackboards, even when there’s no entity accessing them at the moment. To achieve this, you can use global shared blackboards maintained by AI Managers. Such blackboards persist as long as their owning manager exists.

  • C++

  • C#

AIManager manager;
manager.CreateBlackboard("global_shared");

AIEntity entity_1;
AIEntity entity_2;
manager.SubscribeToBlackboard("global_shared", entity_1);
manager.SubscribeToBlackboard("global_shared", entity_2);

std::shared_ptr<Blackboard> shared_1 = entity_1.GetSharedBlackboard("global_shared");
std::shared_ptr<Blackboard> shared_2 = entity_2.GetSharedBlackboard("global_shared");
assert(shared_1 == shared_2);
AIManager manager = new AIManager();
manager.CreateBlackboard("global_shared");

AIEntity entity_1 = new AIEntity();
AIEntity entity_2 = new AIEntity();
manager.SubscribeToBlackboard("global_shared", entity_1);
manager.SubscribeToBlackboard("global_shared", entity_2);

Blackboard shared_1 = entity_1.GetSharedBlackboard("global_shared");
Blackboard shared_2 = entity_2.GetSharedBlackboard("global_shared");
Assert.IsTrue(shared_1 == shared_2);

Merging blackboards

Data stored in Grail blackboards can be easily merged. This code sample demonstrates how it’s done.

  • C++

  • C#

Blackboard blackboard_1;
Blackboard blackboard_2;

blackboard_1.SetValue("param_1", 1);
blackboard_1.SetValue("param_2", 2);

blackboard_2.SetValue("param_2", 5);
blackboard_2.SetValue("param_3", 3);

blackboard_1.Merge(blackboard_2, Blackboard::TheirsStrategy);
assert(blackboard_1.GetValue<int>("param_1") == 1);
assert(blackboard_1.GetValue<int>("param_2") == 5);
assert(blackboard_1.GetValue<int>("param_3") == 3);
Blackboard blackboard_1 = new Blackboard();
Blackboard blackboard_2 = new Blackboard();

blackboard_1.SetValue("param_1", 1);
blackboard_1.SetValue("param_2", 2);

blackboard_2.SetValue("param_2", 5);
blackboard_2.SetValue("param_3", 3);

blackboard_1.Merge(blackboard_2, Blackboard.TheirsStrategy);
Assert.IsTrue(blackboard_1.GetValue<int>("param_1") == 1);
Assert.IsTrue(blackboard_1.GetValue<int>("param_2") == 5);
Assert.IsTrue(blackboard_1.GetValue<int>("param_3") == 3);