Open atlasapplications opened 3 weeks ago
It appears exporting with NativeAOT
in release mode breaks C# projects in v4.3.
Further testing has revealed some important clues. Here's what I've tried since my last post:
Resource
. This is because there may be a bug where custom C# resources are being disposed prematurely as demonstrated here: #83762Node3D
scene from instancing.USER ERROR: Scene instance is missing.
at: instantiate (scene/resources/packed_scene.cpp:244)
This is the same method that fails above in packed_scene.cpp
which is instantiate
; however, the error gets further down.
A part of my testing was using NativeAOT
on a different platform (in this case Windows) because that is the primary difference between publishing to App Store Connect, and say, Android) and this error did not occur initially. However, when I switched Export with debug
off, the same exact error that occurs on iOS now happens on Windows. This may be a regression as I have tested NativeAOT
on Windows with v4.2.2 and this error does not occur.
So it seems that when NativeAOT
is used in combination with the release option, some Godot methods stop working when accessed from C#. My research shows this may be similar to: #94642
These are two commits that could have introduced the regression 465742d & be4cbee
Apparently, when I tested NativeAOT
in the past, I didn't test it in release mode because I tested every single dev build for 4.3 to see which build introduced the regression going all the way back to the stable 4.2.2 and every single one of them fails to export with NativeAOT
on and in release mode. However, when debug is on, the build works correctly. With NativeAOT
off, debug and release modes work.
However, I don't think this changes that there may be a different error introduced in 4.3. This is because when I launch my project in 4.2.2 this is the error:
ERROR: Condition "!sdata.is_valid()" is true. Returning: nullptr
at: instantiate (scene/resources/packed_scene.cpp:220)
This is obviously different than the two other errors above and it's still the same method that's failing which is when I load the packed scene for my top level Node3D
and then call instantiate
.
Here's a quick breakdown on how the errors change:
!sdata.is_valid()
errorIndex nprops
error!sdata.is_valid()
errorIndex nprops
errorScene instance is missing
error
Tested versions
System information
iOS 17.6.1 (Not in debug mode) Windows 11 (NativeAOT enabled & release mode)
Issue description
This is a bug that appears to only affect iOS based devices when distributing one's.ipa
through Apple's App Store (so App Store Connect). This does not occur on iOS when distributing through a debug build on Xcode. When I first load my scene, many of theNodes
load properly, but when I get to the top levelNode3D
that contains most of my game level, it fails to instantiate. The error logs show this:This leads me to believe that it could be related to Apple's restrictions on dynamic code via reflection which is still present in some of Godot's codebase for C#. I tested this with a release build on Android through Google Play and this error does not occur there either.UPDATE It took a long time for me to figure out the exact configuration that was causing the primary world
Node3D
from instancing since my project has over a hundredNode3D
instances that are a part of thatPackedScene
. However, I believe I've narrowed it down to a singleMeshInstance3D
that appears to be responsible.This
MeshInstance3D
has a script attached that utilizes an[Export]
variable of typeStandardMaterial3D
and applies that to theMeshInstance3D
on_Ready()
. I apply a default value in the editor. And in the actual root world where I drag and drop multiple instances I replace this[Export]
value with various differentStandardMaterial3D
assets. When I remove the[Export]
variable and just supply theStandardMaterial3D
withResourceLoader.Load()
instead, the error no longer occurs.Sooo, the workaround is to NOT use
[Export]
forObject
s that inherit from[Resource]
. As a side note, I also back all of myResource
s that I instance fromResourceLoader
into a staticDictionary
that prevents premature disposal ofResource
s. This may or may not be a separate issue altogether which I note below, but seems related.This is a difficult bug to reproduce as I've not found a way yet to create a minimal reproduction sample. My guess is that this bug only has a small chance of happening but since my project has so many eligible
Nodes
for this bug to occur, it was happening to me almost all the time. Nonetheless, here's how one may encounter it...Steps to reproduce
Node3D
as the root.Node3D
with aMeshInstance3D
and attach a script.[Export]
variable that is some kind of material likeStandardMaterial3D
.MeshInstance3D
on_Ready()
MeshInstance3D
nodes in the world.Minimal reproduction project (MRP)
N/A