About this manual
This manual explains the shared board (Blackboard) feature built into ACTION GAME MAKER.
How the shared board works in ACTION GAME MAKER
The shared board is a place for passing values and object references between objects. You define “keys” in the editor in advance, and read and write those keys during the game.
It differs from variables and switches in two ways.
- Keys are defined with a type, so as well as numbers and strings they can hold coordinates and references to objects themselves.
- The scope is chosen per key, so a key can either hold one value shared by every object, or a separate value per object.
Being able to hold an “object reference” is the biggest difference. “Which object am I aiming at” — previously only possible through the lock feature — can now be recorded on the shared board and handed to other actions and conditions. That lets you search for “the nearest enemy” or “the enemy with the most HP”, record it, and shoot at it.
Defining a key
Shared board keys are defined on the “Blackboard” tab (the fifth tab) of the “Configure Variables / Switches” window. You can open the window from:
- The “Configure Variables / Switches” button in the object editing view
- The “Configure Variables / Switches” button in the visual script view
- The “Configure Variables / Switches” button shown in the variable and switch settings in the Inspector
- The “Configure Project Variables / Switches” button in the database
Create a key with “Add” and configure it on the right.
- Name: the key name you pick from in a visual script.
- Scope: choose “Shared By All Objects” or “Per Object”.
- Type: the kind of value (see the table below).
- Initial value: the value at the start of the game. Object reference types have no initial value.
- Is Savable: tick it and the value is kept across save and load.
- Note: a memo about what it is for. It has no effect on behaviour.
The “References” button searches for where the selected key is used in your visual scripts. Deleting a key leaves any setting that referenced it without a reference, and it stops working, so reusing a key is preferable to deleting one.
Key types
| Type | What it holds |
|---|---|
| ON / OFF | The two values ON and OFF |
| Integer | An integer |
| Number | A number including decimals |
| String | A string |
| Position (Vector2) | An X and Y coordinate |
| Object Reference | A reference to one object |
| Object Reference List | References to several objects |
Choosing a scope
“Shared By All Objects” holds one value for the whole game. Use it for things everyone should see the same answer to: a boss defeat flag, the current destination, a reference to the player.
“Per Object” holds a separate value for each object. Use it for anything where the answer differs per object, such as “the player nearest to me”. Making that shared would have every object overwriting everyone else’s record.
Value lifetime and saving
- Values return to their initial value at the start of the game.
- They survive scene changes (a shared-scope value persists across maps).
- Keys marked “Is Savable” are kept across save and load. A per-object key is saved together with that object’s save data.
- Object reference keys are never saved, regardless of the setting. A reference is only meaningful while the game is running, and the same instance cannot be pointed at again after loading.
Actions and conditions
The actions for the shared board are in the “Switch/Variable” category under “Add Other Action”, and the conditions are in the “Variable” category under “Add Other Condition”.
SetBlackboardValue
Writes a value into a shared board key.
- Key Name: the key to write to.
- Operator: “=”, plus “+=”, “-=”, “*=”, “/=” and “%=” on number and integer keys.
- Value to assign: choose the source from “a number” or “a variable / switch”. On an object reference key you can choose “myself”, which records a reference to the object that ran the action.
- When taking it from a variable, specify where it lives (myself, a specified object, a locked object, my parent, the last contacted object, an object on the shared board, a project variable) and the variable name.
BlackboardValueCompare
Compares the value of a shared board key.
- Key Name: the key to test.
- Comparison: choose from “==”, “!=”, “<”, “<=”, “>” or “>=”. On an object reference key the only option is “Has Valid Object Reference”.
- What to compare against: choose from “a number”, “another shared board key” or “a variable / switch”.
“Has Valid Object Reference” on an object reference key can test whether the recorded target is still alive. A defeated target becomes an invalid reference, which lets you build a flow that goes looking for the next one.
SearchObjectToBlackboard
Records references to objects narrowed down by conditions onto the shared board.
- Key Name: the key to record into. Specify an object reference key or an object reference list key.
- Target group: choosing anything but “all objects” searches only within that object group.
- Max distance (0 for unlimited): narrows candidates by distance from you (px).
- Exclude Self (on by default): removes the searching object itself from the candidates.
- Sort Type: choose from “distance”, “an object variable” or “HP”.
- Sort Order: choose “ascending (nearest and smallest first)” or “descending (farthest and largest first)”.
- Sort Variable Name: the variable name used when the sort type is “an object variable”. The name candidates are enumerated from the “Sort Variable Scene Path”, but the actual values are read from each object found.
- Max Count: when recording into an object reference list key, how many of the top results to record.
If no object matches, an invalid reference (or an empty list for a list key) is recorded. Whether anything was recorded can be checked with “BlackboardValueCompare”.
What you can do with a recorded object
A shared board object reference key can be used to specify a target in the following places.
| Where | How to specify |
|---|---|
| Variable and switch selection fields | Choose “an object on the shared board” as the location to read and write the recorded target’s variables and switches |
| ChangeObjectProperty | Choose “an object on the shared board” as the target |
| SwitchVariableChanged | Choose an object on the shared board as the monitored target |
| CarryObject | Choose “an object on the shared board” as the way to specify the target |
| Bullet trajectory (the bullet database) | Choose “fly toward the object on the shared board” for the initial trajectory, and “home in on the object on the shared board” for the change |
Specifying an object reference list key behaves as follows.
- Fields that act on several targets at once (ChangeObjectProperty and the like) apply to everyone in the list.
- Fields that resolve to a single target use the first living entry in the list.
- Bullets are distributed across the list in the order they were fired. Match the number of shots to the number of targets and each one is aimed at a single target; anything beyond that wraps around from the start.
Objects that have already disappeared are dropped from the targets automatically, on every route.
Inserting values into text
The values on the shared board can be inserted into strings such as those in “DisplayText”. The notation is as follows.
| Notation | Output |
|---|---|
| <board.KeyName> | That key’s value. An ON / OFF type becomes ON or OFF |
| <board.KeyName> (object reference type) | The root node name of the recorded object. A list is joined with ", " |
A per-object key can only be read from somewhere its owning object exists. Where there is no owner — a label on the UI layer, for instance — only shared-scope keys can be used.
Checking the values at runtime
You can check whether values are what you expected in the AGM Debug Monitor. Open it from the Debug menu with “Open AGM Debug Monitor…” and look at the “Blackboard” tab.
- Double-clicking a value field lets you rewrite it (object references cannot be rewritten).
- Per-object values appear after that object has read or written the shared board.
Worked examples
A turret that aims at the nearest enemy
Build this in the turret’s visual script.
- Periodically run “SearchObjectToBlackboard”
- Key Name = the target to aim at (object reference / per object)
- Target group = enemies, Sort Type = distance, Sort Order = ascending
- Transition to the firing action only when “BlackboardValueCompare” says the key has a valid object reference
- Set the bullet database’s initial trajectory to “fly toward the object on the shared board” and point its key at the same key
Because the nearest target differs per object, set the key’s scope to “Per Object”.
Aiming at up to 3 enemies with the most HP
- Set the key type to “Object Reference List”.
- In “SearchObjectToBlackboard”, set Sort Type = HP, Sort Order = descending, Max Count = 3.
- Set the bullet to fire 3 shots and set the change to “home in on the object on the shared board”, and one shot heads for each of the 3.
A boss defeat flag
- Set the key type to “ON / OFF”, the scope to “Shared By All Objects” and Is Savable to ON.
- Set it ON with “SetBlackboardValue” when the boss is defeated.
- Have doors and events read the ON with “BlackboardValueCompare” and open.
The value survives scene changes and works with save and load.
Handing out a reference to the player
- Set the key type to “Object Reference” and the scope to “Shared By All Objects”.
- Use “SetBlackboardValue” in the player’s start action with the value to assign set to “myself”.
- Enemies and contraptions can then read the player’s variables by choosing “an object on the shared board” in a variable selection field.
Things to watch out for
- Writing to the shared board does not re-evaluate scene transition conditions (a deliberate difference from variables and switches). To change scene, do it with a variable or switch.
- Deleting a key leaves the visual script settings that referenced it without a reference. Check where it is used with “References” before deleting.
- Object reference keys are not saved. If you need to point at a target again after loading, run a search action after the load.
- Compound assignment (+= and so on) is only available on number and integer keys.
- A per-object key cannot be read from somewhere with no owning object (a label on the UI layer, for instance).