Skip to content
This repository was archived by the owner on Oct 16, 2026. It is now read-only.

Loop an imported animation through asset_configure_import - #1466

Merged
saworbit merged 8 commits into
mainfrom
batch/import-option-fixes
Oct 15, 2026
Merged

saworbit merged 8 commits into
mainfrom
batch/import-option-fixes

Conversation

@saworbit

@saworbit saworbit commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

An animation imported from a .glb loops only when the scene importer's _subresources option says so, and no tool wrote it. asset_configure_import refused the scene importer, so a character's idle played once and froze, and the only way out was editing the .import file behind the editor.

asset_configure_import now takes, for a scene import:

{"_subresources": {"animations": {"idle": {"settings/loop_mode": 1}}}}

It merges that into the sidecar's dictionary, reimports, and checks both the sidecar and the reloaded scene. If either does not hold, it puts the old file back, as it already does for audio.

Measured first. tools/vibe/probes/scene_import_loop_engine.py, on 4.5.1, 4.6.2 and 4.7.2, with the harness model. All three lines gave the same answers:

  • The importer declares settings/loop_mode as None,Linear,Pingpong at all three tags, and checks nothing. Mode 3 loads as 3, -1 as 255, "linear" as 0, and true and 1.0 as 1. A name the model does not have is kept and applied to nothing. No ERROR, no WARNING, uid kept. So the tool takes 0 to 2 or the declared labels, and only names the scene has, read from the editor before writing.
  • After one reimport the engine writes every option a configured animation has: 2056 keys, about 69 KB. So:
    • The edit parses only the path it changes and keeps every other entry's text, in the engine's own layout.
    • The sidecar cap goes from 1 MiB to 16 MiB. Sixteen configured animations would have passed the old one.
    • resource_inspect reports _subresources by name with each animation's loop mode, instead of the text.
  • An AnimationMixer keeps its libraries as one libraries Dictionary on 4.5, and as one libraries/<name> property each from 4.6. The bridge reads the loop modes from the packed scene's state, both layouts, so nothing in the model is instanced in the editor. The probe found the state agrees with an instance in every case. The binds have the same hashes on all three lines.

An extension from before this change lists no animations, so a scene loop change is refused 501 naming the addon, and nothing is written.

The amendment in docs/SURFACE_AMENDMENTS.md records the widening and its evidence, as the original amendment requires.

tools/list grows by about 160 bytes. With #1465 that comes to about 210,350 of the 210,400 full budget, so I kept the new text short rather than raise it.

Found on CI. On the 4.7.2 runner the editor's own import of the model held reimport_files for 8 to 11 seconds, past the 10 seconds one bridge command may wait, and the way-back call failed:

  • The tool put the previous sidecar back and said so. The registry then replaced that answer with the bare reimport error: an unknown outcome, with request_id as its fix, which this tool does not take. A handler that answers a failed bridge request itself now marks its error, and the registry keeps it in the live envelope. asset_reimport's advice to wait a timeout out as a job was lost the same way, and is marked too. AssetConfigureImport.KeepsItsOwnFailureAnswer drives it through the real dispatcher and fails without either change.
  • asset_configure_import now starts its reimport detached and reads it for up to 45 seconds. A timeout names a retry once the editor is idle.
  • Jobs.LongLaunchRunsAsJobAndCancelStopsIt, from Run a runtime_launch past 120 seconds as a job #1465, read the job id only from a job that finished inside the server's wait. On a slower runner it threw. It now reads either answer shape.

Tests

  • AssetConfigureImport.SceneRequestValidation, SceneSidecarEdit and SceneVerifiesAndRollsBack, and Tools.ResourceInspectSummarisesSubresources. Each fails with its part taken out: the loop overwrite, the scene read-back, the summary, the name check and the mode range.
  • Live harness, requests 7418 to 7427:
    • a dry run;
    • idle looped by name and read back through resource_inspect, and through anim_list_tracks on an instance of the model;
    • an unknown animation and mode 3 refused with nothing written;
    • the way back with the reported previous.

Fixes #1425

An animation imported from a .glb loops only when the scene importer's
_subresources option says so, and no tool wrote it. asset_configure_import
now takes {"_subresources": {"animations": {"idle": {"settings/loop_mode":
1}}}} for a scene import, merges it into the sidecar's dictionary,
reimports, and checks both the sidecar and the reloaded scene, putting the
old file back when either does not hold.

Measured first on 4.5.1, 4.6.2 and 4.7.2 by the new probe
tools/vibe/probes/scene_import_loop_engine.py. The engine refuses
nothing: mode 3 loads as 3, -1 as 255, a word as 0, and a name the model
does not have is kept and applied to nothing. So the tool takes 0 to 2 or
the declared labels None, Linear and Pingpong, and only names the scene
has. After one reimport the engine writes every option a configured
animation has, 2056 keys and about 69 KB, so the edit parses only the path
it changes and keeps every other entry's text, the sidecar cap is 16 MiB,
and resource_inspect reports _subresources by name with each animation's
loop mode instead of the text.

The bridge reads the loop modes from the packed scene's state rather than
an instance, so nothing in the scene is instanced in the editor. An
AnimationMixer keeps its libraries as one libraries Dictionary on 4.5 and
as one libraries/<name> property each from 4.6; the read takes both, and
the probe found it agrees with instancing on all three lines.

Refs #1425
@github-actions github-actions Bot added documentation Improvements or additions to documentation tests Test suites and the contracts they assert addon The Godot addon and the in-engine GDExtension mcp-protocol The MCP wire surface: tools, schemas, annotations tooling Generators, harnesses, and developer tooling labels Oct 15, 2026
@saworbit
saworbit enabled auto-merge (squash) October 15, 2026 13:13
Jobs.LongLaunchRunsAsJobAndCancelStopsIt read the job id from _meta,
which only a job that finished inside the server's wait carries. On a
slower runner the first answer is working, with the job in the text, and
the test threw. It failed that way in CI's release-style suite pass on
#1466 and does locally with the wait set to 0. It now reads either.

Refs #1428
On CI's 4.7.2 runner the editor's own import of the model held
reimport_files past the 10 seconds one bridge command may wait, so the
harness's way-back call failed. The tool put the previous sidecar back and
said so, and the registry then replaced that answer with the bare
reimport error: an unknown outcome whose remedy, request_id, this tool
does not take.

A handler that answers a failed bridge request itself now marks its
error, and the registry keeps it in the live envelope. asset_reimport's
advice to wait a timeout out as a job was dropped the same way and is
marked too. asset_configure_import starts its reimport detached and reads
it for up to 45 seconds, and a timeout there names a retry after the
editor is idle rather than request_id.

Refs #1425
@saworbit
saworbit merged commit e6c99e3 into main Oct 15, 2026
29 checks passed
@saworbit
saworbit deleted the batch/import-option-fixes branch October 15, 2026 14:42
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

addon The Godot addon and the in-engine GDExtension documentation Improvements or additions to documentation mcp-protocol The MCP wire surface: tools, schemas, annotations tests Test suites and the contracts they assert tooling Generators, harnesses, and developer tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No tool sets a scene import option, so an imported animation cannot be made to loop

1 participant