Things to not forget to do

There are a few things that need to happen which are easy to forget to do. Simple things. So here's the most common things to make sure one does to avoid a head-scratching situation.

Add Required Prefabs to the scene

Game Modules 4 comes with a few required prefabs. Without these, Game Modules just won't work.
You can find these here: Assets/InfinityPBR/---Game Modules/_Required Prefabs

Make sure GetOtherLevels() is fully populated

The Stats module requires a GetOtherLevels() method, which will provide all the ModificationLevel objects attached to things that aren't Stat objects. This is important, as otherwise the values from those -- Items, conditions, etc -- won't be included in the final Stat calculations.
If your characters inherit from the new GameModulesActor class, GetOtherLevels() is already completed. However, you may want to override it if you have added other objects which may affect the final stat values for your actor.
Check out DemoActor.cs from the Party Based RPG demo project, which overridees the GetOtherLevels method on GameModulesActor.
// This is the code from the Party Based RPG demo project on the DemoActor.cs class
public override List<ModificationLevel> GetOtherLevels(bool cache = false)
// If we have already cached our other levels, and we are not caching them again, then return what we have
if (_modificationLevels != null && !cache)
return _modificationLevels;
var otherModificationLevels = new List<ModificationLevel>(); // We will create a new list
// Add modifications from the Game Module lists
otherModificationLevels.AddRange(conditions.ModificationLevels); // Conditions on the player
otherModificationLevels.AddRange(quests.ModificationLevels); // Quests the player has
otherModificationLevels.AddRange(equippedItems.ModificationLevels); // Equipped items
// Add the race and class modifications
if (!string.IsNullOrWhiteSpace(ActorRace.objectName)) otherModificationLevels.Add(ActorRace.ModificationLevel);
if (!string.IsNullOrWhiteSpace(ActorClass.objectName)) otherModificationLevels.Add(ActorClass.ModificationLevel);
// Add modifications from the Party (GameData) lists
otherModificationLevels.AddRange(GameData.gameData.quests.ModificationLevels); // Party quests that affect all players in the party
_modificationLevels = otherModificationLevels; // Cache the values
return otherModificationLevels; // Return it

Add vs "Transfer" (you often will want Transfer)

Adding a Game[OBJCET] to a Game[OBJECT]List can be done with Add() or TransferTo() / ReceiveTransfer().
Add() adds a vanilla copy of the GameItemObject. To transfer a Game[OBJECT] as it exists, you can use TransferTo() and ReceiveTransfer().
These methods are available in most of the Game[OBJECT]List classes, such as GameConditionList and GameItemObjectList.


To transfer a complete object from one list to another, use the TransferTo() method. You will specify the other list to transfer the object to and the object. The method will call the ReceiveTransfer() method on the other list, which returns a clone of the object if it is successful.
After that, the object will be removed from the original list, and the clone in the other list will be returned back to you.


Use this method to take in a fully formed object into your list. By default, a clone of the object will be made.
Some types, such as Conditions, have additional logic. If a GameCondition object is not stackable, and the GameConditionList already has one of the same name, it will update the existing condition, and return the object, rather than adding a 2nd copy of the condition.

Static reference to Blackboard is MainBlackboard

You are able to have multiple Blackboard objects in your scene. To help keep the required blackboard separated, the static reference to it is MainBlackboard.
The Blackboard prefab in the _Repository Prefabs folder has a MainBlackboard component on it, which creates the static reference to this objects Blackboard, which you can access with MainBlackboard.blackboard.