本文へ移動
cccskills
無料GitHub で公開

scenario-godot-pipeline-automation

Use when Godot 4.7 work must run without a mouse or at scale: batch import of hundreds of GLB props or an AI image-to-3D art drop, naming rules, import presets and post-import scripts, editor plugins, EditorScript and @tool, EditorImportPlugin, GUT or gdUnit4 tests in CI, a GitHub Actions export workflow, GDExtension basics, or a Godot MCP server; also when --import is slow, textures stay uncompressed, tests pass locally but CI fails, or an export ships test folders.

インストール方法を見る

含まれるファイル(30)

  • SKILL.md21.4 KB
  • references/critique.md6.0 KB
  • references/expert-notes.md8.6 KB
  • references/gui-paths.md5.9 KB
  • references/procedures.md28.3 KB
  • references/sources.md11.0 KB
  • scripts/agentkit/pipeline/glb_probe.gd9.8 KB
  • scripts/agentkit/pipeline/prop_audit.gd4.7 KB
  • scripts/agentkit/pipeline/prop_ingest.gd8.2 KB
  • scripts/agentkit/pipeline/prop_rules.gd7.8 KB
  • scripts/agentkit/pipeline/prop_textures.gd2.7 KB
  • scripts/agentkit/pipeline/prop_thumbs.gd3.8 KB
  • scripts/agentkit/prop_pipeline_addon/plugin.cfg251 B
  • scripts/agentkit/prop_pipeline_addon/plugin.gd598 B
  • scripts/agentkit/prop_pipeline_addon/prop_post_import.gd5.0 KB
  • scripts/ci/godot_ci.sh3.0 KB
  • scripts/ci/godot-ci.yml2.8 KB
  • scripts/examples/gdext_c/pipeline_ext.c6.4 KB
  • scripts/examples/gdext_c/pipeline_ext.gdextension259 B
  • scripts/examples/level_importer/lvl_import.gd2.7 KB
  • scripts/examples/level_importer/plugin.cfg246 B
  • scripts/examples/level_importer/plugin.gd370 B
  • scripts/examples/tools/add_spawns.gd829 B
  • scripts/examples/tools/spawn_point.gd698 B
  • scripts/gd_pipeline.py19.7 KB
  • scripts/gdunit/door.gd182 B
  • scripts/gdunit/test_glb_probe.gd2.4 KB
  • scripts/gdunit/test_imported_props.gd616 B
  • scripts/gdunit/test_prop_rules.gd2.7 KB
  • scripts/gdunit/test_scene_runner.gd1.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Godot pipeline automation (tools and build engineer)

Target: Godot 4.7.2.stable, macOS Apple Silicon, gdUnit4 6.2.1.

Expert level here means every step a human would click is a command that CI can run twice with the same result, and every result is checked by a test that has been seen failing. The tools engineer owns the path from an art drop or a commit to a tested export: ingest, import, editor tooling, tests, CI, native extensions and agent channels. If a sibling skill named here is missing from your available skills, ask the user to install it (npx skills add scenario-labs/skills --skill <name>); unattended, proceed from tool schemas and flag the gap.

REQUIRED BACKGROUND: scenario-godot-expert (channels, gd_run and gd_env, the review loop, 4.7 traps). This skill adds scripts/gd_pipeline.py and the AgentKit module scripts/agentkit/pipeline/; it never starts Godot itself, every run goes through gd_run.

Status (2026-10-02): 43 live checks in 9 test files, the round-2 checks (procedures 15) and 8 offline tests, all pass, on a 200-GLB art drop that includes 12 real image-to-3D files (references/procedures.md). Not run: the workflow on GitHub runners, godot-cpp and Rust builds (no scons or cargo here).

Stance (the expert delta)

  1. Write the import settings before the first import. A .glb.import sidecar holding only [remap] importer="scene" and [params] is honored by headless --import, and Godot adds the uid [added, verified M2]. Ingest therefore decides scale, pivot, collision and texture mode per file, then imports once. Rewriting .import files after the fact doubles the import time and dirties the repo.
  2. Pass data to the importer, not code paths. An EditorScenePostImportPlugin declares per-file options (pipeline/fit_height, pipeline/unit_scale, pipeline/fix_pivot, pipeline/collision) that sit in each sidecar, appear in the Import dock, and run under headless --import once the plugin is listed in project.godot [added, verified M6, M10]. One plugin serves the whole project; files without pipeline/prop_id are untouched.
  3. AI image-to-3D files are not DCC files. The 12 real files here call themselves "Khronos glTF Blender I/O", so a generator check cannot find them; only the manifest can. They arrived at arbitrary scale (a toy robot 1.96 m tall) with 2 to 35 materials; 8 of 12 use clearcoat, transmission, ior or specular, which 4.7.2 drops without a warning [added, verified M8]. Fit them to a manifest height; keep DCC props at authored size after a unit fix.
  4. Parse bytes, not paths. Dinoleaf's rule for import code: parse(bytes: PackedByteArray) with the source injected, so the same parser serves res://, user://, zips and tests with literal bytes (sSurjCgebjw [00:04:46]). The GLB probe here works this way, and its tests build GLBs in memory.
  5. A test counts only once you have seen it fail. Butch Wesley, author of GUT: watch red, then green; break the function body to retrofit (ImqhHLlPfZg [00:13:40]). Every suite here has a planted failure that must exit 100.
  6. Judge an export by its artifact, not its exit code. Headless --export-pack crashed at shutdown with signal 11 after "[ DONE ] savezip" in 4 of 5 runs while gdUnit4 was in the pack, and the pack was complete [added, observation]. Check the file, its size and its contents; exclude dev folders from every preset.
  7. Headless output is the truth for agents (Fennara, 2vSYP7GyA5U [00:02:51]). Output-panel scrapers report errors for lines no longer on disk, and the panel does not list every project error [00:06:20]: re-run headless before believing either. MCP servers add scene edits and screenshots, never error truth; call only their headless tools on a shared machine [added].
  8. Test behavior through signals, with bounded waits. Godotneers and Mike Schulze (gdUnit4's author) assert on signals and public results, never private state; call monitor_signals() before the action, since a signal emitted earlier is missed (CreugthdgJ0 [00:36:34]); every wait has a timeout. Headless has no input device, so GUI-input tests are skipped in CI (Butch Wesley [00:48:33]; gdUnit4 6.2.1 prints the same warning).

Establish first

InputChangesDefault
Art drop: count, formats, manifest (file,category,name,height_m,source)ingest rules, AI fitGLB only, manifest required for AI files
Category budgets (triangles, materials, texture side)warn and reject linesprop_rules.gd defaults, set from the frame budget with scenario-godot-performance-export
Texture path: extract plus VRAM pass, or Basis Universal embedimport time, disk, Import dock controlextract
Target platformsVRAM formats (import_etc2_astc for mobile and macOS universal), presetsLinux and macOS desktop
Test frameworkrunner, CI commandgdUnit4 for JUnit reports, GUT if the project already has it; not both
CI hostworkflow file, cachesGitHub Actions, official binaries checked by SHA-512

Workflow

1. Probe and decide (no import). prop_ingest.gd:ingest reads every file as bytes, probes it (glb_probe.gd: header, chunks, triangles, materials, images with their glTF role, extensions, world bounds), applies prop_rules.gd, copies accepted files to res://props/<category>/<id>/<id>.glb with a sidecar, and writes props_manifest.json. Writes happen only when content changes. Put an empty .gdignore in a raw drop inside the project, or the editor imports it too (verified, procedures 15). Collision naming uses Godot's node suffixes, stripped on import (verified, procedures 15): -col keeps the mesh and adds a StaticBody3D with a trimesh shape, -convcol a convex one, -colonly keeps only the body, -noimp drops the node. GATE: counts add up (accepted + warned + rejected + duplicates = files), every reject has a reason, zero engine errors.

2. Import. gd_run.import_project(P). GATE: no ERROR: lines except the exit noise 4.7.2 prints after the work is done (ERROR: N resources still in use at exit, WARNING: N ObjectDB instances were leaked at exit, WARNING: N RIDs of type ... were leaked; filter these three, procedures 15); every accepted prop has a .scn in .godot/imported.

3. Texture pass (extract mode). prop_textures.gd:fix sets VRAM compression, mipmaps, the normal-map flag by glTF role and the size limit by category in each extracted texture's .import, then import again. Headless never draws a frame, so detect_3d never flips and extracted textures stay lossless without this pass [added, verified M7]. GATE: every extracted texture lands as .s3tc.ctex (plus ETC2/ASTC when mobile is a target).

4. Audit and test. prop_audit.gd:audit loads every prop and checks meta version, root name, pivot, fitted height, height range, triangles against three times the budget, the Collision body, no AnimationPlayer, VRAM textures. The same check_prop() runs inside one gdUnit4 case over all props. GATE: 0 failures, JUnit parsed, the planted failure exits 100.

5. Look. prop_thumbs.gd:thumbs (windowed, 160x90 main window, SubViewport renders) frames each prop at three-quarter view next to a red 1 m post; gd_review.contact_sheet builds sheets of 100 at 1500 px. Open them. GATE: no black or missing prop, sizes plausible against the post, nothing floating or sunk.

6. Rerun and change one file. Run ingest and import again: 0 copies, 0 sidecars, nothing reimported. Change one source: only that prop and its textures reimport. GATE: both.

7. Export. Templates: the .tpz holds everything under templates/ (35 files) plus version.txt reading 4.7.2.stable, the folder name; move the contents into export_templates/4.7.2.stable/ under the data dir (~/.local/share/godot on Linux; Voylin AbMESM0UEHk [00:11:34]). C# projects run --build-solutions first (listed in the 4.7.2 --help, implies --editor). Then gd_run.ensure_preset, gp.exclude_from_export(P, preset) (test frameworks, tests, agent tooling, editor-only plugins), gd_run.export. GATE: artifact exists and non-empty, no dev files in the pack listing, verify_pack loads a prop.

8. CI. gp.write_workflow(root, "game", presets=(...)) writes .github/workflows/godot-ci.yml and tools/ci/godot_ci.sh. Run the script locally first, plant a failing test, lint with gp.lint_workflow, HEAD-check the URLs with gp.check_urls. GATE: local run exit 0, planted failure exit 11, actionlint clean, URLs 200.

9. Editor tooling. An EditorScript's _run() is a plain method: a gd_run.run_script(..., editor=True) job opens the scene (EditorInterface.open_scene_from_path), waits a few frames, calls _run(), saves with EditorInterface.save_scene(). Route changes through EditorInterface.get_editor_undo_redo() so Ctrl+Z works later (Queble, nW7YtSSJzbQ [00:04:41]); set owner on new nodes or they vanish on save (docs). Call an @export_tool_button Callable and _get_configuration_warnings() directly. GATE: undo and redo restore the child count, the saved .tscn contains the new nodes, warnings match good and bad inputs.

GridMap. A GridMap level wants a MeshLibrary: create_item(id), set_item_mesh(id, mi.mesh) per imported mesh, saved as .res (verified, procedures 15).

10. Custom formats. An EditorImportPlugin registered by an enabled plugin runs under headless --import; a parse error returns ERR_PARSE_ERROR, leaves valid=false in the sidecar and logs the bad line. GATE: good files load as their resource type, bad files fail with a readable message, a format-version bump reimports through reimport_files().

11. Native code. Only for a profiled hotspot or a native library (Snopek, 4R0uoBJ5XSk [00:03:16]). Smoke-test the chain: dump gdextension_interface.h, build, write the .gdextension, --import, then ClassDB.class_exists and one bound call. Production uses godot-cpp with a renamed entry_symbol (Snopek [00:13:22]); not yet run (no scons here). GATE: class registered, method answers, no load errors.

12. Agent channels. For live scene inspection, clone and build one MCP server in the project's tooling folder, pass GODOT_PATH in its environment only, and call it through gp.mcp_stdio(..., hold_project=P) (shares the GD_MAX lock). Never call tools that launch the editor or game on a shared machine. GATE: tools listed, one headless edit verified by loading the result through gd_run.

Numbers

Measured here (Godot 4.7.2, 2026-10-02), 200-file drop, two fresh runs: relative to that drop. Thumbnail, pack, CI and time-factor numbers are in procedures.md.

MeasureValue
Full pipeline, 200 files (190 imported)21.8 to 24.2 s: ingest 0.6 to 1.4, import 17.4 to 19.7, texture pass 0.4 to 0.5, import 1.9 to 2.7, audit 0.6 to 0.7
Rerun, nothing changedingest 0.6 to 0.7 s, import 1.4 s, 0 files reimported
One file changedimport 1.4 to 1.6 s, 4 imported files touched (scene + texture)
Basis Universal embed instead13.8 to 14.4 s total; .godot/imported 80.6 MB vs 154.5 MB
Reject linemore than 3x the category triangle budget (3 of 12 AI files, 69k to 181k triangles)
gdUnit4 6.2.1 exit codes0 pass, 100 failures or errors, 101 orphans only, 103 headless refused, 104 Godot version unsupported, 105 script errors (GdUnitTestSessionRunner.gd)
godot_ci.sh exit codes [added]10 import, 11 tests, 12 export produced no file

Quality gates

  • Measurable: counts reconcile; 0 engine errors per stage; audit 0 failures; gdUnit4 exit 0 and the planted test exit 100; rerun reimports 0 files; pack listing has no addons/gdUnit4, test/, addons/agentkit, addons/prop_pipeline; project.godot checked for physics/3d/physics_engine="Jolt Physics", the renderer and the plugin line; actionlint clean.
  • Visual: contact sheets opened and read for black or untextured props, scale against the 1 m post, pivots, missing parts.

Common mistakes

MistakeWhat it looks likeFix
Flag AI assets by asset.generatorAI files pass as DCC and keep arbitrary scale (a toy robot 1.96 m tall)manifest source column
Scale every prop to the manifest heightauthored size variation is lost (every lamp becomes 2.2 m)unit fix for DCC, fit only AI
Trust headless to compress extracted textureslossless .ctex, big packstexture pass or [importer_defaults] texture (project-wide, also hits UI)
-rd /abs/path for gdUnit4reports land under <project>/Users/..., CI finds no JUnit-rd res://...
ResourceLoader.exists() as an import checka failed import "exists"read valid=false in the .import
Bump _get_format_version() and run --importnothing reimports-e job: scan(), wait, reimport_files()
Ship with default export filtergdUnit4, tests, agent tools in the packexclude_from_export
upload-artifact the Linux binaryexecutable bit losttar first (Voylin, AbMESM0UEHk [00:20:10])
Loose checksum grepmatches the mono build line tooexact names, expect 2 lines
Toggle plugins from a --script -e jobcontradictory is_plugin_enabled, engine errorsedit [editor_plugins] in project.godot
pause_before_teardown() left in a GUT testa windowed run hangs (killed at 25 s); headless GUT 9.7.1 does not pause-gignore_pause (Butch Wesley [00:32:08], procedures 15)
GUI-input test in CIfails: headless has no input deviceshould_skip_script() returns a reason; GUT counts it Risky, exit 0 (Butch Wesley [00:48:33], procedures 15)
Ignoring GUT's orphan counta leak ships (3 leaked nodes print "3 orphans")a jump from 1 to 80 is a real leak (Butch Wesley [00:57:00])
Trusting a merged .tscnconflict markers break the scene; ResourceLoader.exists() still says trueload every .tscn after a merge (null plus a Parse Error, procedures 15; Lilith Duncan CAJ_iIedx_I [00:01:36])
Trust the first --import after adding a GDExtensionshutdown crash (2 of 3 fresh projects), exit code badcheck extension_list.cfg, run the smoke job

Handoffs

  • Receives GLB, textures and audio with a manifest (blender-expert, scenario-*), budgets (scenario-godot-performance-export), scene conventions (scenario-godot-architecture, scenario-godot-3d-world, which owns how a prop looks and plays).
  • Delivers audited props, a showroom and contact sheets to scenario-godot-3d-world; suites and CI to everyone; presets to scenario-godot-performance-export (signing, stores). Sends decimation to blender-expert, material fixes to scenario-godot-rendering-lighting.

Godot 4.7 notes

  • In an EditorScenePostImportPlugin, _pre_process sees ImporterMeshInstance3D nodes and _post_process sees MeshInstance3D (verified, procedures 15); collision suffixes are already applied in both.
  • EditorScript.get_scene() is deprecated: use EditorInterface.get_edited_scene_root() (verified: the job logs the deprecation).
  • EditorPlugin.add_dock(EditorDock) replaces add_control_to_dock (4.6, still present).
  • Supported glTF extensions in 4.7.2 (M8): basisu, webp, texture_transform, emissive_strength, unlit, pbrSpecularGlossiness, lights_punctual, node_visibility, animation_pointer, OMI physics. No Draco, meshopt, mesh quantization, clearcoat, transmission, ior, specular.
  • GDExtension: classdb_register_extension_class4 and classdb_construct_object2 still load in 4.7.2 but are deprecated; godot-cpp is the production path. A project loads an extension only after --import writes .godot/extension_list.cfg.
  • 4.4+ .uid sidecars move with their scripts; 4.6 .tscn files carry unique_id.

References

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Handle review comments received on GitHub for the current branch's PR or a given PR number or URL, by triaging each unresolved thread, fixing what is warranted, pushing, and replying in each thread, when asked to address, fix or answer PR comments. Works in any Scenario repository.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

Generate one short Conventional Commits squash message describing only the net diff between the PR's base and head, set its header as the PR title, validate it with the repository's commitlint and both copy its description to the clipboard and display it, when asked for a squash message. Works in any Scenario repository, whatever its default branch.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

Refresh the current pull request description from its net changes, following the repository's PR template, when asked to update or write the PR summary. Works in any Scenario repository, whatever its default branch.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

scenario

無料

Use when connecting an AI agent to Scenario (scenario.com) through MCP, or when a task involves generating images, video, 3D, audio, sprites, textures, or game assets. Also when picking a Scenario model, running a LoRA, refining a generation prompt, uploading reference images, waiting on generation jobs, checking credits or quota, hitting Scenario auth, scope, or Forbidden errors, or setting up mcp.scenario.com in Claude Code, Cursor, VSCode, or another agent.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

Use when generating or handling 3D assets through the Scenario MCP server, including text-to-3D or image-to-3D meshes, GPT-6 Astra 3D or Claude Opus 5.5 3D, GLB, FBX, OBJ, STL, or VOX files, PBR-textured or game-ready models, voxel models, multi-view reconstruction, retexture, remesh, UV unwrap, auto-rigging a biped or quadruped, or retargeting an animation, previewing a mesh in the inline 3D viewer, or downloading a model for import into Unity, Unreal, Godot, or Blender.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

Use when generating navigable 3D worlds or Gaussian splat scenes on Scenario via MCP: text-to-world, image-to-world, a 360 panorama or skybox turned into a walkable splat, multi-view photos or a video walkthrough reconstructed as a splat, or one object photo to splat. Keywords: World Labs Marble 1.1, 1.1 Plus, 1.0 Draft, Hunyuan World, HY World, image-to-skybox, skybox-to-splat, multiview-to-splat, TripoSplat, gaussian splatting, 3DGS, spz, world generation, explorable scene, VR.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

scenario-labs のスキルをすべて見る

このスキルの問題を報告する