derkork / godot-statecharts

A state charts extension for Godot 4
MIT License
679 stars 33 forks source link

Binary tokens export in Godot 4.3-dev4 breaks State Charts #90

Closed BattyBovine closed 4 months ago

BattyBovine commented 4 months ago

Godot 4.3 is reintroducing binary export for GDScript as an export option, and it appears it will be enabled by default. When using this export option, State Charts will break. I've created a minimal example project to demonstrate this behaviour. In the Releases for this project there is a set of two builds, one exported with standard text-formatted GDScript, and one with the new binary script export enabled. The text script build lets you walk around with WASD and jump with space bar, and the State Chart debugger shows what state is active. The binary script build will not allow movement or jumping, and the State Chart debugger is blank. Running with console shows the errors caused by these binary exports:

Vulkan 1.3.277 - Forward+ - Using Device #0: AMD - AMD Radeon RX 6600 XT

SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/state_chart.gd:28)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/state_chart.gd:141)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/state_chart.gd:165)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/state_chart.gd:174)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/state_chart.gd:63)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/state_chart.gd:68)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/state_chart.gd:197)
SCRIPT ERROR: Compile Error:
          at: GDScript::reload (res://PlayerCharacter/player_character.gdc:-1)
ERROR: Failed to load script "res://PlayerCharacter/player_character.gdc" with error "Compilation failed".
   at: load (modules/gdscript/gdscript.cpp:2824)
SCRIPT ERROR: Parse Error: Could not resolve super class inheritance from "State".
          at: GDScript::reload (res://addons/godot_state_charts/compound_state.gdc:6)
ERROR: Failed to load script "res://addons/godot_state_charts/compound_state.gdc" with error "Parse error".
   at: load (modules/gdscript/gdscript.cpp:2824)
SCRIPT ERROR: Parse Error: Could not resolve super class inheritance from "State".
          at: GDScript::reload (res://addons/godot_state_charts/atomic_state.gdc:5)
ERROR: Failed to load script "res://addons/godot_state_charts/atomic_state.gdc" with error "Parse error".
   at: load (modules/gdscript/gdscript.cpp:2824)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/transition.gdc:61)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/transition.gdc:53)
SCRIPT ERROR: Parse Error: Could not resolve member "is_satisfied".
          at: GDScript::reload (res://addons/godot_state_charts/transition.gdc:57)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/transition.gdc:66)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/transition.gdc:82)
ERROR: Failed to load script "res://addons/godot_state_charts/transition.gdc" with error "Parse error".
   at: load (modules/gdscript/gdscript.cpp:2824)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:46)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:169)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:234)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:248)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:255)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:165)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:176)
SCRIPT ERROR: Parse Error: Could not parse global class "State" from "res://addons/godot_state_charts/state.gd".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:218)
SCRIPT ERROR: Parse Error: Could not resolve member "resolve_target".
          at: GDScript::reload (res://addons/godot_state_charts/utilities/state_chart_debugger.gdc:238)
ERROR: Failed to load script "res://addons/godot_state_charts/utilities/state_chart_debugger.gdc" with error "Parse error".
   at: load (modules/gdscript/gdscript.cpp:2824)
ERROR: In Object of type 'Node': Attempt to connect nonexistent signal 'event_received' to callable 'CharacterBody3D(player_character.gd)::_on_state_changed'.
   at: (core/object/object.cpp:1353)
ERROR: In Object of type 'Node': Attempt to connect nonexistent signal 'state_physics_processing' to callable 'CharacterBody3D(player_character.gd)::_falling_physics_process'.
   at: (core/object/object.cpp:1353)
ERROR: In Object of type 'Node': Attempt to connect nonexistent signal 'state_physics_processing' to callable 'CharacterBody3D(player_character.gd)::_walking_physics_process'.
   at: (core/object/object.cpp:1353)
ERROR: In Object of type 'Node': Attempt to connect nonexistent signal 'state_entered' to callable 'CharacterBody3D(player_character.gd)::_on_jumping_state_entered'.
   at: (core/object/object.cpp:1353)
SCRIPT ERROR: Trying to assign value of type 'Node' to a variable of type 'state_chart.gd'.
          at: PlayerCharacter._ready (res://PlayerCharacter/player_character.gd:21)

There is an error in this log about being unable to compile "player_character.gdc", but despite this the character does still rotate toward the intended movement direction, and the Escape key exits the program, so that script appears to be running fine.

I'm not entirely sure if this is an issue with this in-development Godot build or with the State Charts addon, but it appears that the binary export makes Godot unable to find the global State class, as well as other related classes and signals. In my much more complex project there appears to be no problems with global classes or signals other than those related to State Charts, leading me to believe the problem is not Godot's implementation of binary token export. There still may be future changes to Godot that fix this, since this is an in-development update, but it seemed like a good idea to report this here now in case this is a problem with State Charts, and it can be fixed before the final release of Godot 4.3.

derkork commented 4 months ago

Thank you very much for reporting this.

I have a feeling this could be related to https://github.com/godotengine/godot/issues/89297 . The state charts addon has some cross referencing between State and StateChart which seems to be what the issue is about. So it would seem that this is something that needs to be fixed in the engine, unless 4.3 introduces some new constraint that classes may no longer cross-reference each other (as it was in 3.x).

BattyBovine commented 4 months ago

I got slightly different errors, but it seems this could very well be related. I would have thought it would be kind of weird that merely changing the text-based tokens to a binary form would cause GDScript to compile differently, but it seems that's what's happening here. I'll have to keep an eye on this issue.

derkork commented 4 months ago

Yes, I'll keep this open for now until the upstream issue is resolved.

BattyBovine commented 4 months ago

I've confirmed that https://github.com/godotengine/godot/pull/89472 fixes this issue. The tokenizer had issues resolving line continuation markers (\) that were followed on the next line by comments. This is the reason State Charts caused this issue, but it's not an issue with any of State Chart's code. I think it's safe to close this issue.

derkork commented 4 months ago

That's great news, thanks a lot for the follow-up!