Live-engine gotchas
Things that only surface when you drive a real 4.7 editor and game, and how to work around each.
Some engine behaviors only show up when you drive a live editor and a running game. Each of these was hit in practice; knowing them up front saves a confusing “why did nothing happen” loop.
Discovery, not memory
Training memory is confidently wrong about specific 4.7 APIs. Lead with engine search and engine class-info on the running build, every time.
Editor-time surprises
scene createwrites the file but does not switch the edited scene. A new--root-type Node3Dscene needs an explicitscene openbefore any 3D-only command works against it.- The editor’s resource cache survives rescans. A script that loads a just-edited scene or script gets the stale copy. Load with
CACHE_MODE_REPLACE_DEEP, and assertget_script() != nullafter instancing, because a script-less instance silently swallows property writes. PackedScene.pack()only keeps nodes whoseowneris the root. Build a scene programmatically and forget to setowner, and the children vanish on save.- Out-of-tree Controls never refresh their cached minimum size, so a
sizewrite clamps to the saved minimum. Add the Control to the tree before sizing it. bake_meshfrom MeshInstance geometry yields an empty navmesh under a headless editor (zero polygons, even synchronously). Bake in a windowed editor, or set the navmesh from colliders.
Headless traps
Screenshots and error capture behave differently without a window.
editor.screenshotneeds a windowed editor (it returns-32000under--headless).runtime.screenshotworks headless, because the game is a separate windowed process.- A real script error in the played game freezes it under a headless editor. The remote debugger breaks with no UI to resume, so every runtime command afterward times out. This includes a hard error in
runtime.eval. Recover withscene stopthenscene play.push_error,push_warning, and shader errors are captured fine; a standalone or windowed run just logs the error and keeps serving IPC.
Value coercion
- Pass packed-array properties as a JSON array of the element literal, for example
'["Vector2(-64,-64)", "Vector2(64,-64)"]'. Each element is coerced to the packed type engine-side. var x := <Array-element arithmetic>fails to compile in GDScript: untypedArrayelements areVariant, so annotate the type (var center: Vector3 = ...). AVector2igrid stores(x, z)as(x, y); it has no.z.