NodeCanvas Forums › Support › Save state and the current active node in State Machine
Hi,
I’m not sure whether this has been questioned before, but is it possible to save all the variable and the current active node when player playing a game? if that is possible, what is the best way to do it.
Thanks
We required the same (saving execution state of FSMs) and there isn’t official support for doing that (correct me if I’m wrong). We settled with the following, although it restricts the usage of FSMs a bit:
– Implement a new custom FSM node called “Checkpoint”, which has a GUID assigned to uniquely identify it (node identities themselves could change when the FSM is edited which is often the case during development, so we need to rely on a more robust way of identifying the same checkpoint across different FSM versions)
– Checkpoint will store its GUID and the serialized blackboard content into two blackboard variables, like “__checkpoint_id” and “__checkpoint_blackboard”. This essentially gives us a execution state snapshot when the checkpoint state is crossed
– To store FSM state, we write the two checkpoint variables of the blackboard into the savegame
– To restore the FSM state, we load the checkpoint id and blackboard data from the savegame, de-serialize the blackboard contents and set the recovery checkpoint node to the start node of the fsm. This will restart the FSM at the checkpoint it was stored at with the same blackboard contents
Some more magic may be required to make this fully work, though, like using proxy objects in the blackboard that can be serialized to recover game object references upon restoration, as the blackboard won’t reliably store UnityEngine.Object
references when serializing a blackboard at runtime.
Hello adib and thanks for your input zsoik 🙂
Blackboard variables can indeed be stored/restored by serializing and then deserializing the Blackboard to json string with the existing methods Blackboard.Serialize() and Blackboard.Deserialize(string json). You can then probably use this json string returned by Serialize as a part of your save game, pretty much similar to how zsoik suggests. As zsoik stated too, UnityEngine.Object variable references will not persist through Serialize/Deserialize though, since such Object references can’t really be serialized to json in any usable way.
Regarding the current active node, if you are referring to the FSM system, then you could save the name of the current state which can be retrieved through the ‘FSMOwner.currentStateName’ property and then use ‘FSMOwner.TriggerState(string name)’ to basically force enter the previously saved state node when loading. You will of course need to have explicit state names for this to work correctly.
zsoik’s suggestion is also quite nice as well 🙂
Let me know if either of this works for you, or if I can help in any further way.
Thanks
Join us on Discord: https://discord.gg/97q2Rjh
First of all, thank you all for your support. I’m in the middle of creating simulation game and use FSM system in NodeCanvas for creating the flow of the main story. The problem is, i need to save the current FSM state when player exit the game. So What i’m looking for is exactly like the Gavalakis answer. I didn’t expect that it could be done that easily. this is a truly awesome component.
Exactly what we do, too 😉 But we found lots of problems with a more generic approach because we have more complex conditions and actions that store state and we can’t reliably just enter any state without running into race conditions. Ideally each action and condition would support storing its state (like timeouts etc.) or store state directly in the blackboard so we could restore the exact FSM execution state. If you make any progress there I really like to hear about it!
Whoops this is also happened to me. Imagine this scenario, i have a node named “add money” that responsible for adding money to the player, the next node won’t be trigger for a while so the currentStateName is “add money”. Before the next node triggered, the player exit the game, and the game manager save currentStateName (which is “add money”). When player load the game, the game manager will load the last node using ‘FSMOwner.TriggerState(‘add money)’. This where the problem arise, the FSM will trigger the “add money” node, and the player will get another money. Is there any way to set the FSM state without trigger it?
Exactly what we do, too But we found lots of problems with a more generic approach because we have more complex conditions and actions that store state and we can’t reliably just enter any state without running into race conditions. Ideally each action and condition would support storing its state (like timeouts etc.) or store state directly in the blackboard so we could restore the exact FSM execution state. If you make any progress there I really like to hear about it!
Hello again,
Hmm, There is currently no good way to set the current state without also triggering it, and without some source code changes, because triggering the state is required to also enable the conditional transitions it has.
If you are interested in that, I can make the required source code changes and send them to you.
Join us on Discord: https://discord.gg/97q2Rjh