Search code examples
arraysperformancedictionarygdscriptgodot4

Is It Better To Use Multiple Dictionaries or One Dictionary With Each Key Being Tied to an Array?


In my Godot project, I'm going to have txt files store information the game needs to have access to. Would it be better to inscribe that information into a single dictionary, with every key associated with an array (for example, {"Building 1": [100, 300, false]}) or should I have however many (for this example, 3) different dictionaries with the same sets of keys? I'm wondering which option would allow for the data to be obtained faster. Please note that I will never only need one of those values; when I'm gathering the information for each of the keys I will need all of it. Thank you for your time!


Solution

  • As per your example, I recommend an array of dictionaries. Using keys to label the data is great for readability. Dictionaries and arrays translate well to JSON.

    For example:

    [
        {
            "name": "Building 1",
            "cost": 100,
            "upgrade": 300,
            "has_windows": false,
        },
        {
            "name": "Building 2",
            // ...
        },
        // ...
    ]
    

    Then say you need to instance these buildings:

    for building_data in buildings:
        var building_object = Building.new()
        building_object.name = building_data.name
        building_object.cost = building_data.cost
        # ...
    

    I don't think you should worry about data locality when using GDScript. Make it as easy to read as possible. For loading data from storage memory, you'll have to run benchmarks on a reasonable sample size with different variants of data formats marshalled into some data structure. I don't think you should worry about that either.


    I'm going to have txt files store information the game needs to have access to.

    Instead of plain text files try using custom Resources. They have a lot of quality of life features:

    • Create in editor
    • Export in editor
    • Export options that are enforced in editor. (range, flags, etc)
    • Caching
    • Marshalling
    • Inheritable
    • Implement interface on top of data

    For example:

    class BuildingData extends Resource:
        @export var name: String
        @export var cost: float
        @export var upgrade: float
        @export var has_windows: bool
    
    class BuildingNode extends Node:
        var data: BuildingData:
            set(v):
                data = v
                set_cost_label(v.cost)
                set_upgrade_label(v.upgrade)
    
    @export var building_data: Array[BuildingData]
    
    for data in building_data:
        var building_node = BuildingNode.new()
        building_node.data = data
        add_child(building_node)