Loading scripts in a loop

Godot Version

3.6

Question

I have a game with dozens of maps and I’d like to make more.
Each map is stored in a large gd file with information about what is on each grid, and settings.

For example in the directory “Maps/Map1/data.gd” I have:

var settings = {
“map_name”:“Map1”
“difficulty”:“easy”,
“player”:{
“name”:“player1”,
“color”:“red”
},

“map_type”: 1
}
var matrix = {
“0,0”: “empty”,
“0,1”: “enemy base”,

“999,999”:“empty”
}

I am trying to loop through these files and create a menu where you can select which map you want to play.

The problem is that godot doesn’t let you have static variables. It doesn’t let you preload scripts dynamically. So it seems I can’t simply make a loop like:

for folder in directory:
    script = load("res://Maps/"+folder+"/settings.gd")
    var data = script.get_settings()
    show_map_button(data)

How should I go about doing this without making a singleton for every map?
I could load json files from “user://”, but as this is an online game, that would require the user to enable third party cookies… and they would be some big cookies at that.

What’s the proper “godot way” of doing this?

Use custom resources for data containers.

1 Like

It does actually. Using a custom resource is still the best option but for static variable you can just use (example):

class_name MyClass extends Node3d

static var my_variable

Then you can easily reference it in another script by using MyClass.my_variable.

Or just make it easy on yourself and use a custom resource. Make a script and add:

extends Resource

class_name MyResourceClass

@export var map_name : String
@export var difficulty : String
@export var player_name : String
@export color : String

Now you can right click in the file system and select “Create New/Resource” and then select “MyResourceClass” as the type. Then you can double click on the newly created resource file and in the Inspector you can fill out the information.

And that’s it. Now you can reference MyResourceClass by simply adding:

@export var my_resource_class : MyResourceClass

In the inspector drag the applicable resource file into the field just created and you’re all set. In your map script you can now simply use my_resource_class.map_name or whatever field’s information you need.

Maybe I’m missing something.

I have dictionaries that are many thousands of keys.

Entering each value manually into a resource’s export fields would take longer than the age of the universe.

Edit: Okay so I made a python script that writes tres files. I feel like there should be a better way, but that’s where I’m at.

You don’t need to store “dictionaries with thousands of keys”. This is for map generation correct? So you only store the input information like map type (jungle, desert, etc.) , height map seed (or image), river map seed (or image) and so on in your resource file. You then feed these values to your map generator to get the map your specified, be that a saved or new map. Not sure where the dictionaries with thousands of keys come from. Objects on the map? You don’t need to store that either. Just the input values for which items, how many and where (seed or map). Or you can just store an index or name for the dictionary that needs to be used in the map if this is something you use in generating the maps.

In other words, you use generation algorithms that take a few input values and produce a map based on those input values and those input values are what you store in a resource file for each map, not the dictionaries and other stuff that runs behind the scenes. Map generation can be based on Perlin noise, height maps or even hand drawn pixel maps if you prefer. Think about how Minecraft generates worlds. Do you think it stores every block or array in a file or in memory? Nope. It simply stores a seed for each world and then it generates the world based on that seed. Well, that and some added information like what biome it should be, how high the water level is, max mountain height and min ground height and all sorts of things that is used to make a specific kind of map. And you need to do the same for a 2D map.

I see what you’re saying. My game is a puzzle game. Each map is a grid, and each grid coordinate has properties. There can easily be hundreds of squares or more on one map. (It’s nothing compared to minecraft’s size but still a lot of data.) I think it would be challenging to generate an exact puzzle from a seed.

So, how do you create a map for your puzzle game normally? Do you start from scratch, create new dictionaries and arrays and all that? Or do you simply say, put his item from that dictionary in this position on the grid? If it’s the former then you need to rethink the process. If it’s the latter you cqn write a script that reads a pixel image that has all this information stored for example. The image would be the size of your grid and each pixel would represent a tile. So if it’s a yellow pixel at postion 10,5 on the pixel that means the script should place whatever you decide a yellow pixel means on the map at x10, y5.

In other words, unless you want to create every map by hand you need some kind of map editor system. Pixel images is just one way to do this but seems ideal as you can save or load files from a simple 2D pixel grid.

Cool. That’s probably a better way to do it. I have a custom resource and a python script that converts json to tres. The json files are made by a map editor that exists in-game.

Well, then you simply put the path to the json file in a resource file and load you map from there. No need to make it complicated. I assume you simply want some way to load a specific map yes? I’m not 100% sure you even need to use a resource file for the maps themselves as you can just load straight from the json files.

Where resource files come in more handy is for the units and objects on your map, if needed. Say you use collision detection and it tells you that you collided with an object on the map. This is where having a resource file attached to the object makes it easy to query what the object is and what its properties is.

Don’t let the name fool you. A resource file does not hold any resources. Think of it more like a json file that stores information about a game object. This information can range from simple variables to icon images for example. If you’re familiar with Unity at all, rources in Godot are the same as Scriptable Objects in Unity.