Set variable in resource when created

Godot Version

v4.2.1.stable.gentoo [b09f793f5]

Question

I want to set automatically a random int when a resource is created and never change it.
That’s pretty much it… But… How to do it?

I already attempted to create an entire import plugin that was actually just a resource file, but the resource file was read-only in inspector, which is not something I want.

The Resource

@tool
class_name RandomInt extends Resource

@export var value: int = randi()

Note: @tool is required to initialize value with randi() in the editor inspector.

Questions

  • When do you want to create this resource?
  • How long should it persist?
  • How do you want to use the resource? Passing the resource via code, or setting it on an exported property in the editor?

Maybe create an empty global variable?

In the editor.

As long as the file persists in the disk

Trough code

It seems to work, but a question before anything.

That value will never change right, even when I execute the game, right?

Also, would it be possible for the value to be hidden in the inspector?

The value will not change. It can be changed, though.

How are you using the random value?

Maybe a script like this is more appropriate:

class_name RandomInt

# This is globally accessible via RandomInt like:
# var value = RandomInt.get_value()
static func get_value() -> int:
	return 8383838 # <- Your random value here.

This way the value will not change and cannot be changed except when manually entered by you.

Tip: godot’s integer field in the inspector has an expression evaluator. You can write randi() and it will evaluate it.


Note: These values are not “secure”. They can absolutely be modified by a malicious, curious, or bored user/person.

Alternately, you could use the resource’s resource_path and hash it:

extends Resource
var my_random_int:
    get:
         return resource_path.hash()

This is guaranteed to remain the same so long as the resource_path doesn’t change - in other words, so long as the path of the file in which the resource is saved doesn’t change. Also, be aware that that there is no guarantee that different resources won’t share the same random integer. That’s a general problem with 32 bit random integers.

Why my first attempt was to create a custom import plugin, but the entire resource was set as read only in the inspector, so yay.

What I just thought is to make a custom Importer where it holds the read only number. But that sounds such an overkill.

That would be great. Except I already thought about it and then… get_path() in Resource returns a empty string when it is created on disk. · Issue #92139 · godotengine/godot · GitHub

And, sadly, two different strings can have the same hash, which would be a debugging nightmare to figure out and something surely I would forget to check.

Using a property with a getter (as in my example code) instead of an actual variable avoids this particular problem.

This is true regardless of the method you use to choose a random number. Especially when the number itself is only 32 bits.