Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export values on instances are lost when there is a parse error on project load. #938

Open
Poikilos opened this issue Jan 20, 2025 · 2 comments

Comments

@Poikilos
Copy link

Poikilos commented Jan 20, 2025

Tested versions

System information

Windows 11 and Ubuntu Studio 24.04, tested with both Redot 4.3 and Godot 4.3 on each OS

Issue description

I get the errors and it seems to erase values of exports that I had set in the GUI, unless that is a separate issue (at some point I did cut and paste exports to the top of a file, not sure if this one, but didn't save until I pasted). For example, load this project in 4.3 (Scroll down and click "Source code" version 0.9): https://poikilos.itch.io/locktopia

  • The entire superclass (Prop in this case) is not even shown in the Inspector when selecting the subclass instance in the Scene, until the syntax error is removed from the code.

Project load errors:

Redot 4.3 on Ubuntu Studio 24.04 Redot Engine v4.3.stable.official (c) 2007-present Juan Linietsky, Ariel Manzur & Godot Contributors & Redot Contributors. --- Debug adapter server started on port 6006 --- --- GDScript language server started on port 6005 --- res://models/characters/player.gd:2 - Parse Error: Could not resolve class "Humanoid". res://craft_item.gd:-1 - Compile Error: modules/gdscript/gdscript.cpp:2938 - Failed to load script "res://craft_item.gd" with error "Parse error". (User) res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type "null" as "Vector3". res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type null to variable "move_to_vec3" with specified type Vector3. modules/gdscript/gdscript.cpp:2938 - Failed to load script "res://models/characters/prop.gd" with error "Parse error". (User) res://models/characters/destructible_prop.gd:2 - Parse Error: Could not resolve class "Prop". modules/gdscript/gdscript.cpp:2938 - Failed to load script "res://models/characters/destructible_prop.gd" with error "Parse error". (User) res://models/characters/creature.gd:2 - Parse Error: Could not resolve class "DestructibleProp". modules/gdscript/gdscript.cpp:2938 - Failed to load script "res://models/characters/creature.gd" with error "Parse error". (User) res://models/characters/humanoid.gd:2 - Parse Error: Could not resolve class "Creature". modules/gdscript/gdscript.cpp:2938 - Failed to load script "res://models/characters/humanoid.gd" with error "Parse error". (User) res://models/characters/player.gd:2 - Parse Error: Could not resolve class "Humanoid". res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type "null" as "Vector3". res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type null to variable "move_to_vec3" with specified type Vector3. res://models/characters/destructible_prop.gd:-1 - Compile Error: res://models/characters/creature.gd:-1 - Compile Error: res://models/characters/humanoid.gd:-1 - Compile Error: res://models/characters/player.gd:-1 - Compile Error: res://inventory_slot.gd:-1 - Compile Error: modules/gdscript/gdscript.cpp:2938 - Failed to load script "res://inventory_slot.gd" with error "Parse error". (User) res://narrator.gd:-1 - Compile Error: modules/gdscript/gdscript.cpp:2938 - Failed to load script "res://narrator.gd" with error "Parse error". (User) res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type "null" as "Vector3". res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type null to variable "move_to_vec3" with specified type Vector3. res://world.gd:-1 - Compile Error: modules/gdscript/gdscript.cpp:2938 - Failed to load script "res://world.gd" with error "Parse error". (User)
Godot 4.3 on Ubuntu Studio 24.04 Godot Engine v4.3.stable.official (c) 2007-present Juan Linietsky, Ariel Manzur & Godot Contributors. --- Debug adapter server started on port 6006 --- --- GDScript language server started on port 6005 --- res://models/characters/player.gd:2 - Parse Error: Could not resolve class "Humanoid". res://craft_item.gd:-1 - Compile Error: modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://craft_item.gd" with error "Parse error". (User) res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type "null" as "Vector3". res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type null to variable "move_to_vec3" with specified type Vector3. modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://models/characters/prop.gd" with error "Parse error". (User) res://models/characters/destructible_prop.gd:2 - Parse Error: Could not resolve class "Prop". modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://models/characters/destructible_prop.gd" with error "Parse error". (User) res://models/characters/creature.gd:2 - Parse Error: Could not resolve class "DestructibleProp". modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://models/characters/creature.gd" with error "Parse error". (User) res://models/characters/humanoid.gd:2 - Parse Error: Could not resolve class "Creature". modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://models/characters/humanoid.gd" with error "Parse error". (User) res://models/characters/player.gd:2 - Parse Error: Could not resolve class "Humanoid". res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type "null" as "Vector3". res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type null to variable "move_to_vec3" with specified type Vector3. res://models/characters/destructible_prop.gd:-1 - Compile Error: res://models/characters/creature.gd:-1 - Compile Error: res://models/characters/humanoid.gd:-1 - Compile Error: res://models/characters/player.gd:-1 - Compile Error: res://inventory_slot.gd:-1 - Compile Error: modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://inventory_slot.gd" with error "Parse error". (User) res://narrator.gd:-1 - Compile Error: modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://narrator.gd" with error "Parse error". (User) res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type "null" as "Vector3". res://models/characters/prop.gd:7 - Parse Error: Cannot assign a value of type null to variable "move_to_vec3" with specified type Vector3. res://world.gd:-1 - Compile Error: modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://world.gd" with error "Parse error". (User)

Even though the project works fine if you delete the bugged part: = null in prop.gd.

  • Yea, I know I really overused inheritance here. Maybe that contributes to the problem? Inheritance is Prop -> DestructibleProp -> Creature -> Humanoid -> Player
  • Many player instances are in the "Main" scene (which has world.gd attached) under the Characters node in the GUI.
  • The lost attributes are in prop.gd which is the file with the = null bug (Vector3 cannot be set to null, but my code has that, my mistake).
    • Every Player instance on the scene had every value filled in for the following exports defined in prop.gd, and every instance's values were all lost:
      • caption
      • affinity
      • motive
      • a few police officers had "move_to_vec3" set, which is actually a bugged line as I mentioned
    • Yeah, I should mention in my case the project was made in Redot 4.3, and it happened once before when loading a project in Redot 4.3, not just the (one) time I loaded it on Godot 4.3 for making a Windows build. I really don't want to boot Windows right now but I can try to open it in that for now. The log above is from Godot 4.3 on Ubuntu Studio 24.04.

Happened twice during the 2-week game jam It's Based Jam - Winter 2021. Final version had no NPC names 😢 so I started using node names for character names and parent nodes to calculate affinity and motive after that, probably from now on because I really don't want to lose that work.

Steps to reproduce

  • Make a new scene that inherits from CharacterBody3D, such as "Prop". Attach a script and add class_name Prop
    • (more levels of inheritance may be required--see issue description)
      • Make an inherited scene called "Player" using a gd script.
        • Add at least one statically typed export such as "@export var caption: String"
  • Make a 3D scene which will be the main scene called "World". Attach a script and save it as "world.tscn"
    • (This step is probably not required) Add at a Node3D such named "Characters". Add another under it called "npcs". Add another under that called "momandpopshop", and add instances below under that one.
    • Add at least one instance of the new Player scene described above to the scene.
    • Set "caption" on the instance.
  • Save. At this point, the main tscn will contain the values. Continue below to reproduce the issue.
  • Add the following additional export to the prop.gd which has a clear bug (= null not allowed on Vector3): @export var move_to_vec3: Vector3 = null
  • Save & Close Redot
  • As soon as you save, the export values are lost, as in not in the main tscn file anymore.
  • Open the project, and the errors messages appear immediately, and you'll notice the export values are no longer in the Scene tree for the world scene.

Minimal reproduction project (MRP)

Yeah sorry I'm really burned out from the game jam but will try to get around to it. Other than the large tar.gz above, the MRP is probably created using the rather quick steps to reproduce above.

If anyone can post that as an MRP I can try to help with it but just not right away. I just figured this is pretty important to get the issue started without it for now, to prevent data loss in projects, especially since the cause and solution are pretty clear.

I can't really get the issue to happen in a smaller example: issue-938-MRP-WIP.zip, only in the big one above. I can't tell what would exactly be the difference that causes the behavior.

Workaround: I mentioned, use nodes as categories and other important attributes. Parent nodes are not really a full solution as it is limited--if you need more attributes you could add child nodes (the actual node name or constants in the child would contain the value) would be the only stable way I can see to fully avoid using @export, and is unwieldy.

  • or don't leave syntax errors before closing Redot--that may avoid it as well...
  • See also the issue link on Godot 4.4 dev3 above

A quick solution would seem to be to have some sort of error message that would prevent Redot from closing in this case, such as:

"An error in %s prevents ALL exports defined there and set in the Scene tree from being saved if you close the program now." where %s is the gd filename. It seems like the best buttons for this dialog would be "Go to error", "Discard Data" and maybe the QUIT signal in linux would trigger this and only SIG_KILL (kill -9 $PID) should actually close the program without this dialog stopping the close, or maybe have a countdown in one and/or the other case.

A better solution seems to be to save the data in the editor regardless of whether it is defined anymore, since if the Inspector has a widget for it and there is data present, clearly the user wants to save the data (We can say with certainty this is the user's intention at least in the case the file merely has a bug--even if export is deleted or renamed, they may want the data back in the short or long term, not realizing it was lost). If this code is deeply intertwined with the way the engine works (such as, only properties defined are saved), maybe have a file called %s.lost+found.tscn (where %s is filename that defines the values but has a parsing error) that would contain values that were in the old file and not the new file (If writing the file, make sure to read it if it already exists so a merge can be performed before overwriting).

@Poikilos Poikilos changed the title Losing export values occasionally during project load, maybe related to when syntax error is elsewhere in file exporting it Losing export values during project load (may be caused by gd syntax error): modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://world.gd" with error "Parse error". (User) Jan 20, 2025
@Poikilos Poikilos changed the title Losing export values during project load (may be caused by gd syntax error): modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://world.gd" with error "Parse error". (User) Losing export values during project load (may be caused by gd file syntax error): modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://world.gd" with error "Parse error". (User) Jan 20, 2025
@Poikilos Poikilos changed the title Losing export values during project load (may be caused by gd file syntax error): modules/gdscript/gdscript.cpp:2936 - Failed to load script "res://world.gd" with error "Parse error". (User) Export values on instances are lost when there is a parse error on project load. Jan 20, 2025
@Trinity1967
Copy link

Update for issue 101669 ... maybe similar problem:

I have also seen a strange behavior in demo programs from the Asset Library. For example, "Meta Scene XR Sample".
The behavior is sporadic. Sometimes the programs work!

I have the impression that a library may not be loaded quickly enough and Godot is accessing classes that simply do not exist at runtime. However, they do exist at design time. Is something like that conceivable?

PS: I hope my English is somewhat understandable :)

@Poikilos
Copy link
Author

Poikilos commented Jan 21, 2025

I'm not sure either. If that is the case, maybe _ready or even some load/save process in the editor is running before certain @export values are loaded from on big scenes? I realize a tcsn is a simple text format but it still takes a while to fully load a scene that has many instances that place many meshes in the 3D view.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Open
Development

No branches or pull requests

3 participants