Better way to save multiple object locations to an ini file?

D

Dave M

Guest
Currently my game saves and loads the player's x and y location and various other items, chest, keys, boss level, health ect to an ini file. These objects however are only added to the room once.

Enemies and level objects are duplicated.
How can i save the location of these duplicated objects?

I don't know where to start, i need a general direction and ill figure it out from there.
I've been messing around with id and for loops, but is there a better way?

Here is my save and load script:

scr_load
Code:
ini_open("savedata.ini");
argument0 =  ini_read_real("Save", "argument0", argument1);
ini_close();
For example: When loading the game:
Code:
scr_load(global.coins)
scr_load(global.playerx,0)
scr_load(global.playery,0)
scr_save
Code:
ini_open("savedata.ini");
ini_write_real("Save", "argument0", argument0);
ini_close();
For example: When saving the game:
Code:
scr_save(global.coins)
scr_save(global.playerx)
scr_save(global.playery)
 
Last edited by a moderator:
ini isn't ideal for saving that kind of information. Have you considered saving to a text or binary file? Binary is easier in my opinion.

It is possible to do this in ini, but I don't really like it just because it adds the extra step of needing to find each enemy using a string. You'd need a variable that tells you how many enemies there are. Then you can load "enemy1", "enemy2", "enemy3", etc, up to the number of enemies.
 
D

Dave M

Guest
ini isn't ideal for saving that kind of information. Have you considered saving to a text or binary file? Binary is easier in my opinion.

It is possible to do this in ini, but I don't really like it just because it adds the extra step of needing to find each enemy using a string. You'd need a variable that tells you how many enemies there are. Then you can load "enemy1", "enemy2", "enemy3", etc, up to the number of enemies.
Yeah was afraid of doing that.
Wouldn't I still need more variables to save the x's and y's?
I would need a variable for how many coins/heart pieces/npcs/and endless other items aswell.
Sounds like a mess.

Ill look into saving to a text or binary file, never tried too before, this is my first attempt/success at a working ini file.
 
If I were you I would do binary. Either that or you could write all your stuff into a data structure, grid or list, or map, and then save that data structure.
 
D

Dave M

Guest
would it be something like this?

create:
Code:
file = file_bin_open('myfile.bin', 2);
xx = file_bin_read_byte(file);
yy = file_bin_read_byte(file);
file_bin_close(file);
x = xx
y = yy
step:
Code:
id.xx = id.x
id.yy = id.y
When saving
Code:
file = file_bin_open('myfile.bin', 2);
file_bin_write_byte(file, xx);
file_bin_write_byte(file, yy);
file_bin_close(file);
When loading
Code:
file = file_bin_open('myfile.bin', 2);
xx = file_bin_read_byte(file);
yy = file_bin_read_byte(file);
file_bin_close(file);
 
Oops, you know what, binary files aren't that easy to work with. What I meant to say was I'd recommend using buffers. They're easier to use since you can use different data types. However, it's nearly as straightforward to write stuff into a list or other data structure, and save that, as it is to use buffers.

Side note: Be aware that if you are saving variables that make reference to dynamically generated resources, such as instances, you can't really save those variables directly, because the indexes to those resources wont necessarily be the same in between game sessions. In that case, it is a good idea to have your own way of id'ing things that will be consistent across sessions.
 
D

Dave M

Guest
"when re-starting a game, remember to delete the buffer first"
Wouldnt that be a problem.

Side note: Be aware that if you are saving variables that make reference to dynamically generated resources, such as instances, you can't really save those variables directly, because the indexes to those resources wont necessarily be the same in between game sessions. In that case, it is a good idea to have your own way of id'ing things that will be consistent across sessions.

Buffer Examples
NOTE: This function is very limited and it is designed for the beginner to get a checkpoint system up and running quickly, but more advanced users may prefer to code their own system using the File functions, due to the fact that the game will not save any of the dynamic resources that you can create at run-time like data structures, surfaces, added backgrounds and sprites etc...

Sounds like a buffer wouldnt work and a ini file would? Confused...


ds list?
Code:
ini_open("savedata.ini");
id.xx =ds_list_write(location);
ini_write_string("Lists", "xx", id.xx);
ds_list_clear(location);
ini_close();
blahhh im so confused, going to quit for a while getting a headache.
 
Last edited by a moderator:
I'll show you an example:

saving:
Code:
    var _buff = buffer_create( 1024, buffer_grow, 1 );
    var _n = instance_number( obj_random );  //write number of instances of obj_random
    buffer_write( _buff, buffer_u32, _n );
    with (obj_random) {  //write data for each instance of obj_random
        buffer_write( _buff, buffer_u32, id );  //write id
        buffer_write( _buff, buffer_s32, target );  //write target id (signed so -4 (noone) can be written)
        //write position and image angle
        buffer_write( _buff, buffer_f32, x );
        buffer_write( _buff, buffer_f32, y );
        buffer_write( _buff, buffer_f32, image_angle );
    }
    buffer_save_ext( _buff, "save1", 0, buffer_tell( _buff ) );  //save buffer
    buffer_delete( _buff );  //buffer no longer needed

loading:
Code:
    //clear old data
    with (obj_random) { instance_destroy(); }
    //load new data
    var _buff = buffer_load( "save1" );
    var _id_map = ds_map_create();
    ds_map_add(_id_map, noone, noone);
    var _n = buffer_read( _buff, buffer_u32 );  //read number of instances of obj_random
    var _old_id;
    repeat (_n) {  //read data for each instance of obj_random
        with (instance_create(0,0,obj_random)) {
            _old_id = buffer_read( _buff, buffer_u32 );  //read old id
            ds_map_add( _id_map, _old_id, id );  //and add it to map
            target = buffer_read( _buff, buffer_s32 );  //read target (old) id
            //read position and image angle
            x = buffer_read( _buff, buffer_f32 );
            y = buffer_read( _buff, buffer_f32 );
            image_angle = buffer_read( _buff, buffer_f32 );
        }
    }
    with (obj_random) { target = _id_map[? target]; }  //repalce old target id's with new id's.
    buffer_delete( _buff );  //buffer no longer needed
    ds_map_destroy( _id_map );  ///map no longer needed

Note that things must be read out of the buffer in exactly the same order in which they were written, and using the exact same data types. If for some reason you find it necessary to skip reading something out of a buffer, you can read without assigning to a variable.

Also note that the buffer file will not be human readable. It will look something like this:
'FêC¸[Þ Cî.dC éØB Áœ ÿCi ÃöB
If you need the file to be human readable then other methods would be superior.
Another downside to using a buffer is that if you change file formats you will have a hard time finding a way to read old file formats without crashing. json or maybe even ini files would end up being better if you are worried about that.

obj_random is just some kind of object whose instances I want to save. And in this example, I want to save a number of properties for each instance. After re-loading all of the instances, instance ids are all going to be different from what they were in the previous game session. Therefore, what I can do is map the new instance ids to the old instance ids, and then for each variable that contains an instance id, look up the new instance id from the map.
 
Last edited:
Top