GMS 2.3+ What is the best data_structure to store Tile Info?

Petrik33

Member
Hello everybody, I have previously make a thread asking wheter structures(GMS 2.3) are good for storing info about tiles, and even without receiving a positive answer I decided to use them in the Level Editor to test before implementing in new Games. But now when I am done with Level Editor and the time has come to implement many of the new changes I have to find out the best data structure to hold info about tiels. Currently my structure is like that:
GML:
//Create Event of the Manager Object
map_grid = ds_grid_create(grid_W,grid_H)
global.top_heights_grid = ds_grid_create(grid_W,grid_H);

for(var W = 0;W < grid_W; W++)
{
    for(var H = 0;H < grid_H;H++)
    {
        //Tile = {gridX,gridY,Height,ScreenX,ScreenY,Sprite,SpriteFrame,ON_TILE,Collision,Cursor}
        global.top_heights_grid[# W,H] = 0;
        map_grid[# W,H] = array_create(grid_levels);//Grid levels = 4;
        var _sprite_frame = 0;
        var _sprite = spr_tiles;
        var _tile = new GameTile(W,H,0,_sprite,_sprite_frame);
        map_grid[# W,H][@ 0] = _tile;
    }
}

//Game Tile Constructor
function GameTile(_tileX,_tileY,_height,_sprite,_sprite_frame) constructor
{
    tileX = _tileX;
    tileY = _tileY;
    height = _height;
    x = TileToScreenX(_tileX,_tileY);
    y = TileToScreenY(_tileX,_tileY,_height);
    sprite_index = _sprite;
    image_index = _sprite_frame;
    on_tile = noone;
    collision = false;
    cursor = -1;
    global.top_heights_grid[# _tileX,_tileY] = max(global.top_heights_grid[# _tileX,_tileY],_height);
}
So, the question is what to choose from the options for storing Tile Info:
1. Structures: leave the things as they are. The biggest con of structures is ability to use Sprite Index, Image index and other integrated GML variables and easy readable code for them.
2. Enumerated Arrays. I think the biggest con of this option is that Arrays are probably quicker than structures. But here is the main problem, I just don't know if they are.
3. I also thought about ds_list like in GameMaker Rob's tutorial, because they are easy to save I guess.
And by the way, if you don't mind I have 2 questions actually. Which is the best way to save and load Level Info containing such Tile Info + A few Objects, .ini or .json???
 

Simon Gust

Member
I don't know what's faster, but I'd assume arrays would be the fastest. Allthough not very pretty to work with. Working with structures is pretty and simple and probably similar in memory usage but slower.
If you run out of memory, then you can create bitfields as one of the constructor variables. This works well for flags (true / false variables) that take up the original 8 bytes of data like every other variable.
At least that is how Terraria handles millions of tiles; using constructors and bitfields.

Based on the answers you previously got which said:
- using constructors for blueprints instead of the tiles themselves.
works, but so does it the other way around. You just need to know, what to store in an individual tile and what to store in a blueprint.
Consistent data, for example: hardness, sound emitter, particle emitter should be located in the blueprints.
Individual data, for example: sprite, frame, depth, orientation.

To save a lot of sequenced information on your disk, you can do it the same way it is saved in memory when the game is running.
create a buffer, go through every tile and save it's information in the buffer, then save the buffer.
The other objects should not go into this buffer, as it's no longer tile-data but more like entity-data; you would have to tell your buffer that it is not only loading tiles but something else also and that causes headaches.
 

Petrik33

Member
I don't know what's faster, but I'd assume arrays would be the fastest. Allthough not very pretty to work with. Working with structures is pretty and simple and probably similar in memory usage but slower.
If you run out of memory, then you can create bitfields as one of the constructor variables. This works well for flags (true / false variables) that take up the original 8 bytes of data like every other variable.
At least that is how Terraria handles millions of tiles; using constructors and bitfields.

Based on the answers you previously got which said:
- using constructors for blueprints instead of the tiles themselves.
works, but so does it the other way around. You just need to know, what to store in an individual tile and what to store in a blueprint.
Consistent data, for example: hardness, sound emitter, particle emitter should be located in the blueprints.
Individual data, for example: sprite, frame, depth, orientation.

To save a lot of sequenced information on your disk, you can do it the same way it is saved in memory when the game is running.
create a buffer, go through every tile and save it's information in the buffer, then save the buffer.
The other objects should not go into this buffer, as it's no longer tile-data but more like entity-data; you would have to tell your buffer that it is not only loading tiles but something else also and that causes headaches.
So, Actually I forgot all the priceless knowledge I got from the Game programming Patterns Book, as this thing is exactly the Flyweight pattern from it, I don't know why didn't I got it when someone told me it in the previous thread, but now I understand it is probably the best solution, Thank you!
 
Top