Quick answer: Create a SkeletonModificationStack2D resource, assign it to Skeleton2D.modification_stack, then add modifications to that stack. Direct runtime bone tweaks aren’t serialized.
A 2D character’s arm uses CCDIK to follow the mouse. The IK works in play but disappears as soon as you reload the scene. Modifications added directly to a Skeleton2D at runtime aren’t saved with the scene file.
How Modifications Persist
SkeletonModification2D objects (LookAt, CCDIK, FABRIK) live inside a SkeletonModificationStack2D resource. The Skeleton2D references this stack via its modification_stack property. The stack is what gets serialized when you save the scene.
Common mistake: code adds modifications via skeleton.add_child(...) or sets fields on a freshly-constructed stack that’s never assigned. The runtime pose updates; nothing persists.
The Fix
- In FileSystem dock: right-click → New Resource → SkeletonModificationStack2D → save as
player_ik.tres. - Select your Skeleton2D in the scene. In Inspector, drag the .tres into Modification Stack.
- Open the stack resource in the Inspector. Add SkeletonModification2DCCDIK (or LookAt etc.) to the stack.
- Configure bones, targets, and enable each modification.
- Save the scene and the modification stack resource.
Tool Script Editing
If you want to author modifications from script while editing:
@tool
extends Skeleton2D
func _ready():
if Engine.is_editor_hint():
if modification_stack == null:
modification_stack = SkeletonModificationStack2D.new()
modification_stack.modification_count = 1
var ik = SkeletonModification2DCCDIK.new()
modification_stack.set_modification(0, ik)
# Save by hitting Ctrl+S on the scene
The @tool annotation makes the script run in the editor. is_editor_hint guards keep gameplay logic out.
Verifying
Save the scene. Reload it (Project → Reload Current). The IK setup should still be active in the scene tree. Play; bone modifications work without code initialization.
“Modifications live on the stack; the stack persists. Runtime tweaks alone don’t carry over reloads.”
Author IK in the inspector against a saved .tres — runtime code can override but the persisted setup is the source of truth.