• Godot Help
  • Works perfectly 0 errors in Editor, but character is null in exported project

Hi 👋

So I made this 2D platform fighter with a wizard character who can clone himself. When he does that, he clones his same scene again, the same character with the same script. In order to avoid infinite self referencing, I hid the load part in an if-statement. As mentioned, this works perfectly in the editor, 0 errors, in the exported project however, the character is null and just not there at all.

Does anyone have an idea why? I can show you some code (I'm a beginner and not experienced in programming, just to apologize for weird coding methods in advance)

First the Match Script, second the character script, third the exported project


This happens only in the exported project, and it's not only the text that is null there, I tested it.

if player1 == null: player2.modulate = Color(1,0,0)

I don't ask quickly and instead always try to solve it myself first, but after many hours of googling, trying and failing I'm just really desperate. Any ideas? (Godot 3.5) (I have 4 characters in the game and this only happens to him, that's why I'm suspecting it has something to do with him referencing his own script, Godot doesn't seem to mind though?)

I may be mistaken here but I think it's possible that all the *.tscn are renamed to *.scn files when they are compiled from text scenes to compressed binary scene files in the export process.

Therefore if you want to use load() you need to check if you are running in the editor and then add a "t" (or ".tscn") to your scene filenames and if you are running in an exported version you need to use ".scn" instead (or not add a "t"). That is one reason why using load() is discouraged and you should use preload() instead.

    Toxe Interesting, thank you for that suggestion! OS.has_feature("editor") gave me True in the Editor and False in the exported game, so I used

    if OS.has_feature("editor"):
    	clone = load("res://Characters/Izado/Izado.tscn")
    else:
    	clone = load("res://Characters/Izado/Izado.scn")

    Unfortunately, that doesn't seem to be the problem. I also commented the load() line out completely
    # clone = load("res://Characters/Izado/Izado.tscn")
    That still gave me the character as a null object in the exported game.
    I very much appreciate your idea, some other Export-problem seems to haunt me though.
    (.scn in the match script and .scn in the character script also didn't work)

    Something makes this one particular character null in the exported game 🤔

    • Toxe replied to this.

      Asstaroth Is there any reason in particular that you don't use preload(), if I might ask?

      const character_izado = preload("res://Characters/Izado/Izado.tscn")
      
      func some_function():
          var clone = character_izado.instantiate()

        Toxe Yeah, I would love to, I usually always use preload(), this is an exception, because it would result in a Cyclic reference.

        E 0:00:11.836   load: Resource: 'res://Characters/Izado/Izado.tscn' is already being loaded. Cyclic reference?
          <C++ Error>   Condition "!success" is true. Returned: RES()
          <C++ Source>  core/io/resource_loader.cpp:340 @ load()
          <Stack Trace> Match.gd:32 @ _ready()

        Maybe there's a way to use preload() and somehow avoid that? That would be great of course.

          Asstaroth You should avoid recursive instantiation. Let something outside of wizard scene manage its cloning.

            Asstaroth I think these issues got reduced a lot with Godot 4.x. Any chance you can upgrade the engine?

              xyz
              Thanks, I tried to make an autoload-script give the clone to one of the wizard's variables, so he doesn't do it himself anymore, that caused the game to crash when entering the match. Something else I encountered was the match just not starting after selecting the stage, the reason was: the match scene was now not valid anymore. When I preloaded the wizard in the stage select, the stage select scene wasn't accessible anymore. When I preloaded him in the character select screen, that wasn't accessible anymore. When in the main menu, the game wouldn't even start. He is infecting every scene he's in, something is seriously wrong with him, and all of that without any errors in the editor, how? This is so weird.
              He is infecting other scenes with his nullness.
              What I just did was comment out his entire script except for the very first line extends KinematicBody2D, he is still null.
              How does exporting the project turn him into null? And only him? None of the other characters, the circle reference is not even possible anymore at this point, I don*t know what it could be.

              Toxe
              I don't know, don't methods and so on have different names etc? I don't know how possible/how much effort/how difficult that is.

              • xyz replied to this.

                Asstaroth It's better for game to crash in the editor than to crash only in export. Much easier to catch bugs when you have a debugger at your disposal. Your problem is likely with order of initialization. Hard to give specific advice without inspecting the project. Try to replicate the problem in a blank minimal project.

                  xyz SOLVED!

                  Alright so I don't even know how to say this, it sounds way too unbelievable, people will think I'm some toxic internet troll trying to waste people's lives, but I SWEAR this is what it was:
                  I mentioned how I commented out the wizard's entire script and he was still null, I added him to the menu and removed his script, still null. I realized it had to be one of his nodes, so I started deleting them one by one and exporting the project after each one to see if he was still null. This is where the weird part starts.
                  Izado was not null anymore, after I removed his AnimatedSprite Node, so I compared it with the other characters and the only difference I could see was that the others had Playing turned on, with that on he was still null though.
                  Desperately I tried the most ridiculous things and when I removed the animations one by one and exported and checked, I found the problem. The animation called "Idle". Removing it made him not null. I just made a new animation with the same Sprite and called it "Stand", replaced all the Idles with Stands in the script and if I export the project now, he is perfectly there just like when opened with the editor.
                  I know how crazy this sounds, I swear this is not a prank. You know that Veritasium video about how charged particles from space can cause bit flips in PCs? Maybe that's what happened and manipulated the animation, I don't know. 🤷‍♂️
                  Thank you for the effort though!

                  • xyz replied to this.

                    Asstaroth Replicate it in a minimal project and report a bug.
                    Still, you should refactor your architecture to avoid recursive instantiating. It will bite you in the butt again sooner or later.