Trending
Opinion: How will Project 2025 impact game developers?
The Heritage Foundation's manifesto for the possible next administration could do great harm to many, including large portions of the game development community.
Featured Blog | This community-written post highlights the best of what the game industry has to offer. Read more like it on the Game Developer Blogs or learn how to Submit Your Own Blog Post
The Blackboard System is a system to decouple features, creating a solid architecture, with easy implementation, maintenance and a helpful editor tool.
UPDATE
This article, is a part of Dead Body Falls dev series:
Creating Decoupled Features: The Blackboard System
During game development, we create many systems to meet the project’s requirements. We have a lot of small and big features, and their systems need to communicate with each other to execute a certain actions or events, check/use/change values and so on. All that to maintain the correct game flow with easy modification, implementation and maintenance of the core architecture.
Our most recent game, Dead Body Falls, is a story-driven experience where you have to interpret a storyline through different perspectives (Rashomon Effect), made by Black River Studios. The game uses a data communication system that we called Blackboard. In this article, I’ll talk a bit about this system, the idea behind it and how it works.
Disclaimer: Dead Body Falls was developed using the Unity engine. Some terms and functionalities described are exclusive or directly related to the engine. However, by understanding the main concepts of the system, it’s possible recreate the idea in other applications without many restrictions.
To provide a means of data access and communication between systems, one of the first ideas that might come up is using singletons to simplify the access to the other systems. This design pattern is very useful, but its application is often inappropriate. The disadvantage of the singleton is that it creates a strong dependence between the systems in the game. This can cause a lot of issues in future changes and for the project’s maintenance (which is usually necessary). Another option, and a better one, is using dependency injection. It doesn’t have the singleton disadvantages, allowing for the creation of decoupled systems. However, when doing this in Unity, we have to deal with performance, serialization and implementation problems. This results in a burdensome and slow process and our goal is a simple and fast one.
Let me open a short parenthesis with an advice that helps our development thinking process a lot. The idea is to dissociate software development from game development. This opens new ways to solve project problems, but this topic is for other time. Getting back, thinking in this concepts, looking at the advantages of these previously mentioned patterns , we decided create our own system and tool.
The development of this system was a combination/evolution of other systems and tools that we created inside the studio. Projects like Finding Monsters and Rock & Rails used the messaging pattern in their systems. It was very functional, but had some limitations and played by the book a little too much. In the game Angest, this system was a improved with a editor tool, bring closer to what we have today.
We gathered the following requirements for this new system in Dead Body Falls:
Data Control;
Messaging System (with any kind);
User Friendly (for others area usage);
Extendible (Easy to implement new modules);
Unity Resource (Use provided features by Unity).
Thus, was created the Blackboard System. A system to decouple features, creating a solid architecture, with easy implementation and a helpful editor tool.
The Blackboard is a messaging and data system. During the game, it can load what we call boards. In the following sections we will show how the board works in the game. Below is a simplified diagram of the system.
The boards have a list of values/data that can trigger a event, and everyone who registers in this event can listen to the message and can get and set the data. For the Dead Body Falls project, we use just a global board, but the system allows to loading multiple boards at once.
In the board, each row has a unique key/ID used to access their data or dispatch an event. All keys are converted to hash-int to improve the performance on search and access. The second column of the board row data has the value or, as we call it, data variable. This data can be any object derived from a Scriptable Object. Some values have an empty variable, because the listeners are only interested in the event itself. The last two columns are for debugging purposes: the first is the “Invoke” button, which forces triggering the event the trigger of the event. The second, the Listeners, shows a list of all the listeners registered to the event.
The Blackboard treats the values/data as variables, like mentioned before. These variables have Scriptable Object as their base class. For those who aren’t familiar with Scriptable Object, I recommend these two videos from past Unites (I really recommend watching these videos!):
In short, Scriptable Object are shared data assets, with their own functions and variables, like any other class.
In Unity, it’s easy to change values, make references, create a custom editor for a ScriptableObject. They are user friendly for those who are non-programmers, for example, a game designers or testers who needs to see the values or a object behaviour. For this reason we use the Scriptable Object.
Primitives types (string, int, bool, etc) are available by default and new custom variables can be created as needed. This is similar to PlayMaker FSM variables.
The Data Variables are indexed on the board along with their keys, the board working as manager and controller. However, the Data Variables can be referenced directly by other components like a normal Scriptable Objects.
Below, an example of blackboard system and tool.
private void Start() { m_blackboardController.AddListener(BlackboardVariable.MyInt4, OnIntValue); m_blackboardController.AddListener(BlackboardVariable.MyCustom1, OnCustomtValue); } private void RemoveListners(ScriptableObject scritableObject) { m_blackboardController.RemoveListener(BlackboardVariable.MyInt4, OnIntValue); m_blackboardController.RemoveListener(BlackboardVariable.MyCustom1, OnCustomtValue); } private void OnIntValue(ScriptableObject data) { IntVariable variable = (IntVariable)data; m_textMesh.text = variable.m_Value.ToString(); } private void OnCustomtValue(ScriptableObject data) { CustomVariable variable = (CustomVariable)data; m_camera.backgroundColor = variable.m_ValueC.m_BgColor; m_textMesh.color = variable.m_ValueC.m_Color; }
BlackboardExample.cs
According to the initial requirements, the Blackboard was planned to be extensible. Two new modules have been added in the Blackboard in this project. The first one is for choosing which values the save system must load and save. The second one is used to send the value to the Unity Analytics service.
Through the Blackboard, we decoupled features in Dead Body Falls, facilitating the handling of the systems and increasing the quality and speed of the game development. Our next step to improve the Blackboard is enhancing the tool editor with new functionalities and better response to the triggered events.
It’s important to point out that the Blackboard isn’t the magic answer for all project requirements or problems. Using it within a system whose individuals parts can communicate through simpler means doesn't make sense. Defining the role for the blackboard in the architecture is very important to the development.
Finally, I would like to thank the Black River Studios team. In particular, the talented to Dead Body Fall’s engineering team, that I could work with as Lead Engineer: Tayana Bacry, Luisa Nunes and Felipe Getúlio. Also, I’d like to thank Anderson Campos, who helped me come up with the Blackboard concept.
Read more about:
Featured BlogsYou May Also Like