I've not watched that specific tutorial, however my own personal solution to this problem was to abstract away the saving and loading, and give each object two custom user events (6 for saving, 7 for loading).
Any object that wished to save its information would do so in that event, writing out to a global buffer. The loading process was the same in reverse.
The backend i created looks something like this (this is a simplified version, but encapsulates the core idea):
Global Save routine:
Code:
global.SAVE_BUFFER = buffer_create(...);
with(all){
// save core object properties
buffer_write(global.SAVE_BUFFER, buffer_u32, object_index);
buffer_write(global.SAVE_BUFFER, buffer_s32, x);
buffer_write(global.SAVE_BUFFER, buffer_s32, y);
// save custom object properties
event_user(6);
}
buffer_save(global.SAVE_BUFFER, "save_data.save");
buffer_delete(global.SAVE_BUFFER);
Global Load routine:
Code:
global.LOAD_BUFFER = buffer_load("save_data.save");
while(buffer_tell(global.LOAD_BUFFER) < buffer_size(global.LOAD_BUFFER)){
// save core object properties
var o_index = buffer_read(global.LOAD_BUFFER, buffer_u32);
var o_x = buffer_read(global.LOAD_BUFFER, buffer_s32);
var o_y = buffer_read(global.LOAD_BUFFER, buffer_s32);
// Create instance
var inst = instance_create(o_x, o_y, o_index);
// load custom object properties
with(inst){
event_user(7);
}
}
buffer_delete(global.LOAD_BUFFER);
Code:
// Example object event user 6
buffer_write(global.SAVE_BUFFER, buffer_u8, my_health);
buffer_write(global.SAVE_BUFFER, buffer_u8, my_level);
// Example object event user 7
my_health = buffer_read(global.LOAD_BUFFER, buffer_u8);
my_level = buffer_read(global.LOAD_BUFFER, buffer_u8);
Then inside event_user 6 and 7 of each object, they would have their own buffer_writes and buffer_reads (writing to global.SAVE_BUFFER, and loading from global.LOAD_BUFFER). This is a nice way of encapsulating saving and loading on a per-object basis. Regarding global variables, my personal approach is to make each controller responsible for the global variables they care about. Though in practise, most things end up not being global, but accessible through a series of functions that interface with the controller objects.
But a system like this basically allows you to give each instance its own custom saving and loading.
Some general notes/tips on how you can extend something like this:
- Doesn't need to be done with "all" instances, but perhaps you could create a list of object indices which need saving.
- You can keep track of the amount of data each object has written to the buffer, by measuring writing position before and after writing custom data. This allows your read routine to be a bit smarter and know how much data to expect in each instance, as a common problem here is if you make a mistake and end up reading more/less than you should, all sorts of nonsense arises.
- You can also assign objects a unique index on creation. If for example instances need to reference each other, GM instance id's will change between different runs, so it is useful to have a "global" array of all instances that need saving and loading and assign then a singular unique system ID that will remain the same between loads, along with a series of functions for fetching an instance from an ID and so on.
-- In this case, the only "core" properties I would bother to save are object index, x and y. This is because anything else is superfluous and could change for different instances. Theres no point saving information you dont need to save.
Hope this helps!