Quick answer: Enums defined in different scripts are treated as separate types. Even if two enums share the same name and values, comparing them across scripts compares unrelated integers. Always reference the enum through its defining script or use a shared autoload.
Here is how to fix Godot enum comparison not working. You define an enum in one script, compare it in another, and the comparison silently returns false even though both values look identical. Enum comparisons in GDScript can fail in subtle ways — wrong scoping, duplicate definitions, or unexpected integer casting. Here is how to make them work reliably.
The Symptom
You have an enum like State.IDLE and you compare it with ==, but the condition never matches. Your match statement falls through to the default case. Or you store an enum value in a dictionary and cannot retrieve it later. The values print as the same integer, yet the comparison fails or behaves inconsistently across scripts.
What Causes This
GDScript enums are syntactic sugar over integers, but their scoping rules create pitfalls that trip up nearly every developer at some point. The most common causes:
- Duplicate enum definitions across scripts — If you define
enum State { IDLE, RUN }in bothplayer.gdandenemy.gd, they are two completely separate enums. ComparingPlayer.State.IDLEwithEnemy.State.IDLEcompares unrelated types. - Unscoped enum access — Referencing
IDLEwithout the enum name works inside the same script, but becomes ambiguous when multiple enums exist or when accessed from another script. - Integer casting confusion — Since enums are integers, assigning an arbitrary int to an enum-typed variable compiles without error, but may not correspond to any valid member.
- Dictionary key mismatch — Storing a value with
State.IDLEas the key and retrieving it with the raw integer0works, but mixing styles leads to hard-to-trace bugs.
Fix 1: Define Shared Enums in One Place
The cleanest solution is to define enums that multiple scripts need in a single autoload or a script with class_name. This guarantees every script references the exact same enum type.
# enums.gd — attach to an autoload named "Enums" or give it a class_name
class_name Enums
enum State {
IDLE,
RUN,
JUMP,
ATTACK
}
enum Element {
FIRE,
WATER,
EARTH,
AIR
}
Now every script references Enums.State.IDLE and comparisons always work because there is only one definition.
# player.gd
var current_state: Enums.State = Enums.State.IDLE
func _physics_process(delta):
if current_state == Enums.State.RUN:
move_and_slide()
Fix 2: Use Fully Qualified Names Across Scripts
If you define an enum inside a script that has a class_name, other scripts can reference it through that class name. Do not redefine the enum locally.
# enemy.gd
class_name Enemy
extends CharacterBody2D
enum State { IDLE, CHASE, ATTACK, DEAD }
var state: State = State.IDLE
# In another script, reference Enemy's enum directly:
func check_enemy(enemy: Enemy):
if enemy.state == Enemy.State.CHASE:
print("Enemy is chasing!")
Fix 3: Be Careful with Enum Dictionary Keys
When using enums as dictionary keys, stay consistent. Either always use the enum member name or always use the integer, but do not mix them.
enum Item { SWORD, SHIELD, POTION }
# Good — consistent enum keys
var inventory = {
Item.SWORD: 1,
Item.SHIELD: 2,
Item.POTION: 5
}
func get_count(item: Item) -> int:
return inventory.get(item, 0)
# Bad — mixing enum name and raw int
# inventory[0] works but is confusing and error-prone
Fix 4: Validate When Casting Integers to Enums
GDScript will not stop you from assigning any integer to an enum-typed variable. If you receive an int from a network message or save file, validate it before treating it as an enum.
enum Direction { UP, DOWN, LEFT, RIGHT }
func set_direction_from_int(value: int):
if value < 0 or value > Direction.RIGHT:
push_warning("Invalid direction value: " + str(value))
return
var dir: Direction = value as Direction
print("Direction set to: ", dir)
"Enums feel simple until you use them across scripts. The moment you duplicate a definition, you have created two separate types that happen to share a name."
Related Issues
If your dictionary access is returning null for other reasons, see Fix: Godot Dictionary Access Returning Null.
If you are hitting cyclic dependency errors when referencing class names across scripts, check Fix: Godot GDScript Cyclic Dependency Error.
One enum definition, one source of truth. That is the entire fix.