Exporting enum with arbitrary values yields unexpected result

Godot Version

v4.6.2_stable

Question

I have declared an enum stating a rarity rate that I want to use for some spawning logic. The enum is defined as follows:

enum RARITY {
    NONE = 0,
    COMMON = 100,
    RARE = 50,
    VERYRARE = 25
}

I would expect that when exporting the value through a Resource and selecting one of the options (i.e. COMMON) it would then yield the chosen arbitrary result when used - in this case 100. For instance:

@export var rarity: RARITY = RARITY.COOMON

print(rarity) # I would expect this to print 100

What I noticed however is that it prints the int value of the position in the enum list, in this case COMMON prints 1. Which it would be correct if I was not using arbitrary values on the enum, but I would expect my value to override the sequence-based numbering.

Does anybody know if this is intended, if I’m doing something wrong, or if it should be raised to the godot team as a bug?

Oh i prints the index of the value in the array. You need to access normal.value() or somethikng like that. I forgot the exact way to do it

I think you could do it like this:

print(RARITY.keys()[rarity])

I will try, thanks, but that sounds to me like such a weird concept :sweat_smile: they even say it in the documentation that the enum should behave like a const. A const is a const, it does not make much sense that I need to lookup its value

The enum does print the value as assigned not the index. Can you post your actual code sample?

1 Like

I have a class which contains a custom Resource like the following:

class_name CustomResource
extends Resource

@export var rarity: Global.RARITY

Then I also have the following:

class_name Global

enum RARITY {
    NONE = 0,
    COMMON = 100,
    RARE = 50,
    VERY_RARE = 25
}
class_name MyClass
extends Node

@export var resource: CustomResource

at some point in my code I want to retrieve the rarity value, for which I have the following in a utility class:

static func get_rarity(obj: MyClass) -> int:
    return obj.resource.rarity

this last step always returns the index of the RARITY enum chosen in the export, not the actual value of the RARITY choice (i.e. “COMMON” returns 1 but I’m expecting 100)

Try re-assigning and re-saving the resource, there could be old export data if COMMON was without a value before and defaults to it’s index value.

1 Like

Thank you for your input.

I tried force-updating the project, as well as creating a new resource from scratch. Nothing changed. In the resource .tres I can only see

rarity = 1

Changing the choice from the dropdown menu updates this value to the currently selected sequential choice from the dropdown, so based on their position in the list (which makes partial sense).

I still don’t understand what the point of assigning a custom value to an enum is if the value is ignored

I may be wrong here but i believe you either need to assign or print something else. Right now you assign the constant and then print it. If you would assign the constant’s value or print the constant’s value you would get the value.

I remember running into this before and just changing to print the key or value of the state to get the prints i wanted. But even though it printed as e.g 1 or 3 prior to that, the states changed and behaved as intended. So there is probably no real problem here except for the print being a bit harder to interpret.

I would disagree. The print is just an example, but if @exporting a RARITY enum should be treated as a constant then there should be virtually no difference between printing (or consuming) the variable through the export or through the enum iself. What I mean is (taking the example above in mind)

print(Global.RARITY.COMMON) # should print 100

print(get_rarity(my_obj)) # should print 100

Ultimately both should point to Global.RARITY.COMMON, which ultimately should have a 100 value.

This does not happen as you would get the index in the dropdown for the second print call. I believe this to be counter intuitive as it would somewhat lose the concept of it being a constant.

I just tried this and I always get 100 with both approach.

You can check it here and test yourself. Maybe we are doing things slighlty different.

3 Likes

The setup is the same, for some reason in my case it is not working tho. I see that in your resource scene it correctly saves as “100”, in mine it does not. I even tried creating a new resource… I’ll try to go through it again later and perhaps start from a clean plate just in case anything is conflicting.

I’ll mark the post as closed as the issue seems to be a “me” issue at this point :joy: I must have messed too hard with the Godot gods

1 Like

I may know what is wrong..

If you change the enum in globals, and your variable in the custom resource uses it, sometimes your custom resource doesn’t refresh the change of enum.

You need to make a small change and save your main custom resource script (not the resource itself but the resource script). And then check again if it fixes.