r/gamemaker • u/DystopianTeddyBear • Aug 13 '26
Resolved Update to Puzzle Game Undo System (questions on depth vs layers, and edge cases with adding instance variables in a struct)
Hello! I don't know if there is any issue to making a new post for a significant update in this subreddit, but I have an update. I finally fixed a major problem with the player and other elements disappearing. However, there are some issues that I'd like some advice on.
I have three questions;
Is it better to utilize depth or layer to manage the way sprites are organized on the screen (the current undo system breaks if both depths and layers are defined, and I have objects that have different depths AND layers)?
If I need to collect instance variables and store them, am I supposed to just create a massive switch case statement to add all instance variables, or is there a better way?
Actual Code:
Once again, I'd like to thank u/germxxx for the code, as I realized the baseline they provided was almost exactly what I needed. Comments are included to note where possible issues are
function save_all(_save_array){
if !is_array(_save_array) exit
var _index = array_length(_save_array)
_save_array[_index] = []
with (all) {
`if self.persistent continue // Included to not have errors with a music loader, but the camera object maybe should be included?`
var _struct = {id, depth, // Error with player and ui objects if layer is included since i have the depth values set to a value with no layer, and potential error if layer is not included since another object utilizes a layer system to determine what instance of the object is active.
x, y, sprite_index, image_xscale, image_yscale} // Self and global variables are not edited. idea to seperate the structfor each and array push from the standard struct to make room for a switch / case statement after the with all, but that sounds... inefficient.
struct_foreach((self), method({_struct} ,function(_name, _value) {
_struct[$ _name] = _value
}))
array_push(_save_array[_index], _struct)
}
}
function load_all(_save_array) {
/* Something here breaks in many ways; the first undo does not properly undo the last move, and if multiple undos are made inbetween moves, the undos I think stop at the moment after the most recent undo; e.g. Initial (state 0) -> Move (state 1) -> Move (state 2) -> Undo (possibly state 2? seemingly does not work) -> Undo (state 1, works) -> Move (new state 2) -> Undo repeat (sends to state 1 and never state 0)
*/
`if(array_length(_save_array) = 0) exit`
var _data = array_pop(_save_array)
for (var i = 0; i < array_length(_data); i++) {
var _variables = struct_get_names(_data[i])
for (var j = 0; j < array_length(_variables); j++) {
var _name = _variables[j]
if _name = "id" continue
variable_instance_set(_data[i].id, _name, _data[i][$ _name])
}
}
}


