Scene Prop Set Asset
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.
Contract
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, openai, or wan 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:
{
"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:
res://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:
res://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.
Produce
Validate the request, provider, slot declaration, object names, and optional
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.
Generate one real provider source sheet for this asset_id, containing all
requested 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.
Record provenance through the pinned provider's controlled report or claim
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.
Use the raw source sheet directly with the owned deterministic processor:
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.
Run tools/asset_curation_select.py for every selected candidate, first
writing 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.
Run tools/asset_image_finalize.py separately for every selected prop with
its 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.
Assemble only the normalized per-prop PNGs through
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.
Compile every metadata region with
.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.
Run the controlled validation command below for applicable L0-L4. It owns
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:
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.
Result And Handoff
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.
1---2name: scene-prop-set3description: Generate non-pixel-art scene prop sets from one real source sheet and deliver fixed-slot AtlasTexture resources.4---56# Scene Prop Set Asset78Use this Skill for a set of standalone foreground props derived from a scene,9map, stage reference, or an explicit scene brief. It produces usable prop10resources only. It does not perform scene placement, PackedScene creation, TileMap editing,11collision, navigation, scripts, and gameplay behavior are outside this Skill.12Do not use it for pixel art, characters, UI, backgrounds, terrain, or generic13compact pickup packs.1415## Contract1617Accept the shared Asset Skill request schema at18`.godotmaker/asset-runtime/schema/asset-skill-request.schema.json` with19`asset_type: "scene-prop-set"`. Use the shared result schema and checker. This20Skill can be invoked directly or by an orchestrator with the same contract. Do21not read or write `ASSETS.md`, tags, stage state, or generated manifests.22Read `.godotmaker/asset-runtime/asset-skill-contract.md` before producing a23result; this family adds the source-sheet and atlas rules below.2425`references` is optional. Without references, derive the visual direction and26complete object list from the written brief. With references, every path must be27a readable image, every declared role must be preserved, and the actual images28must be supplied to the pinned provider. A path mentioned only in prompt text is29not reference use. If the selected provider cannot attach a required image,30return STOP. Never silently change `native`, `codex`, `gemini`, `openai`, or `wan` to31another provider. For Codex, call image generation with32`referenced_image_paths` containing every readable local reference image.3334Reject pixel-art requests. Request painted, illustrated, or rendered35non-pixel-art source art. Do not use nearest-neighbor scaling or describe a36normal image as pixel art after processing.3738The family-specific `spec` is the exact fixed-slot declaration passed to39`tools/asset_atlas_assemble.py --declaration` after source processing:4041```json42{43 "version": 1,44 "atlas": {"width": 512, "height": 256},45 "slots": [46 {"name": "market_stall", "rect": [0, 0, 144, 128], "source": ".godotmaker/asset-generation/normalized/market-stall/market_stall.png", "pivot": [0.5, 1.0]},47 {"name": "lantern_post", "rect": [160, 0, 64, 160], "source": ".godotmaker/asset-generation/normalized/market-stall/lantern_post.png", "pivot": [0.5, 1.0]}48 ]49}50```5152Slot rectangles are explicit, positive, and non-overlapping `[x, y, width,53height]` values. Their positions are never inferred or auto-packed. Autoslice54is allowed only to discover separated source candidates before assembly; it55must not invent semantic regions, merge touching props, or alter the declared56atlas slots. No automatic packing is permitted. `asset_atlas_assemble.py` writes canonical lexicographic metadata57region order; use it when compiling and reporting the resources. `source` names58the already-normalized image that will fill the declared slot. `pivot` is59optional and defaults to `[0.5, 0.5]`.6061The shared physical atlas and metadata use stable paths:6263```text64res://assets/generated/scene-prop-set/<asset_id>/<asset_id>.png65res://assets/generated/scene-prop-set/<asset_id>/<asset_id>.json66```6768Every declared logical prop receives one independent runtime resource:6970```text71res://assets/generated/scene-prop-set/<asset_id>/<logical_prop_id>.tres72```7374Return one shared generic result with one `region_atlas` source and one75`runtime` `AtlasTexture` output per declared slot. Output names exactly equal76metadata region names. Internal processing reports and provenance remain77sidecar evidence, never extra keys in the generic result.7879## Produce80811. Validate the request, provider, slot declaration, object names, and optional82 references before generation. A PackedScene request, unreadable required83 reference, unsupported provider attachment, contradictory request, or an84 invalid slot declaration is a real STOP. Do not ask the execution prompt to85 decide this outcome.862. Generate one real provider source sheet for this `asset_id`, containing all87 requested props as visibly separated objects on a solid `#FF00FF`88 background. This is one image-generation attempt for the complete set,89 rather than separate per-slot provider calls. Require no text, labels, UI, actors, floor90 plane, grid lines, annotations, or watermarks. Keep the provider pixels91 unchanged at `.godotmaker/asset-generation/sources/<asset_id>_source.png`.923. Record provenance through the pinned provider's controlled report or claim93 tool. For Codex, before the call write a one-item plan under94 `.godotmaker/asset-generation/` containing its exact project-relative95 `source_path`, **every** request reference as `{role, path}`, and96 `require_provider_trace: true` even when references is `[]`. After the one97 `image_gen` call, write its controlled generated-path report with `asset_id`,98 `generated_path`, `references`, and `provider_trace` containing provider,99 coding model, reasoning, image call identity, image-model identity, and the100 exact `referenced_image_paths` supplied to the call. Then run101 `python .godotmaker/asset-runtime/tools/codex_image_claim.py --plan ... --report ...102 --project-root . --out-report .godotmaker/asset-generation/reports/<asset_id>_source.json`.103 The resulting claim must retain those fields, including empty reference lists104 for a no-reference request. Never hand-write provider provenance or set105 `require_provider_trace` false for this family. For API-backed providers, use106 `tools/asset_source_generate.py --spec` with its controlled report path.1074. Use the raw source sheet directly with the owned deterministic processor:108109 ```powershell110 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.json111 ```112113 Do not pass `--grid` to autoslice. The supplied names count must exactly114 equal the detected disconnected regions. `needs_regeneration`, touching115 props, split props, opaque magenta, an absent requested object, or an116 unreadable source is diagnostic evidence: repair the source layout, prompt,117 or processing parameters and re-run. Do not silently discard, merge, or118 publish partial candidates.1195. Run `tools/asset_curation_select.py` for every selected candidate, first120 writing its selected copy under121 `.godotmaker/asset-generation/selected/<asset_id>/<logical_prop_id>.png`.122 Preserve the shared autoslice/curation report, selected state, and source123 lineage. A selection failure is a repair diagnostic, not permission to124 substitute a different prop.1256. Run `tools/asset_image_finalize.py` separately for every selected prop with126 its declared slot size. For a slot named `<logical_prop_id>`, use the127 selected copy as `--source`, the declaration's `source` as `--out`,128 `--resize <slot-width>x<slot-height>`, `--background magenta`,129 `--label <logical_prop_id>`, `--no-origin`, and write130 `.godotmaker/asset-generation/reports/<asset_id>_<logical_prop_id>_finalize.json`.131 preserve aspect ratio and center the prop with transparent padding. Never132 resize the whole sheet before autoslice and never stretch a tall or wide prop133 to fill a slot.1347. Assemble only the normalized per-prop PNGs through135 `tools/asset_atlas_assemble.py`. It writes the stable atlas PNG and metadata136 at the paths above. The metadata is the only runtime authority for named137 regions and pivots.1388. Compile every metadata region with139 `.godotmaker/asset-runtime/asset_compiler/atlas_texture.py`, using the140 stable atlas, metadata path, and that exact logical region name. The output141 `.tres` filename must equal its logical prop id.1429. Run the controlled validation command below for applicable L0-L4. It owns143 the family `standalone_validation.py` binding, writes the returned generic144 result back to `<asset_id>-result.json`, and records production diagnostics145 beside it. By default it resolves this project's configured `godot_path`;146 `--godot-path` is an explicit production-run override:147148 ```powershell149 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 .150 ```151152 L3 loads every AtlasTexture headlessly through that configured engine. L0153 binds the request/result, L1 verifies atlas and metadata delivery, L2154 compiles, and L4 verifies every AtlasTexture's shared atlas path, exact155 region, and zero margin. Read diagnostics, repair source, parameters,156 metadata, or artifacts, then repeat from the affected step. Return ready157 only after all applicable layers pass; the first check failure is never the158 final result unless it is a real STOP condition. This production loop does159 not perform private Eval L5/L6 grading.160161The project-owned deterministic tools above are the preferred processing path.162Diagnostic repair may also use Pillow, System.Drawing, ImageMagick, SVG,163canvas, Godot drawing, or a temporary script when necessary. Trace the reason,164command or code, inputs, outputs, modified files, diagnostics, and repair165result. Never fabricate provider calls, reference attachments, or validation166evidence. Repeated ad-hoc repairs are a follow-up improvement signal, not a167reason to stop this production run.168169## Result And Handoff170171Return exactly one shared generic result JSON object and no prose. A failed172result has `outputs: []`, `validation.passed: false`, and explanatory notes; it173must not expose partial runtime output.174175For `/gm-asset`, persist the successful generic request/result pair at176`.godotmaker/asset-generation/<asset_id>-request.json` and177`.godotmaker/asset-generation/<asset_id>-result.json`. The declared slots are178the complete output contract. The manager validates the result and directly179registers every named AtlasTexture in its matching `ASSETS.md` row. The Skill180itself does not register catalog rows or update stage documents.181182See `samples/result/market-scene.json` and183`samples/atlas/market-scene.json` for the stable multi-output shape.