• 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!

Legacy GM Buffer saving and loading problems [Solved]

Anixias

Member
Okay, so my problem is probably a lot more complicated than you'd originally think. I am making a fairly complex game, using realistic physics (I even found the speed of light in px/f in my game!), and I have a spaceship builder.

The builder part is fine, just a grid containing the parts making up the ship. I run a few checks to make sure the ship is closed, and meets a whole bunch of criteria.

Well, the hard part comes when you change from the building layer to the painting layer. I build a drawing program into the ship builder, where you can paint on the ship. I simply use surfaces and draw_set_blend_mode_ext(bm_dest_alpha,bm_zero) so that blank parts are always blank, and all parts and inside-the-ship tiles (even if there is no part there) are always opaque. You just choose the color of parts on the exterior of the ship.

This part is fine. The problem is, whenever you change layers, the painting surface is destroyed and buffer_get_surface is called to hold the surface. Well, I had a problem with that, so I also had to store the width and height of the surface, so when I call buffer_set_surface, the surface is at the right size.

Now, it works fine that way. But whenever you save the ship, I originally made a temporary ds_map. A key for the grid of parts, a key for the surface width, a key for the surface height, and a key for the buffer as a base64_encode.

Now, whenever I load the file, everything is perfect, except the buffer loads as solid black. Opaque, not just black, so it lost all data. The reason it is the correct size is due to me saving the surface size.

So I tried changing my approach. Now I call buffer_save and save to a file in a different folder from the ship. The file is named the same as the ship but has a different extension. It still loads as solid black. I cannot figure out why.

platebuff is the buffer holding the surface. platebuff_w and platebuff_h hold the surface size

Saving code:
Code:
//Save Ship!
        //First, get a name for the ship
        var name = "";
        while(name == "")
        {
            name = get_string("Name your ship:","");
        }
        while(file_exists("Data/Ships/"+name+".shp"))
        {
            name = "";
            while(name == "")
            {
                name = get_string("That ship name is already in use! Rename your ship:","");
            }
        }
        var f = file_text_open_write("Data/Ships/"+name+".shp");
        var data_map = ds_map_create();
      
      
        buffer_seek(platebuff,buffer_seek_start,0);
        if surface_exists(psurf)
        {
            platebuff_w = surface_get_width(psurf);
            platebuff_h = surface_get_height(psurf);
            buffer_get_surface(platebuff,psurf,0,0,0);
        }
      
      
        data_map[? "buff_w"] = platebuff_w;
        data_map[? "buff_h"] = platebuff_h;
        buffer_save(platebuff,"Data/Ships/bfdat/"+name+".bfd");
        data_map[? "parts"] = ds_grid_write(parts);
        file_text_write_string(f,ds_map_write(data_map));
        file_text_close(f);
        ds_map_destroy(data_map);
        data_map = undefined;
Loading code:
Code:
var name = get_string("Enter the name of a previously saved ship:","");
        if name != ""
        {
            var file = "Data/Ships/"+name+".shp";
            if file_exists(file)
            {
                var f = file_text_open_read(file);
                var data_map = ds_map_create();
                var str = "";
                while(!file_text_eof(f))
                {
                    str += file_text_readln(f);
                }
                file_text_close(f);
                ds_map_read(data_map,str);
                ds_grid_read(parts,data_map[? "parts"]);
                surface_free(psurf);
                if buffer_exists(platebuff) buffer_delete(platebuff);
                platebuff = buffer_load("Data/Ships/bfdat/"+name+".bfd");
                platebuff_set = true;
                platebuff_w = data_map[? "buff_w"];
                platebuff_h = data_map[? "buff_h"];
                buffer_seek(platebuff,buffer_seek_start,0);
                ds_map_destroy(data_map);
                data_map = undefined;
            }
            else show_message("No ship with that name found!");
Remaking the surface from the buffer code:
Code:
        if platebuff_set
        {
            var bfsurf = surface_create(platebuff_w,platebuff_h);
            buffer_seek(platebuff,buffer_seek_start,0);
            buffer_set_surface(platebuff,bfsurf,0,0,0);
            //surface_save(bfsurf,"bfsurf.png");
            var deltax = plate_minx-minx;
            var deltay = plate_miny-miny;
            for(var j = 0; j < surface_get_height(psurf); j++)
            {
                for(var i = 0; i < surface_get_width(psurf); i++)
                {
                    if i-deltax == clamp(i-deltax,0,surface_get_width(bfsurf)-1)
                    {
                        if j-deltay == clamp(j-deltay,0,surface_get_height(bfsurf)-1)
                        {
                            draw_set_color(c_black);
                            draw_set_color(surface_getpixel(bfsurf,i-deltax,j-deltay));
                            var col = surface_getpixel(tsurf,i+1,j+1);
                            if col != c_black draw_point(i,j);
                            draw_set_color(c_black);
                        }
                    }
                }
            }
            surface_free(bfsurf);
            bfsurf = undefined;
        }
EDIT:
I just got so frustrated that I deleted everything regarding buffers and just switched to a grid that copies surface data every frame. So much easier.
 
Last edited:
Top