How do we deal with nested data ?

One think that feels like a punch in my face is that we simply cant put NativeLists into struct Components and that UnsafeLists cant accept another UnsafeList as a generic parameter.

Thats why i come up with this question… how do we deal with nested data ?

Following example… Recipes. A recipe in any game looks like this.

/// <summary>
    /// Represents an ingredient.
    /// </summary>
    public struct Ingredient {
       
        public FixedString32 type;    // The item type... 3:1 is wood for example
        public byte icon;      // Its icon
        public uint amount;
        public bool consume;

        public Ingredient(FixedString32 type, byte icon, uint amount, bool consume) {
            this.type = type;
            this.icon = icon;
            this.amount = amount;
            this.consume = consume;
        }
    }

    /// <summary>
    /// The craftable result
    /// </summary>
    public struct Craftable {

        public FixedString32 type;   // The item type... 2:1 is gold for example
        public byte icon;
        public uint amount;

        public Craftable(FixedString32 type, byte icon, uint amount) {
            this.type = type;
            this.icon = icon;
            this.amount = amount;
        }
    }

    /// <summary>
    /// The recipe, containing ingredients and a craftable result.
    /// </summary>
    public struct Recipe {

        public UnsafeList<Ingredient> ingredients;
        public UnsafeList<Craftable> craftables;
        public byte describtion;

        public Recipe(UnsafeList<Ingredient> ingredients, UnsafeList<Craftable> craftables, byte describtion) {
            this.ingredients = ingredients;
            this.craftables = craftables;
            this.describtion = describtion;
        }
    }

But once we wanna give the player a list of recipes… for example public struct Recipes{ public UnsafeList<Recipe> recipes... other stuff} it does not work, because UnsafeLists dont accept structs with other unsafelists in it.

We could use a DynamicBuffer, but that sucks with networking and is also very limiting… imagine that the ingredients could also have a list in it… broken. Well we could make each recipe into an entity on their own, eliminating the need of nested data… but even then we have the problem that it may contain another list and we run into the same problem and at some point it doesnt make sense to split everything into entities…

Imagine one entity for recipe, one for each ingredient and so on… that just doesnt make sense anymore and is hard to network.

So how the heck do we implement such nested structures in that ecs environment ? What are common techniques ? And why the heck doesnt UnsafeList accept another UnsafeList ?

tl;dr I don’t. Almost always I just flat out my nested arrays and just like in databases use some sort of key to connect the data.

To give an example:
-an entity with a couple of DynamicBuffers to be used as a RecipeBook: one for every ingredient, result, and recipe there is in the game (this is all read-only so safe for parallel)

  • and a DynamicBuffer on the player itself to keep IDs of known recipes

This way you don’t need to send your recipes over the internet as they are not-mutable data. If you need a short list I would recommend FixedList. And fill it with ID instead of whole structs of recipe/ingredient definition.

As I’m writing this I wonder why you send recipe/ingredient data over the network at all. Is that something the player can change?

1 Like

If your data is read-only, you can use Blob Assets and nest blob arrays.

1 Like

Incorrect. You can nest UnsafeList inside UnsafeList.

1 Like

How ? I tried it multiple times, but it always told me it only allows nested unmanaged structs with primitives in it.

Thanks ! Well i had those dynamic buffers in mind, but those are uncompatible with my network solution atm. However i look into them ^^

Just… use them?

7956693--1019463--upload_2022-3-11_15-14-44.png

7956693--1019475--upload_2022-3-11_15-21-13.png

7956693--1019478--upload_2022-3-11_15-22-2.png

1 Like