derkork / godot-statecharts

A state charts extension for Godot 4
MIT License
761 stars 39 forks source link

Save/Load State #144

Closed TornadoStorm closed 3 weeks ago

TornadoStorm commented 3 weeks ago

Is it in any way possible to store and restore the current state of the state chart itself? I would like to use this addon with rollback netcode, which requires this functionality so that the chart can be "rewinded" to previous frames at any point if needed.

derkork commented 3 weeks ago

This feature is currently only partially implemented (for the history states) but that code could probably be adapted to store the whole state chart's current state when called at the right time. However implementing this at the state chart is only half of the story because usually you would also have scripts attached to the signals of the state chart and these scripts also have state which may not be as easy to roll back.

This is not public API, but have a look at: https://github.com/derkork/godot-statecharts/blob/main/addons/godot_state_charts/state_chart_state.gd#L144

Every state node has a _state_save function which saves the nodes state (and its subtree if needed) into a SavedState object. There is also _state_restore which restores the state from a given SavedState object. Theoretically you could call this on the root state and save/restore the whole tree state with it (i haven't tried this yet). You would probably need to add some code that saves the expression properties from the state chart node.

TornadoStorm commented 3 weeks ago

Thanks for the response & insight!

That should be fine. I'm using the Delta Rollback addon and there, anything that needs to have a state loaded and saved just needs to implement a _save_state() and _load_state() function, so attached scripts would also rollback on their own.

I am thinking of implementing a new node for the state chart similar to the history node, but has 3 fields; deep, save event and load event. When the save event is triggered, it collects and stores the state of the parent node (excluding anything from the current node), and then restores the parent node when load state is triggered, calling an exception if nothing was saved. Thoughts on this?

derkork commented 3 weeks ago

I'm not sure if this necessarily needs to be a child of the state chart but in general the approach should be workable. These things tend to have a ton of edge cases though so there will likely be some hiccup along the way. But only one way to find out 😁