• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

game_load_buffer() / game_save_buffer() and global data scope problem...?

N

Nick Pelling -- Orlando

Guest
I'm trying to use game_load_buffer() / game_save_buffer() to add simple checkpoints to my GMS2 game. However, I've ended well and truly confused. :-(

My main character starts with three lives:

(Main Character Instance -> Begin Room Event)
GML:
        level_buffer = buffer_create(512 * 1024, buffer_grow, 1);
        global.level_saved = false;
        global.level_lives = 3;
When the main character reaches a checkpoint, the level gets saved:

(Main Character Instance -> Begin Step Event)
GML:
        global.level_saved = true;
        buffer_seek(level_buffer, buffer_seek_start, 0);
        game_save_buffer(level_buffer);
When the main character loses a life and the level has been saved, the level is reloaded:

(Main Character Instance -> Begin Step Event)
GML:
        global.level_lives--;     // i.e. global.level_lives is now equal to 2
        if (global.level_saved)
        {
            buffer_seek(level_buffer, buffer_seek_start, 0);
            game_load_buffer(level_buffer);
            // Printing out global.level_lives here yields 2
        }
Even though this looks basically right, the moment that Main Character instance's Begin Step Event function exits, global.level_lives becomes 3 again, because that was the value written out by game_save_buffer() and loaded in by game_load_buffer(). So global.level_lives goes from 3 to 2 and then back to 3 again, which is not the desired behaviour. :-(

What is happening (I think):
* the Main Character Instance Begin Step Event code calls game_load_buffer()
* game_load_buffer() creates a new global instance and new object instances, which GMS2 queues up for activation later
* game_load_buffer() deactivates the global instance and all the object instances
* the Main Character Instance Begin Step Event code exits
* GMS2 destroys the old global instance and all the old object instances
* GMS2 activates the new global instance and all the new object instances

So it seems to me that global.level_lives won't ever function properly while it's in global, because all changes made to the old global instance (e.g. to global.level_lives) get discarded when the save buffer (e.g. saved global.level_lives == 3) gets loaded.

But if global is the wrong place for level_lives to live, where should it live? In an ideal world, you would be able to attach data to room instances themselves (i.e. created in a Begin Room Event and destroyed in an End Room Event), or to some "super-global" area. But I can't see any way of doing this in GMS2. How do people get around this? This feels like a pretty basic showstopper. :-(

Is game_load_buffer() / game_save_buffer() genuinely useful core functionality, or just a demo to get people sort-of going?
 
Last edited by a moderator:

Nocturne

Friendly Tyrant
Forum Staff
Admin
Is game_load_buffer() / game_save_buffer() genuinely useful core functionality, or just a demo to get people sort-of going?
This is pretty much it... Honestly, those functions were added because similar functions existed in old GM versions and people asked for them, but they really are NOT very good and only save a bare-minimum of data. You should 100% go with a more robustsolution that you have coded yourself. YYG published a tech blog I wrote on Friday that actually covers the basics of making a checkpoint system using buffers, which you may find useful: https://www.yoyogames.com/blog/564/coffee-break-tutorials-checkpoints-using-buffers-gm
 
Top