Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generate non-pixel-art scene prop sets from one real source sheet and deliver fixed-slot AtlasTexture resources.
.claude/skills/randallliuxin-scene-prop-set/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 28% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -32% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 157% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 54% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 119% | 0% |
Use this Skill for a set of standalone foreground props derived from a scene, map, stage reference, or an explicit scene brief. It produces usable prop resources only. It does not perform scene placement, PackedScene creation, TileMap editing, collision, navigation, scripts, and gameplay behavior are outside this Skill. Do not use it for pixel art, characters, UI, backgrounds, terrain, or generic compact pickup packs.
Accept the shared Asset Skill request schema at .godotmaker/asset-runtime/schema/asset-skill-request.schema.json with asset_type: "scene-prop-set". Use the shared result schema and checker. This Skill can be invoked directly or by an orchestrator with the same contract. Do not read or write ASSETS.md, tags, stage state, or generated manifests. Read .godotmaker/asset-runtime/asset-skill-contract.md before producing a result; this family adds the source-sheet and atlas rules below.
references is optional. Without references, derive the visual direction and complete object list from the written brief. With references, every path must be a readable image, every declared role must be preserved, and the actual images must be supplied to the pinned provider. A path mentioned only in prompt text is not reference use. If the selected provider cannot attach a required image, return STOP. Never silently change native, codex, gemini, or openai to another provider. For Codex, call image generation with referenced_image_paths containing every readable local reference image.
Reject pixel-art requests. Request painted, illustrated, or rendered non-pixel-art source art. Do not use nearest-neighbor scaling or describe a normal image as pixel art after processing.
The family-specific spec is the exact fixed-slot declaration passed to tools/asset_atlas_assemble.py --declaration after source processing:
json{ "version": 1, "atlas": {"width": 512, "height": 256}, "slots": [ {"name": "market_stall", "rect": [0, 0, 144, 128], "source": ".godotmaker/asset-generation/normalized/market-stall/market_stall.png", "pivot": [0.5, 1.0]}, {"name": "lantern_post", "rect": [160, 0, 64, 160], "source": ".godotmaker/asset-generation/normalized/market-stall/lantern_post.png", "pivot": [0.5, 1.0]} ] }
Slot rectangles are explicit, positive, and non-overlapping [x, y, width, height] values. Their positions are never inferred or auto-packed. Autoslice is allowed only to discover separated source candidates before assembly; it must not invent semantic regions, merge touching props, or alter the declared atlas slots. No automatic packing is permitted. asset_atlas_assemble.py writes canonical lexicographic metadata region order; use it when compiling and reporting the resources. source names the already-normalized image that will fill the declared slot. pivot is optional and defaults to [0.5, 0.5].
The shared physical atlas and metadata use stable paths:
textres://assets/generated/scene-prop-set/<asset_id>/<asset_id>.png res://assets/generated/scene-prop-set/<asset_id>/<asset_id>.json
Every declared logical prop receives one independent runtime resource:
textres://assets/generated/scene-prop-set/<asset_id>/<logical_prop_id>.tres
Return one shared generic result with one region_atlas source and one runtime AtlasTexture output per declared slot. Output names exactly equal metadata region names. Internal processing reports and provenance remain sidecar evidence, never extra keys in the generic result.
references before generation. A PackedScene request, unreadable required reference, unsupported provider attachment, contradictory request, or an invalid slot declaration is a real STOP. Do not ask the execution prompt to decide this outcome.
asset_id, containing allrequested props as visibly separated objects on a solid #FF00FF background. This is one image-generation attempt for the complete set, rather than separate per-slot provider calls. Require no text, labels, UI, actors, floor plane, grid lines, annotations, or watermarks. Keep the provider pixels unchanged at .godotmaker/asset-generation/sources/<asset_id>_source.png.
tool. For Codex, before the call write a one-item plan under .godotmaker/asset-generation/ containing its exact project-relative source_path, every request reference as {role, path}, and require_provider_trace: true even when references is []. After the one image_gen call, write its controlled generated-path report with asset_id, generated_path, references, and provider_trace containing provider, coding model, reasoning, image call identity, image-model identity, and the exact referenced_image_paths supplied to the call. Then run python .godotmaker/asset-runtime/tools/codex_image_claim.py --plan ... --report ... --project-root . --out-report .godotmaker/asset-generation/reports/<asset_id>_source.json. The resulting claim must retain those fields, including empty reference lists for a no-reference request. Never hand-write provider provenance or set require_provider_trace false for this family. For API-backed providers, use tools/asset_source_generate.py --spec with its controlled report path.
powershell python tools/asset_sheet_process.py --source .godotmaker/asset-generation/sources/<asset_id>_source.png --out-dir .godotmaker/asset-generation/candidates/<asset_id> --names <declared-slot-names-in-reading-order> --asset-id <asset_id> --background magenta --snap-mode autoslice --report .godotmaker/asset-generation/reports/<asset_id>_autoslice.json
Do not pass --grid to autoslice. The supplied names count must exactly equal the detected disconnected regions. needs_regeneration, touching props, split props, opaque magenta, an absent requested object, or an unreadable source is diagnostic evidence: repair the source layout, prompt, or processing parameters and re-run. Do not silently discard, merge, or publish partial candidates.
tools/asset_curation_select.py for every selected candidate, firstwriting its selected copy under .godotmaker/asset-generation/selected/<asset_id>/<logical_prop_id>.png. Preserve the shared autoslice/curation report, selected state, and source lineage. A selection failure is a repair diagnostic, not permission to substitute a different prop.
tools/asset_image_finalize.py separately for every selected prop withits declared slot size. For a slot named <logical_prop_id>, use the selected copy as --source, the declaration's source as --out, --resize <slot-width>x<slot-height>, --background magenta, --label <logical_prop_id>, --no-origin, and write .godotmaker/asset-generation/reports/<asset_id>_<logical_prop_id>_finalize.json. preserve aspect ratio and center the prop with transparent padding. Never resize the whole sheet before autoslice and never stretch a tall or wide prop to fill a slot.
tools/asset_atlas_assemble.py. It writes the stable atlas PNG and metadata at the paths above. The metadata is the only runtime authority for named regions and pivots.
.godotmaker/asset-runtime/asset_compiler/atlas_texture.py, using the stable atlas, metadata path, and that exact logical region name. The output .tres filename must equal its logical prop id.
the family standalone_validation.py binding, writes the returned generic result back to <asset_id>-result.json, and records production diagnostics beside it. By default it resolves this project's configured godot_path; --godot-path is an explicit production-run override:
powershell python tools/asset_scene_prop_set_validate.py --request ASSET_REQUEST.json --result .godotmaker/asset-generation/<asset_id>-result.json --report .godotmaker/asset-generation/reports/<asset_id>_validation.json --project-root .
L3 loads every AtlasTexture headlessly through that configured engine. L0 binds the request/result, L1 verifies atlas and metadata delivery, L2 compiles, and L4 verifies every AtlasTexture's shared atlas path, exact region, and zero margin. Read diagnostics, repair source, parameters, metadata, or artifacts, then repeat from the affected step. Return ready only after all applicable layers pass; the first check failure is never the final result unless it is a real STOP condition. This production loop does not perform private Eval L5/L6 grading.
The project-owned deterministic tools above are the preferred processing path. Diagnostic repair may also use Pillow, System.Drawing, ImageMagick, SVG, canvas, Godot drawing, or a temporary script when necessary. Trace the reason, command or code, inputs, outputs, modified files, diagnostics, and repair result. Never fabricate provider calls, reference attachments, or validation evidence. Repeated ad-hoc repairs are a follow-up improvement signal, not a reason to stop this production run.
Return exactly one shared generic result JSON object and no prose. A failed result has outputs: [], validation.passed: false, and explanatory notes; it must not expose partial runtime output.
For /gm-asset, persist the successful generic request/result pair at .godotmaker/asset-generation/<asset_id>-request.json and .godotmaker/asset-generation/<asset_id>-result.json. The declared slots are the complete output contract. The manager validates the result and directly registers every named AtlasTexture in its matching ASSETS.md row. The Skill itself does not register catalog rows or update stage documents.
See samples/result/market-scene.json and samples/atlas/market-scene.json for the stable multi-output shape.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 14,705 | 17,251 | +17% | 1 | 1 | 0% | 2,544 | 5,074 | +99% | 0 | 0 | — |
case-02 | fail→fail | 27,017 | 7,196 | -73% | 1 | 1 | 0% | 5,809 | 3,060 | -47% | 0 | 0 | — |
case-03 | fail→fail | 29,782 | 6,798 | -77% | 1 | 1 | 0% | 6,197 | 2,931 | -53% | 0 | 0 | — |
case-04 | fail→pass | 16,809 | 7,137 | -58% | 1 | 1 | 0% | 3,046 | 3,904 | +28% | 0 | 0 | — |
case-05 | fail→pass | 32,361 | 9,471 | -71% | 1 | 1 | 0% | 6,175 | 4,200 | -32% | 0 | 0 | — |
case-06 | fail→fail | 12,572 | 18,265 | +45% | 1 | 1 | 0% | 1,843 | 6,186 | +236% | 0 | 0 | — |
case-07 | fail→pass | 8,171 | 1,884 | -77% | 1 | 1 | 0% | 1,109 | 2,854 | +157% | 0 | 0 | — |
case-08 | pass→pass | 11,287 | 3,900 | -65% | 1 | 1 | 0% | 1,613 | 3,151 | +95% | 0 | 0 | — |
case-09 | fail→pass | 13,024 | 3,128 | -76% | 1 | 1 | 0% | 1,977 | 3,049 | +54% | 0 | 0 | — |
case-10 | pass→pass | 14,257 | 3,929 | -72% | 1 | 1 | 0% | 2,304 | 3,275 | +42% | 0 | 0 | — |
case-11 | fail→pass | 8,845 | 2,186 | -75% | 1 | 1 | 0% | 1,309 | 2,867 | +119% | 0 | 0 | — |
case-12 | pass→pass | 11,628 | 2,269 | -80% | 1 | 1 | 0% | 2,066 | 2,983 | +44% | 0 | 0 | — |
case-13 | fail→pass | 6,423 | 2,548 | -60% | 1 | 1 | 0% | 1,245 | 3,153 | +153% | 0 | 0 | — |
case-14 | fail→pass | 10,669 | 2,477 | -77% | 1 | 1 | 0% | 1,756 | 3,064 | +74% | 0 | 0 | — |
case-19 | fail→pass | 10,446 | 4,052 | -61% | 1 | 1 | 0% | 1,668 | 3,322 | +99% | 0 | 0 | — |
case-15 | pass→pass | 9,855 | 2,191 | -78% | 1 | 1 | 0% | 1,595 | 2,919 | +83% | 0 | 0 | — |
case-16 | fail→pass | 11,921 | 1,893 | -84% | 1 | 1 | 0% | 1,902 | 2,843 | +49% | 0 | 0 | — |
case-17 | fail→pass | 7,539 | 2,322 | -69% | 1 | 1 | 0% | 1,169 | 2,916 | +149% | 0 | 0 | — |
case-18 | pass→pass | 12,291 | 2,475 | -80% | 1 | 1 | 0% | 1,773 | 2,970 | +68% | 0 | 0 | — |
case-20 | pass→pass | 3,044 | 3,865 | +27% | 1 | 1 | 0% | 494 | 3,200 | +548% | 0 | 0 | — |
case-21 | pass→pass | 2,621 | 2,487 | -5% | 1 | 1 | 0% | 432 | 2,947 | +582% | 0 | 0 | — |
case-22 | fail→fail | 3,488 | 3,377 | -3% | 1 | 1 | 0% | 540 | 3,085 | +471% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 20 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 20 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.