Custom Itterated Variables

v4.3.stable.official [77dcf97d8]

Ok, so, the question I have is something I’m having trouble defining because I don’t know enough about it to know what I don’t know, so it’s being a real issue for me.

I’m working on a setup that uses variables for individual objects. example:
A Sides

  1. shiny
  2. transparent
  3. matt
  4. glossy

B Corners

  1. sharp
  2. dull
  3. rounded
  4. square

C color

  1. Red
  2. Blue
  3. Black
  4. Green

Then we put it all together in a variable
ABC to shorten the biz and keep the variables uniform for ease of typing.
111 for example is a shiny, sharp, red shape.
112 for a shiny sharp blue shape
113, etc.

so doing this, I have about a thousand variables.
I also want to designate where they all are LOCATED.

Building which building
Door if it is in the door
Window if it is in the window
Building 1, 2 or 3
and door 1 and window 2, so now we got
11111
for a shiny sharp blue shape within the first building, in the door.

after adding all THIS I expect to have just SO many variables to have, and then I can easily track them because I have a key/code for them all, making it simple to add/remove them as needed, but my save will include like 1000 variables that all equal 0 for the most part.

So far the closest thing to an answer I’ve found is something with a dictonary or array, buuut I want to do more than just randomly pop up the meaning of each string into the game, like most of the examples are, and they don’t really help me get to where I need it to be.

Basically, the game will create an object, and that object will become the var 11111 because it will be created in that spot, of that type, then when I take it from there and put it in another building it’ll change to 11121 or something, and then as it changes it may end up being 31121, etc.
So I need a way to generate the string that adds up to being a meaning with the key, and a way to maintain it in the game, then save it at the end, without typing out every possible combination of the string, then just having “when moving 11111 to place 11111-=1, and 11121 += 1” for every interaction.

Thanks in advance, I hope I’ve made sense of the spaghetti in my mind

If I understand correctly, you want to assign a bunch of different properties to an object, these properties all have discrete values that you know the meaning for (I really hope you are already using enums or at least defined constants and you do not have all the values in your head).

The problem is that you want to have so many of these properties that it would become impossible to manage them manually through variables.

If this is correct a dictionary is really not a bad option. Every time you want to add a property you just need to define a new constant for example:

const PROPERTY_SIDES = "sides"

and then you can create a wrapper class for your dictionary, something along the lines of:

class_name Entity #Name this whatever you want
extends Resource

@export var db = {} #exported just for testing purposes

# Value (and also keys) are not limited to being Strings and ints but
# try to keep it simple
func set_property(property_name: String, property_value: int) -> void:
	db[property_name] = property_value

func get_property(property_name: String) -> int:
	if db.has(property_name):
		return db[property_name]
	return 0 # 0 Is the default value in this case

func reset_property(property_name: String) -> void:
	db.erase(property_name)

I did not test this so it might contain errors but I believe you get the idea.

I extended Resource since you mentioned something about wanting to save and load it. Godot is capable of serializing and saving/loading resources by itself. Look into ResourceSaver and ResourceLoader

Usage of this could look something like this

# These consts need to be defined once somewhere in your project, it is probably
# best to do it in a globally loaded script, you could also use enums but that
# brings other complications with it
const PROPERTY_SIDES = "sides"
const PROPERTY_CORNERS = "corners"

const SIDE_SHINY = 0
const SIDE_TRANSPARENT = 1
const SIDE_MATT = 2

const CORNER_SHARP = 0
const CORNER_DULL = 1

var matt_sharp = Entity.new()
# With the default of 0 being sharp we do not need to set corners only sides
matt_sharp.set_property(PROPERTY_SIDES, SIDE_MATT)

ResourceSaver.save(matt_sharp, "res://test.tres")

I like that you kept the examples the same as mine, makes it easier to grasp, I did forget that enums were a thing, and I’m about to go look into that.

The other factor I had was where the things were located, though since posting I found something that MAYBE will be what I need. I don’t intend to work with a huge number of the actual items, except one or two, and so the important bit is that the individual items with pretty big variety are placed properly and function together correctly.
Seems the easiest way to deal with it is to have nodes for the places/areas
then a node for each type, and nodes for the various factors of the types.
Find a way to build them up into trees then place those trees into the main tree in the locations they need to be in, and then save the whole tree layout somehow, as that’d take care of what’s in the tree, and where in the tree they are.

I also will be having animated, and non animated sprites that tie to all of these objects, one set to be placed in the areas, and the other to be played around the area, to signify visually that they are in the area.
Like if you had a token for a bird, and you place it in a slot of a house, and then the sprite shows an animation of the red bird flying around the roof.
it’s a whole thing, but I was hoping to simplify some part of it with the variable thing, but after finding out how LONG that’d make that script, and the subsiquent saving script, I thought to reach out here.

read about bit flags and
@export_flags("type_name:1", "type_name_different:1024") var flags:int
ChatGPT or DeepSeek are good at describing it.

then check if variable of object has needed flag with
if flags & 1024: print("type_name_different")

its exactly what you need to define flags of objects and check if needed flag is valid.

1 Like

In another programming language, we would call these bitmasks. As @solver10 said, you can use export flags for this:

@export_flags("shiny", "transparent", "matt", "glossy", "sharp", "dull", "rounded", "square", "Red", "Blue", "Black", "Green", "Building1", "Building2", "Building3", "Window", "Door") var object_elements = 0

Godot uses bitmasks in Tilemaps, as well as in collision detection, navigation, and rendering.

Having said all this, I believe you are putting the cart before the horse. You are optimizing before implementation. It’s a very tempting thing to do, but often distracts from getting stuff done. More specifically, from having a playable game.

If you want to store all this information in a bitmask, and space on disk is your worry - do it when you save the game. When you’re writing the game, use dictionaries like @m4tic suggests. The reason I suggest this is Godot is optimized for certain things. Bitmasks are used specifically for things the GPU processes. CPUs process in 64-bit chunks, and processing data smaller than that is counterintuitively slower. So you may impact performance for the sake of disk space.

The game already stores data in a way that is fast and saves space. Try it first, and then optimize if it becomes unbearable. The two reasons I can see for wanting to do this are:

  1. You are making a multiplayer game and sending this information over the internet and want to reduce packet size to reduce lag and latency.
  2. You are making the game for a very old device and want to save storage space.

I don’t know your programming experience, and perhaps you know enough to know you need this. In which case, I would recommend writing a plugin in C++ to handle this and use bitmasks.

A final caution: Using Dictionaries allows you to change your mind about how to organize data. You can add or remove keys and the dictionaries will continue to work. Even if you save the data. If you store information as bits, any changes you make to your data structure (for example inserting a fourth building) will require you to change your code and invalidate all saved data.

I agree with this, especially with the cart before the horse part.

I personally did not suggest bitmasks/flags because they can be a bit finicky to use if you are not familiar with how bitmasking works. Dictionaries are a lot more straightforward and allow for you to change your mind a lot later.

But if you have a very clear specification for what you want and are limited with space (like you mentioned very old devices, network bandwidth, … and if I understand what you are trying to do then it seems to me that you are not limited in this regard) then flags are the way to go. In the end you are the only one that knows exactly what you want/need @sorities.

One thing I would add is that the performance impact of bitmasking in your case is negligible on basically all hardware so do not worry about that.

1 Like