Is it considered better form to track resources with a dictionary, or a list + switch?

I’m working on a building game that has a number of resources like wood, stone, and metal- I’m not finished iterating on the design, but it looks like I’ll end up with 20-25 unique resource types. Each resource is just represented as an enum, and every category of resource is stored as a custom ResourceStorageSlot struct:

[System.Serializable]
public struct ResourceStorageSlot
{
    public ResourceType resource; //Wood, metal, or something else
    public int amount; //Amount held in whole units
    public int capacity; //Total possible amount that can be held
}

Where I’m finding myself indecisive is how I should actually be storing these; my first thought was to create a dictionary<ResourceType, ResourceStorageSlot>, and just get/set resources via resourceDict[ResourceType.Wood] or what have you. However, once initialized the dict will never change (since every game will let you store the same set of resources), and I don’t like blindly trusting that my desired key will be present, even if I explicitly initialize it every time.

The alternative that seems obvious to me would be using a list manually configuring it in the inspector, and doing something like the following:

List<ResourceStorageSlot> resourceList;
public void AddResource(ResourceType newType, int newAmount){
switch(newType){
case ResourceType.Wood:
resourceList[woodIndex].Amount+= newAmount;
}
}

As far as I can tell the dict is preferable, since my understanding is that dictionaries take longer to add/insert data into than lists, but less time to search and get data out of, but I have no clear, technical criteria to base my decision on. I could moderate some of the list iteration by using a switch to test the incoming ResourceType in advance and target a specific index, but I suspect the switch block would average out to the same number of operations over time as the iteration. Is either of these options (or something I missed entirely) obviously preferable for reasons I’m unaware of?

Since you’re using an Enum, you can just use the enum’s index to look up in the list. Enums are, after all, glorified ints, and unless you specify something else, they have values from 0 and up. You should probably actually use an array:

var numResourceTypes = 
System.Enum.GetValues(typeof(ResourceType)).Length
var resources = new ResourceStorageSlot[numResourceType];

resources[(int) ResourceType.Wood].amount = 50;
resources[(int) ResourceType.Wood].capacity = 150;

Since the number of ResourceTypes is constant (while you’re playing), this makes more sense than a List, as you’re not going to need to add or remove elements ever.

Note that both with a dictionary or a list/array setup, there’s no reason whatsoever that ResourceStorageSlot should have a ResourceType field. The resource type is given by it’s index in the dictionary/array. Unless there’s a use case where you send the slot somewhere else and need to know which resource type it was, which sounds weird?

If you intitialize your dictionary once, and give it all the appropriate values, you can blindly trust that the key will be present. If you end up with a situation where you can’t trust that, use the TryGet method, and handle the case where the key doesn’t exist.

Oh hey, that is a really good idea; I never thought about casting the enum to directly use as the index- thank you for clarifying! :slight_smile: