Search Unity

Question Resize an 2D array?

Discussion in 'Scripting' started by TheKrazyDev, May 20, 2023.

  1. TheKrazyDev

    TheKrazyDev

    Joined:
    Sep 8, 2021
    Posts:
    107
    I'm using a 2d array to store my block class's position in the world. Only problem is the array needs to have an infinite size, being the player will being placing blocks constantly, thus the array needs to expand.

    Ive seen people talk about Array.Resize but doesnt seem array appears. I dont know if I need to reference something at the top of my script or do I have to use something else?
     
  2. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    orionsyndrome likes this.
  3. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,113
    You're doing it wrong if you're resizing your map array every time something new is discovered.

    That doesn't scale well. To cope with infinite worlds, we tend to construct them out of chunks. You produce a new chunk, keep it separate in memory, but stitch the visuals together (also you can stitch them internally for the purpose of running continuous game logic, but that's another topic).

    Chunks solve the issue of having anything "infinite" because they are themselves of finite and predictable size, and besides the game world will never get infinitely explored anyway.

    Plus you get a tech for occlusion culling for free, because you can now toggle your chunks in render and relieve the system of excess geometry. That's how literally 90% of all 'open world' or strategy maps work.

    You can think of chunks like they're individual tiles, but more beefy than that. Because this is a trade off solution, there is a sweet spot in their size so make sure you make a system where you can experiment with such parameters.

    If you don't need chunks, that means you wouldn't have to resize arrays either, so what you're doing is making a system (thus something that ought to be comprised of multiple interconnected parts) that pretends to not be a system. This will come back to haunt you.
     
    Last edited: May 20, 2023
    Yoreki and Bunny83 like this.
  4. TheKrazyDev

    TheKrazyDev

    Joined:
    Sep 8, 2021
    Posts:
    107
    Yea but the problem with a list is i need the name to store the position, so i could easily grab a block without for looping thus i used a 2d array.
     
  5. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    So use a Dictionnary<Vector3, Tile>() instead of an array ? :p
     
    Kurt-Dekker likes this.
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,004
    The go-to example when it comes to chunks is usually minecraft. It's organised in dimensions. Each dimension is a pseudo infinite world which consists of "regions". Each region is actually stored as a separate file on disk. A region consists of 32x32 chunks (1024 in total). A chunk is a 16x16 block area that goes from the bottom to the top (used to be 0 to 127, later 0 to 255, currently -64 to 319). Each chunk is further split into chunk sections of 16x16x16 blocks (so a chunk is a single column of sections)

    Most of those things can be arranged in fixed sized single dimensional arrays which are faster than multi-dimensional arrays. The only "variable" thing here would be regions which can be organised in a dictionary. Since you barely need to deal with more than one region at a time (max 4 at a corner) that usually isn't that much of an issue.

    The advantage of using power-of-two sizes is that you can easily convert an absolute block coordinate into a region / chunk or local block coordinate by bitshifting. In minecraft you would simply divide a world coordinate by 512 (32*16) or shift to the right by 9 bits and you get the region. Taking the modulo 512 of a block coordinate gives the relative coordinate within the region. Again dividing by 32 (right shift by 5) gives us the relative chunk coordinate. Modulo 16 gives us the block coordinate inside a chunk.

    2d games are a bit simpler and may work with slightly larger chunk sizes. Though it usually makes sense to not create too large chunks. Minecraft of course has tied other game features to the concept of chunks. Like random block ticks. Each game tick (20 ticks/s) every loaded chunk receives 5 random block ticks. So it literally picks 5 random blocks in that chunk and tries to "tick them". Most blocks don't do anything but gras, planted seeds,saplings or leaves use that tick to grow.

    Note that in MC since the chunks contain a lot of information, in the past it used just a single byte per block in a chunk / section (4096 blocks / bytes == 16x16x16). Completely empty sections were not stored at all. Each block had an additional metadata byte which was used for lighting and other block features which were block type dependent ( block orientation, activation state, growth state, ....). So that may be also something to consider.
     
    orionsyndrome and Yoreki like this.
  7. TheKrazyDev

    TheKrazyDev

    Joined:
    Sep 8, 2021
    Posts:
    107
    Ooooooh ok.I've wondered if thats how dictionary's worked. Thanks alot :D
     
  8. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,113
    Can you at least use Dictionary<Vector3Int, Tile> before you hurt yourself?
     
    Bunny83 and Yoreki like this.