GM:S 1.4 Level / Map Editor - Saving and Loading

Discussion in 'Programming' started by Gamerev147, Aug 8, 2017.

  1. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    Hello!

    I have built a simple level editor as its own separate executable.

    How can I save what I have made in this level editor and load in into a different game maker game, and also have it be playable?

    Sorry if that was a bit confusing, but any help is appreciated. I would prefer code rather than a YouTube tutorial.
    Thanks! :)
     
  2. Bridget7298

    Bridget7298 Guest

    You would need to use a DLL to use file saving functions. Then after you create the level, save the info to a text file. Then in the other game have it read the text file and load the level accordingly.
     
  3. dannyjenn

    dannyjenn Member

    Joined:
    Jul 29, 2017
    Posts:
    568
    What @Bridget7298 said, except you don't need a DLL. What you need to do is come up with some way of saving it. For example, you could loop through all the tiles and save their coordinates and stuff to a text file or something. Then in your game you would make an empty room, and put in some code to do the reverse (read the coordinates from the text file and place the corresponding tiles in the room at those coordinates).
     
  4. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    What type of DLL?
     
  5. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    Would you happen to have any example code of this?
     
  6. dannyjenn

    dannyjenn Member

    Joined:
    Jul 29, 2017
    Posts:
    568
    It really depends on how you have level editor set up. I've done this before, but when I did it I think I just used a ds_grid or something which made it a lot easier.

    edit - If I recall, what I did was, in my room editor every time I added a tile to the room at (x,y), I also stored a number in a ds_grid at (x div 16,y div 16). (Different tiles had different numbers. This is how I was able to tell the tiles apart.) So I had one of these grids set up for each layer, and when I wanted to save it I just used ds_grid_write() and saved that string to a file.
    Then in my game, I made a script that did the reverse. It read the string from the file, then it used ds_grid_read() to fill the grid, and then it looped through the grid, placing the correct tiles in the room at their correct locations (x*16, y*16).
     
    Last edited: Aug 9, 2017
  7. IndianaBones

    IndianaBones Member

    Joined:
    Jul 5, 2016
    Posts:
    2,203
    You could use a ds_map. The best tutorials I know for this are in videos.

    However, as you asked for code, here is a post with some example code that I used as a starting point for my own save/load system (Thanks @Fel666):

    https://forum.yoyogames.com/index.php?threads/saving-an-entire-room-while-ingame.14708/#post-98157

    You will need to adapt it to your own game of course.

    Basically, as the others have said, you need to save the data to a file that can then be read by your game.

    As GMS games are sandboxed, you will have to use a DLL, or manually move the file to your game folder, or perhaps upload it to a server where you game can download it from (haven't tested this, but it's something I'd like to do for my own level editor)

    Here is a save game system:

    https://marketplace.yoyogames.com/assets/2441/savegame-custom-plus-encrypt

    Here is a extension for saving to non-sandboxed locations:

    https://marketplace.yoyogames.com/assets/5172/non-sandboxed-filesystem
     
    Gamerev147 and dannyjenn like this.
  8. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    Awesome! Thank you guys so much! :)

    Hopefully later tonight I can read about the ds_map and ds_grid as well as ds_list.
    I know ds_list fairly well. So learning the others shouldn't be too bad.

    The way the file file is going to work is that you can put in your own file name and possibly location. Then in the actual game, to read the file, I'll use the file explorer to get the location and read it from there.

    Thank you all so much and I'll be sure to post back on here if I run into any issues. Thanks again! :):)
     
  9. IndianaBones

    IndianaBones Member

    Joined:
    Jul 5, 2016
    Posts:
    2,203
    Sounds good. Just bear in mind that the functions for letting the user select a file from outside the sandbox file areas are only available on Windows.
     
    Gamerev147 likes this.
  10. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    I tried using the maps and lists along with the code to save it, however, I get an error when trying to write the map as a string to the file.
    What's wrong here?
     
  11. IndianaBones

    IndianaBones Member

    Joined:
    Jul 5, 2016
    Posts:
    2,203
    Post the error you are getting and the relevant code.
     
  12. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,441
    I made a tutorial on a pretty neat way to saves in gms:


    It s similar to the post I McAfee but easier to add objects to
     
  13. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    Error Code:
    ___________________________________________
    ############################################################################################
    FATAL ERROR in
    action number 1
    of Step Event0
    for object obj_Controller:

    file_text_write_string argument 2 incorrect type (0) expecting a String (YYGS)
    at gml_Script_scr_SaveMap (line 47) - file_text_write_string(file, map);
    ############################################################################################
    --------------------------------------------------------------------------------------------
    stack frame is
    gml_Script_scr_SaveMap (line 47)
    called from - gml_Object_obj_Controller_StepNormalEvent_1 (line 3) - scr_SaveMap();

    The code for scr_SaveMap:
    Code:
    ///scr_SaveMap()
    
    var map = ds_map_create();
    
    var wall_list_1 = ds_list_create();
    var wall_list_2 = ds_list_create();
    
    //Add the lists to the map
    ds_map_add_list(map, "Wall_1", wall_list_1);
    ds_map_add_list(map, "Wall_2", wall_list_2);
    
    //Go through all Wall_1 objects and add them to list
    with (obj_Wall_1) {
    
        //Create a map to represent this instance
        var instance_map = ds_map_create();
        
        //Store the Positions
        ds_map_add(instance_map, "x", x);
        ds_map_add(instance_map, "y", y);
        
        //Add the map to the Wall_1 list
        var pos = ds_list_size(parent);
        ds_list_add(wall_list_1, instance_map);
        ds_list_mark_as_map(wall_list_1, pos);
    
    }
    
    //Go through all Wall_2 objects and add them to list
    with (obj_Wall_2) {
    
        //Create a map to represent this instance
        var instance_map = ds_map_create();
        ds_map_add(instance_map, "x1", x);
        ds_map_add(instance_map, "y1", y);
        
        //Add the map to the list
        var pos = ds_list_size(parent);
        ds_list_add(wall_list_2, instance_map);
        ds_list_mark_as_map(wall_list_2, pos);
    
    }
    
    //Create a JSON and save it
    var json = json_encode(map);
    var file = file_text_open_write(working_directory + "\mapSave.json");
    file_text_write_string(file, map);
    file_text_close(file);
    
    //Free the map
    ds_map_destroy(map);
    

    Code for scr_LoadMap:
    Code:
    ///scr_LoadMap()
    
    var file = file_text_open_read(working_directory + "\mapSave.json");
    var json = "";
    
    while (!file_text_eof(file)) {
    
        json += file_text_read_string(file);
        file_text_readln(file);
    
    }
    
    file_text_close(file);
    
    //Decode the JSON into a map
    var map = json_decode(json);
    
    //Get the object lists
    var wall_list_1 = ds_map_find_value(map, "Wall_1");
    var wall_list_2 = ds_map_find_value(map, "Wall_2");
    
    //Go through the lists creating the objects
    for (var i = 0; i < ds_list_size(wall_list_1); i++) {
    
        var instance_map = ds_list_find_value(wall_list_1, i);
        var instance = instance_create(0, 0, obj_Wall_1);
        instance.x = ds_map_find_value(instance_map, "x");
        instance.y = ds_map_find_value(instance_map, "y");
    
    }
    
    for (var i = 0; i < ds_list_size(wall_list_2); i++) {
    
        var instance_map = ds_list_find_value(wall_list_2, i);
        var instance = instance_create(0, 0, obj_Wall_2);
        instance.x = ds_map_find_value(instance_map, "x1");
        instance.y = ds_map_find_value(instance_map, "y1");
    
    }
    
    //Free the map
    ds_map_destroy(map);
     
  14. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,441
    In your save map script,
    You try to write the map directly to the file.
    You have to first encode it as a json string.
    You did that, but then you are not using it.

    This is a very simple mistake. Are you sure you understand what is going on? (Or did you just copy paste code?)
     
  15. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    I understand the list part and writing things to the map, but I don't understand the whole json thing...
     
  16. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    Ok I wrote the json to the file and it works now, but in your example code on the other thread, when getting the size of the ds_list, you use "parent". What is the parent ds_list?
     
  17. Gamerev147

    Gamerev147 Member

    Joined:
    Sep 12, 2016
    Posts:
    444
    Sorry for the spam, but I fixed all of the issues and I understand what is going on. I had to read a few things, but I got it now.
    Thank you all for the amazing help! :)
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice