Match statement always returning default value.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By razor7131

When I tried to parse enemy data the one that involves enum, it always gives the default value here the code:

	func parse_enemy_data():
	    var new_enemy
	    print("Enemy class: ", data.enemy_class)  #Return 1
	    match data.enemy_class:
		    0:     # Class normal
			    new_enemy = enemy_normal_resource.instance()
			    new_enemy.enemy_class = 0
		    1:     # Class mid
			    new_enemy = enemy_mid_resource.instance()
			    new_enemy.enemy_class = 1
		    2:     # Class high
		    	new_enemy = enemy_high_resource.instance()
			    new_enemy.enemy_class = 2
		    _:
			    push_error("Invalid enemy class.")
	    enemy_container.add_child(new_enemy)
	    ...

Here’s how the data structure looks like:

{"drop_item":"GOLD","enemy_class":1,"health":100,"name":"Enemy","pos_x":1052.812622,"pos_y":467.378937,"score":3}

Why this is happened? Thanks for your time.

It works however if I use if statement instead. If possible I want to use this statement instead since it was cleaner and easy to read.

razor7131 | 2020-11-04 19:39

:bust_in_silhouette: Reply From: jgodfrey

Your code works exactly as intended when I tested it like this:

func _ready():
	var data = {"drop_item":"GOLD","enemy_class":1,"health":100,"name":"Enemy","pos_x":1052.812622,"pos_y":467.378937,"score":3}
	print("Enemy class: ", data.enemy_class)  #Return 1
	match data.enemy_class:
		0:     # Class normal
			print(0)
		1:     # Class mid
			print(1)
		2:     # Class high
			print(2)
		_:
			print("default)")

I don’t get it, I just ran the test and yes it works as it should be. But my code still gives me the same error, I tried to double-check everything including how the flow works and nothing seems wrong… debugger says it is match 1 but it goes to the default case. Any idea why this is happen?

razor7131 | 2020-11-04 20:24

No, I don’t see any obvious issue. Is the project available somewhere to look at?

jgodfrey | 2020-11-04 20:39

Yes, that’s fine I got the problem already, thanks for your support.

razor7131 | 2020-11-04 20:55

:bust_in_silhouette: Reply From: razor7131

I found that the issue roots in the value type, when I check the type of the data I tried to match it turns out to be.

TYPE_REAL = 3, Variable is of type float (real).

instead of

TYPE_INT = 2, Variable is of type int.

I don’t know that Godot by default store enum value in TYPE_REAL instead of TYPE_INT, here’s how I declare my enum:

enum EnemyClass{
NORMAL,
MID,
HIGH,
}

so knowing that I simply need to explicitly tell Godot to match it in TYPE_INT:

match int(data.enemy_class):

And finally it works perfectly well. I don’t know why in if statement it works anyway without me explicitly transform the value into integer.

Edit

Godot does not treat enum as float, it just that I use built-in parse_json function that parses all numeric values as float. And as @Magso said below The if statement works because it can work with both datatypes. That’s it, becareful with that thing.

This could be a bug, specifying a value without a decimal place should declare as an int.

"enemy_class":1 #should be int
"enemy_class":1.0 #should be float

The if statement works because it can work with both datatypes but a match statement expects an int.

Magso | 2020-11-06 20:17

If it is, the bug probably somewhere between on how they implement to_json
or parse_json. And how it still printed as integer is really confusing.

razor7131 | 2020-11-06 21:51