| name | analyze-reference |
| description | Read one reference image and produce a structured scene plan (terrain, objects, palette, lighting, camera). Use when build-world calls into Phase 0. |
Codex adaptation
Use the available Codex tools for image viewing, file inspection, and file edits. In this migrated skill, $1 means the world slug chosen by the user or derived by build-world.
You are analysing one reference image and writing a scene plan to worlds/$1/plan.json.
Procedure
-
Read the reference image. Use the Read tool on worlds/$1/source/reference.png — Use Codex's available image input or view_image on the local PNG. No external vision API.
-
Identify the style anchor. Match against docs/style-references.md anchors:
- Banjo-Kazooie · Treasure Trove Cove (high-stylisation cartoon)
- Wind Waker (cel-shaded)
- Mario Sunshine · Isle Delfino (mid-high stylisation, tropical)
- Pokémon Scarlet/Violet (mid-stylisation, modern toon)
- Donkey Kong Bananza (vibrant cartoon, dense scatter)
- Animal Crossing: New Horizons (tight stylisation)
- Or
"custom" if no clear match.
-
Extract style metadata:
palette: dominant 4-5 hex colours (sand, water, foliage, wood, sky)
level_of_stylization: "high" (Banjo) / "mid" (Pokémon SV) / "low" (Horizon FW)
shading: "toon" / "flat" / "pbr-light"
lighting: "golden-hour" / "noon" / "dusk" / "overcast"
-
Identify the terrain shape. Read the image and decide:
"island" (round, surrounded by water)
"shoreline" (water on one side)
"hills" (no water, vertical relief)
"flat" (no relief)
"crater" (recessed centre)
Plus: ground type (sand/grass/dirt/rock/snow), water level if applicable, approx size in metres (default 12×12 for an island).
-
Enumerate the objects. Look at the image and list every distinct object class you can identify. For each:
id: lowercase-slug (e.g. palm-tall, beach-hut, rock-mossy)
name: human-readable description suitable for a Tripo gen prompt (e.g. "Tall stylised palm tree with curved trunk")
count: how many instances are in the reference (or how many you'd add to look right)
approx_positions: list of [x, y] in metres, anchored at scene origin
scale_hint: "large" / "medium" / "small" / "tiny"
priority: "hero" (visually critical, use Tripo P1 textured) / "filler" (generic, use Trellis 2 or re-instance)
face_limit: integer in [5000, 15000]. Pick from the table in generate-3d/SKILL.md (hero structural 12-15k, hero organic 10-13k, mid-detail 7-9k, filler 5-6k).
The 25-object default cap
Total instance count across all objects MUST be ≤ 25 by default. Each instance = $0.30-0.50 in fal spend. The cap keeps a single scene under $15 of asset generation.
How to fit:
- Identify ~6-10 distinct
ids (object classes).
- Re-instance via
count for repeating items (palms, rocks, shells). Same .glb, different positions — costs $0.50 once.
- Sum of
count across all objects = total instances. Keep this ≤ 25.
If the reference clearly NEEDS more than 25 instances to read correctly:
- Stop and ask the user:
Reference suggests ~N instances. Default cap is 25 (≈$<estimated cost> in fal spend). Raise the cap?
- Only proceed past 25 after explicit user confirmation.
-
Camera framing. Estimate the reference's camera:
framing: "three-quarter aerial" / "side" / "top-down" / "hero-low-angle"
focal_length_mm: usually 35 for the Nintendo aerial-three-quarter look, 50 for closer, 24 for wider
-
Write worlds/$1/plan.json with the structure shown in docs/PIPELINE.md:
{
"world_slug": "$1",
"style": { "anchor": "...", "palette": ["#..."], "level_of_stylization": "...", "shading": "...", "lighting": "..." },
"terrain": { "shape": "...", "ground": "...", "water": { "present": true, "level": -0.05 }, "size_meters": [12, 12], "feature_notes": "..." },
"objects": [
{ "id": "palm-tall", "name": "...", "count": 3, "approx_positions": [[2,1], [3,0.5], [1.5,2]], "scale_hint": "tall", "priority": "hero", "face_limit": 12000 },
...
],
"camera": { "framing": "three-quarter aerial", "focal_length_mm": 35 }
}
- Sanity-check the plan: read it back, confirm total instances (sum of
count) ≤ 25, confirm all priority: hero objects have a clear name suitable for asset generation, confirm every object has a face_limit in [5000, 15000]. Fix in-place if needed.
Output
Returns the plan path: worlds/$1/plan.json. Logs a one-line summary of the analysis (anchor, terrain, object count) for the orchestrator.