Search Unity

Representing nested grids in data without recursion

Discussion in 'Scripting' started by Sendatsu_Yoshimitsu, Feb 17, 2019.

  1. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    I'm working on a silly roguelike thingie in which the overworld is abstracted as an n by n grid of squares, each square contains a similiar, larger grid of squares to represent more granular terrain, and so forth. Ideally I'd like to build a reusable pattern that lets me nest as many grids inside of each other as I'd like, since that affords a lot of flexibility.

    However, I also need the grid to be easily serializable, so I can't do something like this without jumping straight into recursion territory:

    Code (csharp):
    1.  
    2. [System.Serializable]
    3. public class GridSquare
    4. {
    5.     Grid grid;
    6. }
    7.  
    8. [System.Serializable]
    9. public class Grid
    10. {
    11.     GridSquare[,] grid;
    12. }
    13.  
    My solution at present is to simply make a few similiar but unrelated classes with identical functionality, so MacroGrid has a 2d array of MediumGridSquares, each of which have a grid of MicroGridSquares. This works, but it's really clunky- are there any specific design patterns I should be looking up which accomplish this sort of nested data in a more nuanced and extensible fashion?
     
  2. mbaske

    mbaske

    Joined:
    Dec 31, 2017
    Posts:
    473
    How about sticking with a recursive setup, but add Serialize/Deserialize methods that parse the grid shape to/from a flat data structure, perhaps a JSON string.
     
  3. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    There's the Compound Design Pattern. All it says is to use a recursive data structure, but it's in a round-about way and never uses the word recursion, so it satisfies people who think recursion isn't really object oriented.

    In general, won't C# serialize recursive data? I thought the rule was it assumes all pointer/references are to "owned" data, and it always follows and writes everything. The problem, I thought, is when your class references data serialized elsewhere, often in a cycle of them referencing parts of you.
     
  4. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    Well it's a small thing to get scared off by, but Unity freaks out and starts throwing errors once you hand it something with a serialization depth greater than seven.

    I suppose it's not the cleanest approach in the world, but I suppose I could always handle this by storing the grid in a flat array, and making each square contain a list of integer array indices instead of a pointer to the grid square itself. It would require more lookups and be slightly more cumbersome to work with, but it bypasses the problem entirely.
     
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    Ah, right. I think that's a safety measure, in case you accidentally try to serialize something using pointers. I've actually done that once and gotten saved by the error (otherwise it would have run in a circle, forever).

    I suppose you could have each object hold 2+ levels. Or the giant array idea I suppose would work. I think those usually have an extra index array, letting you know what starts where.
     
  6. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    I appreciate the ideas- I have a much better place to start poking around than I did the other day. Thanks! :)
     
  7. mbaske

    mbaske

    Joined:
    Dec 31, 2017
    Posts:
    473
  8. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691