Metadata in a block game using ds_grids

Discussion in 'Programming' started by Niften, Nov 12, 2017.

  1. Niften

    Niften Member

    Joined:
    Aug 14, 2016
    Posts:
    231
    Hello everybody,

    I'm incorporating metadata for blocks in my game and I'm not sure what the most efficient method is. Right now I have 3 grids of data for one chunk - foreground, background, and metadata for the foreground layer. I was thinking of nesting ds_maps inside of each grid cell and this would come with a huge number of benefits, but wouldn't this take up a lot of memory and cause lag every time I have to refer to it?

    Just need a nudge in the right direction here. Anyone?

    (PS: I'm using buffers to save)
     
  2. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,244
  3. kburkhart84

    kburkhart84 Firehammer Games

    Joined:
    Jun 26, 2016
    Posts:
    470
    Actually, bit-masking into a raw array would be even more memory friendly...but sometimes the most efficient way isn't the best if it makes it harder to work with. This is part of the reason why we wish we had more data types in GM, letting us have a Vector3 type or similar would let us put 3 values into a single gridspace.

    I don't think accessing a data structure within a data structure is going to be lagging much more than accessing it singly. You are technically storing the data regardless, and you are only doing an access 4 times instead of 3 times(4 times being 1 to access the grid, and 3 more to access each section, and 3 times being 1 access per separate data structure). The real decision here will depend on what is easier for you to do, as in is one easier than the other for organization, level design, etc... If this bit of code is something that such a small difference is make/break for your performance, then I think you have much bigger issues(don't think that is the case though).
     
  4. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,244
    Technically we have a data type like that, it's called color. The function make_color_rgb takes three 8bit arguments and fuses them into a 24bit value. This can be read by other built-in functions as well (color_get_). It is just limited to 8 bit per value (0-255).
     
  5. kburkhart84

    kburkhart84 Firehammer Games

    Joined:
    Jun 26, 2016
    Posts:
    470
    LOL, Technically...I think you are right! I forgot about that(never use it). I bet it's just doing some bit-masking under the hood.
     
  6. Niften

    Niften Member

    Joined:
    Aug 14, 2016
    Posts:
    231
    That's so interesting! Thank you all for your replies. Using bitmasking is genius, and I could store up to three values with make_color_rgb. Thanks so much guys!
     
  7. Niften

    Niften Member

    Joined:
    Aug 14, 2016
    Posts:
    231
    Could you even nest them? I.E. make_color_rgb(make_color_rgb(...),make_color_rgb(...),make_color_rgb(...))
    EDIT: Nevermind, I just remembered they have to be 0-255
    EDIT2: You can! I just ran a test and it was able to read the first value.
    Code:
    var v1,v2,v3,v4,v5,v6,v7,v8,v9
    
    v1 = 1;
    v2 = 2;
    v3 = 3;
    v4 = 4;
    v5 = 5;
    v6 = 6;
    v7 = 7;
    v8 = 8;
    v9 = 9;
    
    var nested1 = make_color_rgb(v1,v2,v3);
    var nested2 = make_color_rgb(v4,v5,v6);
    var nested3 = make_color_rgb(v7,v8,v9);
    
    var final = make_color_rgb(nested1,nested2,nested3);
    
    var test = color_get_red(color_get_red(final));
    
    show_debug_message(string(test));
    
    EDIT3: I tried reading back the other values and it didn't work. RIP Still, being able to store three values in one is a gamechanger and I'll probably be able to do more by following the bitmasking post
     
    Last edited: Dec 3, 2017
  8. PNelly

    PNelly Member

    Joined:
    Jun 20, 2016
    Posts:
    256
    I would encourage you to use the ds_map solution. All solutions consume memory, and all solutions consume access time. Bit masking against an integer (the color solution) is going to be a little faster and use a little less memory, but you'll be limited to 3 bytes of data per cell and your code will be more difficult to understand. Good practice is to get your performance in the right ball park and then optimize later if it's really necessary, since it usually introduces code complexity, bugs, and less readability. Bit masking and using a map are both going to be ϴ(1) so it's really a wash unless your back is against the wall on grid performance.

    If you do want to go with bit masking tho, since it's fun (and important) to experiment and learn new stuff, you ought to drop the colors and do it either with int64's (8 bytes of data per cell) or use buffers which will give you a lot more flexibility in size. You'll learn a lot about bitwise operations which are super handy now and then in a pinch.
     
  9. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,244
    I guess
    To be fair, no one has to use the colours. Bitmasking is just a general mechanic. You can easily bitmask three 16-bit numbers, but you have to remember how to shift each time. The performance on bitmasking is almost the same as just using arrays normally if you are using the yyc. maps will do the trick too, they are slower but it isn't a lookup you do a 100 times at once, so it's fine either way, unless in generation process, that is something to consider.

    The real deal is the memory you have available, there is a limit and this limit can be reached fast if your game is complex and extensive.
     
  10. PNelly

    PNelly Member

    Joined:
    Jun 20, 2016
    Posts:
    256
    It would appear we are in agreement?
     
  11. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,244
    I think so.
     

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