diff --git a/.github/workflows/art-pipeline.yml b/.github/workflows/art-pipeline.yml index e26799a..81c41dd 100644 --- a/.github/workflows/art-pipeline.yml +++ b/.github/workflows/art-pipeline.yml @@ -33,7 +33,6 @@ jobs: - run: python -m pip install -r requirements-art.txt # pytest runs both styles: unittest classes and plain test functions (unittest discover skipped the latter) - run: python -m pytest scripts -v -p no:cacheprovider - - run: python scripts/creek_layers.py - run: python scripts/split_layers.py --check - run: python scripts/collision_check.py - run: python scripts/export_stage.py --verify --out tmp/stage-export diff --git a/art/direction/boss-jenny.md b/art/direction/boss-jenny.md index 73ce35d..fdfca21 100644 --- a/art/direction/boss-jenny.md +++ b/art/direction/boss-jenny.md @@ -18,7 +18,7 @@ Match the first image's style exactly. Boss arena: the open boss clearing at the - `Jenny15GDX_4.jpg` (GameJam_Merch, outside Git) - `Jenny14GDX-rollout.jpg` (GameJam_Merch, outside Git) - `RolloutJenny16_9.jpeg` (GameJam_Merch, outside Git) -- [after-right.png](../stages/rusty-creek/images/after-right.png) +- [after-right.png](../stages/rusty-creek/prototype/after-right.png) - [hero-preview.png](../sprites/images/hero-preview.png) - [wall-188.jpg](../../references/games/terraria/images/wall-188.jpg) diff --git a/art/direction/combat.md b/art/direction/combat.md index fbb313c..8279f7d 100644 --- a/art/direction/combat.md +++ b/art/direction/combat.md @@ -16,7 +16,7 @@ A real GAMEPLAY screenshot, same camera as the first image: strict side view, wi - [style-master](style-master.md) (this pack) - [hero-preview.png](../sprites/images/hero-preview.png) -- [after-center.png](../stages/rusty-creek/images/after-center.png) +- [after-center.png](../stages/rusty-creek/prototype/after-center.png) - [bad-seed-02.jpg](../../references/games/dead-cells/images/bad-seed-02.jpg) Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/combat.png` · rebuild: `python scripts/make_boards.py draw --config art/direction/direction.json --redo combat` diff --git a/art/direction/direction.json b/art/direction/direction.json index 55ef015..6f1da31 100644 --- a/art/direction/direction.json +++ b/art/direction/direction.json @@ -12,7 +12,7 @@ "factor": 2, "keyed": false, "inputs": [ - "repo:art/stages/rusty-creek/images/after-center.png", + "repo:art/stages/rusty-creek/prototype/after-center.png", "repo:art/sprites/images/hero-preview.png" ], "prompt": "The first image IS our game's stage, Rusty Creek: keep its composition, the blue-green riveted rusty girder maze, ladders, autumn trees and creek exactly, only widen it to 16:9 and finish it as a real game screenshot. Place the hero from the second image (the THD poncho character) small, walking right along the lowest broad girder deck in the left third of the frame. Add a darker foreground band of autumn leaves and a rusty railing along the bottom edge, gentle haze on the far trees, sunlight glinting on the creek, a few drifting leaves. This image will be the reference that every other image of the game must match.", @@ -120,7 +120,7 @@ "merch:Jenny15GDX_4.jpg", "merch:Jenny14GDX-rollout.jpg", "merch:RolloutJenny16_9.jpeg", - "repo:art/stages/rusty-creek/images/after-right.png", + "repo:art/stages/rusty-creek/prototype/after-right.png", "repo:art/sprites/images/hero-preview.png", "repo:references/games/terraria/images/wall-188.jpg" ], @@ -168,7 +168,7 @@ "inputs": [ "out:style-master", "repo:art/sprites/images/hero-preview.png", - "repo:art/stages/rusty-creek/images/after-center.png", + "repo:art/stages/rusty-creek/prototype/after-center.png", "repo:references/games/dead-cells/images/bad-seed-02.jpg" ], "prompt": "A real GAMEPLAY screenshot, same camera as the first image: strict side view, wide, the hero small (one eighth of the screen height). Location: the rusty blue-green girder maze of Rusty Creek (third image). On a broad girder deck the hero from the second image (THD poncho, shadow-filled hood) swings a honey-plywood stacking chair with thin black steel legs in a HORIZONTAL SIDE SWEEP into a six-legged autonomous crab robot, which is knocked back with a small white impact flash and a few sparks and bolts (Dead Cells-style hit feel: short, crisp, readable). Further along the deck a small yellow-wheeled autonomous rover charges in, its lidar glowing red; above, a black autonomous quadcopter drone hovers out of reach. Minimal HUD in the top-left: five battery cells (four full) and a three-segment glitch meter. Dark blurred foreground leaves at the bottom edge. Clean readable silhouettes, no gore.", diff --git a/art/direction/style-master.md b/art/direction/style-master.md index 4ddf7d3..41892aa 100644 --- a/art/direction/style-master.md +++ b/art/direction/style-master.md @@ -14,7 +14,7 @@ The first image IS our game's stage, Rusty Creek: keep its composition, the blue ## Inputs -- [after-center.png](../stages/rusty-creek/images/after-center.png) +- [after-center.png](../stages/rusty-creek/prototype/after-center.png) - [hero-preview.png](../sprites/images/hero-preview.png) Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/style-master.png` · rebuild: `python scripts/make_boards.py draw --config art/direction/direction.json --redo style-master` diff --git a/art/inventory.csv b/art/inventory.csv index f4a0d07..fb4fcfe 100644 --- a/art/inventory.csv +++ b/art/inventory.csv @@ -37,11 +37,11 @@ hidden-garden 05-play,stage layer,"renderer (2), hero (3)",2160×720 ×5,scroll hidden-garden 06,stage layer,renderer (2),–,–,–,n/a,not needed: the foreground blur and occlusion use z 7 (stage/depth.ts) hidden-garden 07-foreground,stage layer,renderer (2) – blur over hero,tiles ×5,scroll 1.2,hg chunks,approved,"approved by Alexander 24 Oct (""I am happy with garden"")" hidden-garden bench,stage prop,prologue (4) – Dexter sits,painted in hg-0-0 05-play,–,hg-0-0,approved,part of the plate (seat ≈ x 700–880 in hg-0-0); Dexter's sit frames are placed on it -rusty-creek layers,stage layer,Region 1,3 chunks × 7 layers,clean + anomaly,rusty-creek sources,approved,art ✅; collision ⬜ (docs/07) +rusty-creek layers,stage layer,Region 1,3 × 3 chunks × up to 7 layers,clean + anomaly (tears),the zone (art/zones/rusty-creek),exported,"the zone as the stage (#157, 26 Oct): rusty_creek_zone.py --stage; collision traced" surfaces / atmosphere data,data,"(2), (3)",–,–,–,approved,"art/stages/hidden-garden/{atmosphere,surfaces}.json and rusty-creek/surfaces.json (#166, #168), exported with the stage" it-props,sprite,"the storm drain (hg-3-1): balloon, eyes in the pipe, paper boat",balloon ~18 · eyes 7 · boat 9,balloon 3 · eyes 3 · boat 3,food sheet look + Dexter's eyes + style master,exported,stage/props.ts places them from the zone's spawn markers; awaiting Alexander's review rubber-chicken,sprite,"secret (hg-0-0, behind the gate pillar)",37×9 (lying),rest 1 · squeak 1,food sheet look + style master,exported,playtest T2; squeaks (synth); awaiting Alexander's review -arena-platform,stage prop,Jenny's arena (rc-2-0 anomaly),202×25 girder,platform 1,maze girder crop + coffee-machine look,drawn,composed into art/stages/rusty-creek/arena/right.png by scripts/arena_platforms.py; awaiting review -arena-chain,stage prop,Jenny's arena (rc-2-0 anomaly),"14 px wide, tiled",chain 2,arena-platform look,drawn,"the platforms hang on it, tiled up to the girder above; awaiting review" +arena-platform,stage prop,Jenny's arena (rc-2-1 anomaly),202×25 girder,platform 1,maze girder crop + coffee-machine look,drawn,composed into art/stages/rusty-creek/arena/rc-2-1.png by scripts/arena_platforms.py; awaiting review +arena-chain,stage prop,Jenny's arena (rc-2-1 anomaly),"14 px wide, tiled",chain 2,arena-platform look,drawn,"the platforms hang on it, tiled up to the girder above; awaiting review" arena-wall,stage prop,Jenny's arena walls (both ends),56×300,lamp 2,coffee-machine look + Jenny sheet,exported,the arena's walls while the fight runs; despeckle 12; awaiting review hero-ladder,sprite,hero (3) – ladder ends,76,ladder-top 4 · ladder-bottom 3,hero sheet + pose photos,exported,the climb onto and off a ladder (traversal.ts times are pinned to these clips) diff --git a/art/locations/hidden-garden-anomaly.md b/art/locations/hidden-garden-anomaly.md index 575601e..114a345 100644 --- a/art/locations/hidden-garden-anomaly.md +++ b/art/locations/hidden-garden-anomaly.md @@ -15,7 +15,7 @@ The SAME stage as the first image - same camera, same layout, same landmarks - a ## Inputs - [hidden-garden-clean](hidden-garden-clean.md) (this pack) -- [after-center.png](../stages/rusty-creek/images/after-center.png) +- [after-center.png](../stages/rusty-creek/prototype/after-center.png) - [style-master-preview.png](../direction/images/style-master-preview.png) Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hidden-garden-anomaly.png` · rebuild: `python scripts/make_boards.py draw --config art/locations/locations.json --redo hidden-garden-anomaly` diff --git a/art/locations/locations.json b/art/locations/locations.json index 2cb97d3..7565676 100644 --- a/art/locations/locations.json +++ b/art/locations/locations.json @@ -26,7 +26,7 @@ "keyed": false, "inputs": [ "out:hidden-garden-clean", - "repo:art/stages/rusty-creek/images/after-center.png", + "repo:art/stages/rusty-creek/prototype/after-center.png", "repo:art/direction/images/style-master-preview.png" ], "prompt": "The SAME stage as the first image - same camera, same layout, same landmarks - a second after the hero touched the pond. The reflection has climbed out of the water: rusty blue-green girders from the second image grow up through the reeds and the deck, the hill path is cut and shifted sideways in places, a strip of trees is stretched into vertical streaks, a rectangle of sky has become flat grey with torn edges. Dexter is gone. Still beautiful, now wrong.", diff --git a/art/locations/rusty-creek-stacked.json b/art/locations/rusty-creek-stacked.json index 53038cb..70d4840 100644 --- a/art/locations/rusty-creek-stacked.json +++ b/art/locations/rusty-creek-stacked.json @@ -54,7 +54,7 @@ "anomaly-1": { "edited": "clean-4.png", "refs": [ - "art/stages/rusty-creek/images/after-center.png", + "art/stages/rusty-creek/prototype/after-center.png", "art/direction/images/style-master-preview.png" ], "prompt": "The first image is the CLEAN version of this zone: keep its layout, camera, bridge, piers, path, creek and every underground room exactly where they are, repaint it as the anomaly. The other images show the anomaly's look: the rust-maze girders (shape, colour, ladders) - never their layout.\n\nZONE: Rusty Creek on a university campus in Bavaria, as one stacked cross-section, top to bottom. ABOVE: a long rusty blue-green riveted plate-girder RAILWAY BRIDGE crosses high over the whole image on two tall concrete piers with ivy; a lower steel truss footbridge hangs under it between the piers; ladders climb from the creek path to the footbridge and from the footbridge to the rail bridge's maintenance walk; a signal gantry with a ladder on the right; soft grassy railway embankments rise left and right; autumn trees (yellow, orange, red) behind. WATER LEVEL: a cement CREEK PATH with a grey pipe railing runs along the water under the bridge; the calm creek surface reflects the trees. BELOW the water line the cutaway shows the BUILT underground of the campus - no natural caves, no rock formations, no stalactites: on the left a big round concrete CULVERT mouth opens at water level and drops through a shaft into a long arched STORM DRAIN tunnel with a shallow channel of water in its floor; in the middle a tall PUMP ROOM with two big teal pumps, vertical pipes and a steel catwalk; then a long SERVICE TUNNEL with cable trays along the ceiling; on the right a FLOODED BASEMENT, its lower half filled with still black water. Warm caged wall lamps light every built room; between the rooms is dark packed earth and concrete.\n\nSTATE: anomaly - the SAME place, same camera, same layout, after the crash. Rusty blue-green riveted girders with ladders have grown through everything: a girder maze rises above the railway bridge and through the trees, girders pierce the culvert, the storm drain and the pump room. The flooded basement and the water under the creek become the RUST MAZE upside down: the creek's WRONG REFLECTION, a drowned girder maze lit cold blue-green. Two or three '404' holes torn in the sky: clean rectangular cuts showing flat black void with a few stretched pixel rows at their edges (no letters). Still calm and pretty at first glance, wrong on the second.\n\nSCALE: this is an overview of a big zone: a person would be only about 27 px tall here, so every room is at least 160 px tall and every passage at least 135 px tall - big, quiet, airy spaces, never cramped. Ground and banks flow in soft rounded Planet-of-Lana curves, never blocky steps or tiles; only built things (bridges, walls, tunnels, rooms) are straight. Strict side view, a cutaway cross-section of the land like an architect's elevation: what is above the water, the water surface, and what is under it.\n\nLOOK: detailed hi-bit pixel art, fine 2-pixel grain, warm autumn palette, low golden light, soft haze between layers, like the game's style master. TONE: secret horror - calm and pretty first, wrong on a second look. No people, no animals, no characters, no text, no letters, no signs with writing, no UI." @@ -62,7 +62,7 @@ "anomaly-2": { "edited": "clean-4.png", "refs": [ - "art/stages/rusty-creek/images/after-center.png", + "art/stages/rusty-creek/prototype/after-center.png", "tmp/zones/concepts/zone-a.png" ], "prompt": "The first image is the CLEAN version of this zone: keep its layout, camera, bridge, piers, path, creek and every underground room exactly where they are, repaint it as the anomaly. The other images show the anomaly's look: the rust-maze girders (shape, colour, ladders) - never their layout.\n\nZONE: Rusty Creek on a university campus in Bavaria, as one stacked cross-section, top to bottom. ABOVE: a long rusty blue-green riveted plate-girder RAILWAY BRIDGE crosses high over the whole image on two tall concrete piers with ivy; a lower steel truss footbridge hangs under it between the piers; ladders climb from the creek path to the footbridge and from the footbridge to the rail bridge's maintenance walk; a signal gantry with a ladder on the right; soft grassy railway embankments rise left and right; autumn trees (yellow, orange, red) behind. WATER LEVEL: a cement CREEK PATH with a grey pipe railing runs along the water under the bridge; the calm creek surface reflects the trees. BELOW the water line the cutaway shows the BUILT underground of the campus - no natural caves, no rock formations, no stalactites: on the left a big round concrete CULVERT mouth opens at water level and drops through a shaft into a long arched STORM DRAIN tunnel with a shallow channel of water in its floor; in the middle a tall PUMP ROOM with two big teal pumps, vertical pipes and a steel catwalk; then a long SERVICE TUNNEL with cable trays along the ceiling; on the right a FLOODED BASEMENT, its lower half filled with still black water. Warm caged wall lamps light every built room; between the rooms is dark packed earth and concrete.\n\nSTATE: anomaly - the SAME place, same camera, same layout, after the crash. Rusty blue-green riveted girders with ladders have grown through everything: a girder maze rises above the railway bridge and through the trees, girders pierce the culvert, the storm drain and the pump room. The flooded basement and the water under the creek become the RUST MAZE upside down: the creek's WRONG REFLECTION, a drowned girder maze lit cold blue-green. Two or three '404' holes torn in the sky: clean rectangular cuts showing flat black void with a few stretched pixel rows at their edges (no letters). Still calm and pretty at first glance, wrong on the second.\n\nSCALE: this is an overview of a big zone: a person would be only about 27 px tall here, so every room is at least 160 px tall and every passage at least 135 px tall - big, quiet, airy spaces, never cramped. Ground and banks flow in soft rounded Planet-of-Lana curves, never blocky steps or tiles; only built things (bridges, walls, tunnels, rooms) are straight. Strict side view, a cutaway cross-section of the land like an architect's elevation: what is above the water, the water surface, and what is under it.\n\nLOOK: detailed hi-bit pixel art, fine 2-pixel grain, warm autumn palette, low golden light, soft haze between layers, like the game's style master. TONE: secret horror - calm and pretty first, wrong on a second look. No people, no animals, no characters, no text, no letters, no signs with writing, no UI." @@ -70,7 +70,7 @@ "anomaly-3": { "edited": "clean-4.png", "refs": [ - "art/stages/rusty-creek/images/after-center.png" + "art/stages/rusty-creek/prototype/after-center.png" ], "prompt": "The first image is the CLEAN version of this zone: keep its layout, camera, bridge, piers, path, creek and every underground room exactly where they are, repaint it as the anomaly. The other images show the anomaly's look: the rust-maze girders (shape, colour, ladders) - never their layout.\n\nZONE: Rusty Creek on a university campus in Bavaria, as one stacked cross-section, top to bottom. ABOVE: a long rusty blue-green riveted plate-girder RAILWAY BRIDGE crosses high over the whole image on two tall concrete piers with ivy; a lower steel truss footbridge hangs under it between the piers; ladders climb from the creek path to the footbridge and from the footbridge to the rail bridge's maintenance walk; a signal gantry with a ladder on the right; soft grassy railway embankments rise left and right; autumn trees (yellow, orange, red) behind. WATER LEVEL: a cement CREEK PATH with a grey pipe railing runs along the water under the bridge; the calm creek surface reflects the trees. BELOW the water line the cutaway shows the BUILT underground of the campus - no natural caves, no rock formations, no stalactites: on the left a big round concrete CULVERT mouth opens at water level and drops through a shaft into a long arched STORM DRAIN tunnel with a shallow channel of water in its floor; in the middle a tall PUMP ROOM with two big teal pumps, vertical pipes and a steel catwalk; then a long SERVICE TUNNEL with cable trays along the ceiling; on the right a FLOODED BASEMENT, its lower half filled with still black water. Warm caged wall lamps light every built room; between the rooms is dark packed earth and concrete.\n\nSTATE: anomaly - the SAME place, same camera, same layout, after the crash. Rusty blue-green riveted girders with ladders have grown through everything: a girder maze rises above the railway bridge and through the trees, girders pierce the culvert, the storm drain and the pump room. The flooded basement and the water under the creek become the RUST MAZE upside down: the creek's WRONG REFLECTION, a drowned girder maze lit cold blue-green. Two or three '404' holes torn in the sky: clean rectangular cuts showing flat black void with a few stretched pixel rows at their edges (no letters). Still calm and pretty at first glance, wrong on the second.\n\nSCALE: this is an overview of a big zone: a person would be only about 27 px tall here, so every room is at least 160 px tall and every passage at least 135 px tall - big, quiet, airy spaces, never cramped. Ground and banks flow in soft rounded Planet-of-Lana curves, never blocky steps or tiles; only built things (bridges, walls, tunnels, rooms) are straight. Strict side view, a cutaway cross-section of the land like an architect's elevation: what is above the water, the water surface, and what is under it.\n\nLOOK: detailed hi-bit pixel art, fine 2-pixel grain, warm autumn palette, low golden light, soft haze between layers, like the game's style master. TONE: secret horror - calm and pretty first, wrong on a second look. No people, no animals, no characters, no text, no letters, no signs with writing, no UI." }, @@ -95,7 +95,7 @@ "anomaly-4": { "edited": "clean-4.png", "refs": [ - "art/stages/rusty-creek/images/after-center.png" + "art/stages/rusty-creek/prototype/after-center.png" ], "prompt": "The first image is the CLEAN version of this zone: keep its layout, camera, the railway bridge, both piers, the creek path, the creek and the underground's culvert shaft and storm drain where they are, and repaint it as the anomaly. The second image shows the anomaly's look: the rust-maze girders (shape, colour, ladders) - never its layout.\n\nZONE: Rusty Creek on a university campus in Bavaria, as one stacked cross-section, top to bottom. ABOVE: a long rusty blue-green riveted plate-girder RAILWAY BRIDGE crosses high over the whole image on two tall concrete piers with ivy; a lower steel truss footbridge hangs under it between the piers; ladders climb from the creek path to the footbridge and from the footbridge to the rail bridge's maintenance walk; a signal gantry with a ladder on the right; soft grassy railway embankments rise left and right; autumn trees (yellow, orange, red) behind. WATER LEVEL: a cement CREEK PATH with a grey pipe railing runs along the water under the bridge; the calm creek surface reflects the trees. BELOW the water line the cutaway shows the BUILT underground of the campus - no natural caves, no rock formations, no stalactites: on the left a big round concrete CULVERT mouth opens at water level and drops through a shaft into a long arched STORM DRAIN tunnel with a shallow channel of water in its floor; in the middle a tall PUMP ROOM with two big teal pumps, vertical pipes and a steel catwalk; then a long SERVICE TUNNEL with cable trays along the ceiling; on the right a FLOODED BASEMENT, its lower half filled with still black water. Warm caged wall lamps light every built room; between the rooms is dark packed earth and concrete.\n\nSTATE: anomaly - the SAME place, same camera, same layout, after the crash. Rusty blue-green riveted girders with ladders have grown through everything: a girder maze rises above the railway bridge and through the trees, girders pierce the culvert, the storm drain and the pump room. The flooded basement and the water under the creek become the RUST MAZE upside down: the creek's WRONG REFLECTION, a drowned girder maze lit cold blue-green. Two or three '404' holes torn in the sky: clean rectangular cuts showing flat black void with a few stretched pixel rows at their edges (no letters). Still calm and pretty at first glance, wrong on the second. UNDERGROUND in the anomaly: keep the built rooms (culvert shaft with ladder, arched storm drain, service tunnel, round outfall) but tall and open - the creek bed is the ceiling of ONE TALL FLOODED HALL in the middle, at least 250 px tall, where the girder maze of the surface hangs UPSIDE DOWN from the ceiling into still water, a mirror image of the maze above lit cold blue-green; girders and ladders grow through the concrete rooms on both sides. The 404 holes are mandatory: two clean black rectangles cut into the open sky between the bridge piers.\n\nSCALE: this is an overview of a big zone: a person would be only about 27 px tall here, so every room is at least 160 px tall and every passage at least 135 px tall - big, quiet, airy spaces, never cramped. Ground and banks flow in soft rounded Planet-of-Lana curves, never blocky steps or tiles; only built things (bridges, walls, tunnels, rooms) are straight. Strict side view, a cutaway cross-section of the land like an architect's elevation: what is above the water, the water surface, and what is under it.\n\nLOOK: detailed hi-bit pixel art, fine 2-pixel grain, warm autumn palette, low golden light, soft haze between layers, like the game's style master. TONE: secret horror - calm and pretty first, wrong on a second look. No people, no animals, no characters, no text, no letters, no signs with writing, no UI." }, @@ -118,7 +118,7 @@ "clean-3": { "edited": "guide-a.png", "refs": [ - "art/stages/rusty-creek/images/before-center.png", + "art/stages/rusty-creek/prototype/before-center.png", "tmp/zones/concepts/zone-a.png" ], "prompt": "The first image is a rough flat LAYOUT GUIDE: keep every shape where it is and paint it fully. The second image is the real Rusty Creek bridge as painted for the game (materials of the bridge, piers, railing, trees, water) and the third a stacked zone concept (its look and its lit cutaway rooms) - never copy their layout.\n\nZONE: Rusty Creek on a university campus in Bavaria, as one stacked cross-section, top to bottom. ABOVE: a long rusty blue-green riveted plate-girder RAILWAY BRIDGE crosses high over the whole image on two tall concrete piers with ivy; a lower steel truss footbridge hangs under it between the piers; ladders climb from the creek path to the footbridge and from the footbridge to the rail bridge's maintenance walk; a signal gantry with a ladder on the right; soft grassy railway embankments rise left and right; autumn trees (yellow, orange, red) behind. WATER LEVEL: a cement CREEK PATH with a grey pipe railing runs along the water under the bridge; the calm creek surface reflects the trees. BELOW the water line the cutaway shows the BUILT underground of the campus - no natural caves, no rock formations, no stalactites: on the left a big round concrete CULVERT mouth opens at water level and drops through a shaft into a long arched STORM DRAIN tunnel with a shallow channel of water in its floor; in the middle a tall PUMP ROOM with two big teal pumps, vertical pipes and a steel catwalk; then a long SERVICE TUNNEL with cable trays along the ceiling; on the right a FLOODED BASEMENT, its lower half filled with still black water. Warm caged wall lamps light every built room; between the rooms is dark packed earth and concrete.\n\nSTATE: clean - the real place, calm, early morning, everything intact and maintained; only a faint wrongness: the still water in the flooded basement reflects a rusty girder that is not there.\n\nSCALE: this is an overview of a big zone: a person would be only about 27 px tall here, so every room is at least 160 px tall and every passage at least 135 px tall - big, quiet, airy spaces, never cramped. Ground and banks flow in soft rounded Planet-of-Lana curves, never blocky steps or tiles; only built things (bridges, walls, tunnels, rooms) are straight. Strict side view, a cutaway cross-section of the land like an architect's elevation: what is above the water, the water surface, and what is under it.\n\nLOOK: detailed hi-bit pixel art, fine 2-pixel grain, warm autumn palette, low golden light, soft haze between layers, like the game's style master. TONE: secret horror - calm and pretty first, wrong on a second look. No people, no animals, no characters, no text, no letters, no signs with writing, no UI." diff --git a/art/sprites/arena-platform.md b/art/sprites/arena-platform.md index 87e693b..258d5b1 100644 --- a/art/sprites/arena-platform.md +++ b/art/sprites/arena-platform.md @@ -15,7 +15,7 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh ## Inputs - [coffee-machine-preview.png](images/coffee-machine-preview.png) -- [girder-reference.png](../stages/rusty-creek/arena/girder-reference.png) +- [girder-reference.png](../stages/rusty-creek/prototype/girder-reference.png) - [style-master-preview.png](../direction/images/style-master-preview.png) Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/arena-platform.png` · rebuild: `python scripts/make_boards.py draw arena-platform --redo --config art/sprites/boards.json` diff --git a/art/sprites/boards.json b/art/sprites/boards.json index 09bc037..9f6a13e 100644 --- a/art/sprites/boards.json +++ b/art/sprites/boards.json @@ -1204,7 +1204,7 @@ "factor": 2, "inputs": [ "repo:art/sprites/images/coffee-machine-preview.png", - "repo:art/stages/rusty-creek/arena/girder-reference.png", + "repo:art/stages/rusty-creek/prototype/girder-reference.png", "repo:art/direction/images/style-master-preview.png" ], "prompt": "On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground shadows, no dust under the objects), with NO text at all - no titles, no captions, no frame numbers, no labels, no readable words or logos: Image 1 is an approved prop sheet from this game: draw in exactly that pixel-art look - solid three-dimensional objects drawn as detailed 2D pixel art with volume, the same pixel grain, palette and warm rim light. Image 2 shows the rusty steel girders of the level these props hang in: copy their material exactly - pale blue-grey painted steel eaten by orange rust, riveted flanges, a dark grated underside. Prop sprite sheet, 2 rows. Row 1, exactly 1 frame: ONE short girder PLATFORM segment hung like a stage rigging bar, seen from slightly below like image 2: a long flat box beam about FIVE times as long as it is tall, its front face with rivets, a lit top flange, a dark grated underside with depth, solid end caps showing its thickness; on top, near each end, a heavy steel eye-bolt with the lowest three links of a rusted chain rising straight up from it. Row 2, exactly 1 frame: ONE long straight vertical rusted steel CHAIN hanging perfectly straight up and down, many identical links, about as long as the platform in row 1, the same chain as on the platform. Both rows at the SAME pixel scale. Rows separated by a wide empty magenta band. No people, no scenery, no sky.", diff --git a/art/stages/rusty-creek/README.md b/art/stages/rusty-creek/README.md index 792d569..80090f0 100644 --- a/art/stages/rusty-creek/README.md +++ b/art/stages/rusty-creek/README.md @@ -1,63 +1,37 @@ # Rusty Creek – stage art -![Rusty Creek, centre chunk](images/after-center.png) +![Rusty Creek, the creek path](images/rc-1-1.png) -Region 1 of the jam slice ([04 – World and levels](../../../docs/04-WORLD-AND-LEVELS.md)). Three chunks of 2160×720 make a 6480×720 stage, seven registered layers each. The creek, bank, rails and trees come from our [crossings photo board](../../../references/campus/crossings.md). The blue-green riveted girder maze is the anomaly's version of the creek: pathfinding imagery, a nod to the algorithms professor. +Region 1 of the jam slice ([04 – World and levels](../../../docs/04-WORLD-AND-LEVELS.md)): a 3 × 3 zone of 2160×720 chunks, grown from one cut of the stacked concept ([#157](https://github.com/THD-AI/WinCS/issues/157), [zone](../../zones/rusty-creek/zone.json), [09 – World pipeline](../../../docs/09-ART-PIPELINE.md)). The rows are rooms; the camera frames the row the hero is in. -## The journey - -| Left – entry, first climb | Centre – branches, reconnection | Right – boss clearing, exit | -| --- | --- | --- | -| ![Left](images/after-left.png) | ![Centre](images/after-center.png) | ![Right](images/after-right.png) | - -The same place before the anomaly (clean campus architecture, nature layers identical): - -| Left | Centre | Right | +| Row | Chunks | What is there | | --- | --- | --- | -| ![Clean left](images/before-left.png) | ![Clean centre](images/before-center.png) | ![Clean right](images/before-right.png) | - -## Seven layers - -| # | Role | Left | Centre | Right | In game | -| --- | --- | --- | --- | --- | --- | -| 01 | Sky / distant trees | [png](images/01-distance-left.png) | [png](images/01-distance-center.png) | = left | Parallax 0.2 | -| 02 | Rear masonry | [png](images/02-supports-left.png) | [png](images/02-supports-center.png) | [png](images/02-supports-right.png) | Scrolls with 05 | -| 03 | Rocky bank | [png](images/03-bank-left.png) | [png](images/03-bank-center.png) | = left | 1.0 | -| 04 | Water / reflection mask | [png](images/04-water-left.png) | [png](images/04-water-center.png) | = left | Hazard zone; reflection clip | -| 05 | Girders and ladders | [png](images/05-traversal-left.png) | [png](images/05-traversal-center.png) | [png](images/05-traversal-right.png) | Collision is authored on top | -| 06 | Near rails | [png](images/06-near-rails-left.png) | [png](images/06-near-rails-center.png) | = left | Foreground 1.1, never collides | -| 07 | Near foliage | [png](images/07-foliage-left.png) | [png](images/07-foliage-center.png) | [png](images/07-foliage-right.png) | Foreground 1.15 | +| 0 – above | `rc-0-0` … `rc-2-0` | The rust maze standing on the railway girder: beams, ladders, open sky. | +| 1 – level | `rc-0-1` … `rc-2-1` | The creek path under the railway girder, three piers with ladders up to its deck, the lit culvert. | +| 2 – below | `rc-0-2` … `rc-2-2` | The drains under the creek bed: catwalks, a steel stair, the drain door under the culvert. | -"= left": shared scenery repeats on the right chunk and is stored once (alias in [media-sources.json](media-sources.json)). In the game, layers 01, 06 and 07 come from one region-wide plate each ([layers/](layers/), `python scripts/depth_layers.py region art/stages/rusty-creek`, #150): per chunk they overlapped at 0.2 and left gaps at 1.1 and 1.15. The creek as the game draws it: [parallax.png](previews/parallax.png). The clean architecture plates are [left](images/clean-architecture-left.png) and [centre](images/clean-architecture-center.png); right = left. +## Two states, one picture -## Route - -[route.json](route.json) is the authored route: 47 nodes and 47 edges (walk, ladder, jump) covering the entry, the climbs, three dead ends with rewards, a reconnection, the boss clearing and the exit. The verifier checks that it is connected, that every dead end returns, that ladders are vertical and that jumps fit the envelope. The collision data that the game uses is drawn separately: see the colour code in [04](../../../docs/04-WORLD-AND-LEVELS.md). - -## Collision - -Six files, one per chunk and state, in the [docs/13 schema](../../../docs/13-PRODUCTION-PIPELINE.md#contract-collisionjson). [chunks.json](chunks.json) maps the ids to the art: `rc-0-0` left, `rc-1-0` centre, `rc-2-0` right. - -- **Clean:** the bridge deck at y 132 across all three chunks, the water below as no-go, the player on the left. Jenny's ram is the `jenny-ram` trigger in the centre ([M4-S1](https://github.com/THD-AI/WinCS/issues/54)). -- **Anomaly:** the hero walks in front of the maze, so every girder deck is a one-way platform and the quays are floors. The first chunk has the chair on the entry deck, the tutorial rover on the low deck, and a pillar down to the water that needs a ladder up: the spur ladder onto the low girder or the tall ladder onto the high beam. The lookout tower holds a muffin and note 1. In the centre, a high route (crab, Leberkäse cache) and a low route (two rovers under a drone) meet again at the coffee machine and Dexter. On the right, the top route and the low route both end at the boss gate before the open girder floor. Jenny and Dexter wait there, the overlook holds note 2, and the exit anomaly is behind the stone steps. - -| Chunk | Clean | Anomaly | -| --- | --- | --- | -| Left | ![](collision/rc-0-0.clean.png) | ![](collision/rc-0-0.anomaly.png) | -| Centre | ![](collision/rc-1-0.clean.png) | ![](collision/rc-1-0.anomaly.png) | -| Right | ![](collision/rc-2-0.clean.png) | ![](collision/rc-2-0.anomaly.png) | +- **Clean:** you land on the path (`rc-0-1`); Jenny comes down it and rams you at the `jenny-ram` box (`rc-1-1`), and Dexter watches from beyond it. The ram turns the region. +- **Anomaly:** the same art with the 404 tears in the maze's sky (`tears/`, from the zone's `world.json`) and the rust maze's fight on the zone's floors: + - the chair at the start; + - rovers on the path, the maze and the drains; + - the drone over the path and the crab on a maze girder; + - the coffee machine with Dexter; + - snacks and notes off the path. -`python scripts/collision_check.py --overlay` checks them all and redraws these overlays. Colours are the [docs/04 legend](../../../docs/04-WORLD-AND-LEVELS.md#collision-and-interaction-annotation); the white box is the 28×76 body. + Jenny's arena is on the right-hand chunk (`rc-2-1`): the boss gate at x 1096, her floor to x 1690, and two platforms on chains from the railway girder (`arena/rc-2-1.png`, [arena_platforms.py](../../../scripts/arena_platforms.py)). -## Rebuild and verify +## Built by -```bash -python scripts/creek_layers.py --build # rebuilds every plate and preview from sources/ + inputs/ -python scripts/creek_layers.py # verifies hashes, alpha, exact recomposition, route graph -``` +`python scripts/zones/rusty_creek_zone.py --stage`, then: +1. `depth_layers.py fill … --only sky` for each row with sky, and `depth_layers.py whole …` for the drains; +2. `rusty_creek_zone.py --fills`; +3. `arena_platforms.py`; +4. `split_layers.py art/stages/rusty-creek`; +5. `collision_check.py art/stages/rusty-creek --surfaces`; +6. `export_stage.py`. -- `sources/` – the generated scene-first architecture plates, the foliage strip and the two seam-repair candidates -- `inputs/` – fixed earlier plates the stage is built from (far trees, bank, water, rails, clean structure, maze) -- `assembly.json` – mask regions, offsets, draw order · `prompts.json` – exact prompts · `stage.json` + `packet.json` + `repair-report.json` – the seam-repair record · `verification.json` – the last verification +Every layer scrolls with the path for now; parallax comes back with region plates quilted per row. -To extend the stage (a new chunk left, right or in the middle), see [09 – Art pipeline](../../../docs/09-ART-PIPELINE.md). +The earlier one-row stage (seven registered layers, 24 Oct) is in git history; the paintings other boards still use as references are in [prototype/](prototype/). diff --git a/art/stages/rusty-creek/arena/rc-2-1.png b/art/stages/rusty-creek/arena/rc-2-1.png new file mode 100644 index 0000000..5e8215a Binary files /dev/null and b/art/stages/rusty-creek/arena/rc-2-1.png differ diff --git a/art/stages/rusty-creek/arena/right.png b/art/stages/rusty-creek/arena/right.png deleted file mode 100644 index 3c125c0..0000000 Binary files a/art/stages/rusty-creek/arena/right.png and /dev/null differ diff --git a/art/stages/rusty-creek/assembly.json b/art/stages/rusty-creek/assembly.json deleted file mode 100644 index 3a131c1..0000000 --- a/art/stages/rusty-creek/assembly.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "version": 2, - "role_order": [ - "01-distance", - "02-supports", - "03-bank", - "04-water", - "05-traversal", - "06-near-rails", - "07-foliage" - ], - "world_size": [ - 6480, - 720 - ], - "panel_size": [ - 2160, - 720 - ], - "draw_order": [ - "01-distance", - "03-bank", - "02-supports", - "05-traversal", - "06-near-rails", - "07-foliage", - "04-water" - ], - "shared_roles": [ - "01-distance", - "03-bank", - "04-water", - "06-near-rails", - "07-foliage" - ], - "masonry_regions": { - "left": [ - [ - 400, - 400, - 455, - 620 - ], - [ - 560, - 170, - 605, - 620 - ], - [ - 860, - 440, - 900, - 620 - ], - [ - 1040, - 420, - 1090, - 620 - ], - [ - 1280, - 135, - 1325, - 620 - ], - [ - 1470, - 250, - 1520, - 620 - ], - [ - 1680, - 350, - 1730, - 620 - ] - ], - "center": [ - [ - 335, - 390, - 380, - 620 - ], - [ - 570, - 275, - 605, - 620 - ], - [ - 890, - 190, - 935, - 620 - ], - [ - 1210, - 390, - 1250, - 620 - ], - [ - 1340, - 130, - 1390, - 620 - ], - [ - 1500, - 460, - 1545, - 620 - ], - [ - 1720, - 205, - 1760, - 620 - ], - [ - 1860, - 405, - 1905, - 620 - ] - ], - "right": [ - [ - 200, - 435, - 240, - 620 - ], - [ - 325, - 295, - 365, - 620 - ], - [ - 510, - 215, - 555, - 620 - ], - [ - 775, - 425, - 820, - 620 - ], - [ - 990, - 150, - 1035, - 620 - ], - [ - 1730, - 190, - 1770, - 620 - ], - [ - 1870, - 390, - 1910, - 620 - ] - ] - }, - "segmentation_note": "Authored disjoint source-region masks, not semantic reconstruction. These are static masonry cuts; ladder/collider/prop rigs remain separate work.", - "nature_note": "Reuse original far, bank, water and rail sources at exact canonical coordinates in BOTH states. Odd chunks mirror the source horizontally, making their shared edges identical. Bank/rails shift down90px. New foliage shrinks only vertically to504px at y263, with a clear boss-floor alpha window. Mirroring is a designed stage, not a surveyed campus map." -} diff --git a/art/stages/rusty-creek/atmosphere.json b/art/stages/rusty-creek/atmosphere.json index cdfe04e..42f0254 100644 --- a/art/stages/rusty-creek/atmosphere.json +++ b/art/stages/rusty-creek/atmosphere.json @@ -1,15 +1,20 @@ { - "note": "Rusty Creek atmosphere (docs/09, Atmosphere): read by game/src/stage/render.ts. Built things stand still – the girder maze, its supports, the rails and the clean bridge never sway (without this file every layer took the default foliage sway and the maze wobbled like leaves). Only the bank's grass and the foreground foliage move.", + "note": "Rusty Creek atmosphere (docs/09, Atmosphere): read by game/src/stage/render.ts. Built things stand still – the rust maze, the railway girder, the piers, the path and the drains never sway. The trees behind sway a little, the creek ripples, the leaves in front move; the drains (no sky) take 'indoor'.", "wind": { "base": 0.45, "gust": 0.9, "gustSpeed": 240, "gustLength": 1400, "frequency": 0.55, "direction": -1 }, "defaults": { "sway": 0, "reach": 260, "anchor": "base", "foliage": 0, "bob": 0, "blur": 0 }, "layers": { - "01-distance": { "sway": 0 }, - "03-bank": { "sway": 1, "reach": 40, "anchor": "top", "foliage": 0.3 }, - "02-supports": { "sway": 0 }, - "clean-architecture": { "sway": 0 }, + "00-sky": { "sway": 0 }, + "01-far": { "sway": 0.4, "reach": 220, "foliage": 0 }, + "02-mid": { "sway": 0.8, "reach": 260, "foliage": 0.25 }, + "03-rear": { "sway": 0 }, "04-water": { "ripple": 1.5, "shimmer": 0.5 }, - "05-traversal": { "sway": 0 }, - "06-near-rails": { "sway": 0 }, - "07-foliage": { "sway": 3.5, "reach": 150, "foliage": 0.15, "bob": 1, "blur": 1.25 } + "05-play": { "sway": 0 }, + "07-foreground": { "sway": 2.5, "reach": 150, "foliage": 0.15, "bob": 0.6, "blur": 0 } + }, + "indoor": { + "03-rear": { "sway": 0 }, + "04-water": { "ripple": 0.8, "shimmer": 0.3 }, + "05-play": { "sway": 0 }, + "07-foreground": { "sway": 1.2, "reach": 80, "anchor": "base", "foliage": 0.6 } } } diff --git a/art/stages/rusty-creek/chunks.json b/art/stages/rusty-creek/chunks.json deleted file mode 100644 index 1fe668c..0000000 --- a/art/stages/rusty-creek/chunks.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "region": "rusty-creek", - "note": "Chunk ids are grid positions (column-row), left to right; art names the plate each state is drawn on.", - "chunks": {"rc-0-0": "left", "rc-1-0": "center", "rc-2-0": "right"}, - "art": {"clean": "images/before-{chunk}.png", "anomaly": "images/after-{chunk}.png"} -} diff --git a/art/stages/rusty-creek/collision/rc-0-0.anomaly.png b/art/stages/rusty-creek/collision/rc-0-0.anomaly.png deleted file mode 100644 index 3278d56..0000000 Binary files a/art/stages/rusty-creek/collision/rc-0-0.anomaly.png and /dev/null differ diff --git a/art/stages/rusty-creek/collision/rc-0-0.clean.png b/art/stages/rusty-creek/collision/rc-0-0.clean.png deleted file mode 100644 index 9801aec..0000000 Binary files a/art/stages/rusty-creek/collision/rc-0-0.clean.png and /dev/null differ diff --git a/art/stages/rusty-creek/collision/rc-1-0.anomaly.png b/art/stages/rusty-creek/collision/rc-1-0.anomaly.png deleted file mode 100644 index ec8d899..0000000 Binary files a/art/stages/rusty-creek/collision/rc-1-0.anomaly.png and /dev/null differ diff --git a/art/stages/rusty-creek/collision/rc-1-0.clean.png b/art/stages/rusty-creek/collision/rc-1-0.clean.png deleted file mode 100644 index 403ba5a..0000000 Binary files a/art/stages/rusty-creek/collision/rc-1-0.clean.png and /dev/null differ diff --git a/art/stages/rusty-creek/collision/rc-2-0.anomaly.png b/art/stages/rusty-creek/collision/rc-2-0.anomaly.png deleted file mode 100644 index 738353e..0000000 Binary files a/art/stages/rusty-creek/collision/rc-2-0.anomaly.png and /dev/null differ diff --git a/art/stages/rusty-creek/collision/rc-2-0.clean.png b/art/stages/rusty-creek/collision/rc-2-0.clean.png deleted file mode 100644 index 5d58c51..0000000 Binary files a/art/stages/rusty-creek/collision/rc-2-0.clean.png and /dev/null differ diff --git a/art/stages/rusty-creek/export.json b/art/stages/rusty-creek/export.json index b4258d2..e1e0324 100644 --- a/art/stages/rusty-creek/export.json +++ b/art/stages/rusty-creek/export.json @@ -1,101 +1,124 @@ { - "note": "Draw order follows creek_layers.py compose(): the plates are soft and blend, so the water is drawn last. z names the docs/04 role; loaders draw in list order. 01-distance (0.2), 06-near-rails (1.1) and 07-foliage (1.15) are region-wide plates in chunk-wide tiles (depth_layers.py region, #150): per chunk they overlapped or left gaps. Clean draws the bank over the clean architecture (24 Oct, Alexander): the bank is in front, the bridge piers behind it. The maze has no railing and no foliage lens (24 Oct, Alexander): only the clean creek does.", + "note": "Rusty Creek as a 3 x 3 zone (#157): the rust maze, the creek path, the drains. Every layer scrolls with the path; the anomaly is the same picture with the 404 tears (05-tears) and Jenny's arena platforms (05-arena, an overlay on rc-2-1).", "chunks": { "rc-0-0": { "x": 0, - "y": 0, - "name": "left" + "y": 0 }, "rc-1-0": { "x": 1, - "y": 0, - "name": "center" + "y": 0 }, "rc-2-0": { "x": 2, - "y": 0, - "name": "right" + "y": 0 + }, + "rc-0-1": { + "x": 0, + "y": 1 + }, + "rc-1-1": { + "x": 1, + "y": 1 + }, + "rc-2-1": { + "x": 2, + "y": 1 + }, + "rc-0-2": { + "x": 0, + "y": 2 + }, + "rc-1-2": { + "x": 1, + "y": 2 + }, + "rc-2-2": { + "x": 2, + "y": 2 } }, "layers": { - "01-distance": { - "file": "layers/rusty-creek.01-distance.{tile}.png", + "00-sky": { + "file": "layers/{name}.00-sky.png", + "z": 0, + "scroll": 1.0, + "optional": true + }, + "01-far": { + "file": "layers/{name}.01-far.png", "z": 1, - "scroll": 0.2, - "region": true, - "rest": "art/stages/rusty-creek/images/01-distance-{name}.png" + "scroll": 1.0, + "optional": true }, - "03-bank": { - "file": "images/03-bank-{name}.png", + "02-mid": { + "file": "layers/{name}.02-mid.png", "z": 2, - "scroll": 1.0 + "scroll": 1.0, + "optional": true }, - "02-supports": { - "file": "images/02-supports-{name}.png", + "03-rear": { + "file": "layers/{name}.03-rear.png", "z": 3, - "scroll": 1.0 + "scroll": 1.0, + "optional": false }, - "clean-architecture": { - "file": "images/clean-architecture-{name}.png", - "z": 3, - "scroll": 1.0 + "04-water": { + "file": "layers/{name}.04-water.png", + "z": 4, + "scroll": 1.0, + "optional": true }, - "05-traversal": { - "file": "images/05-traversal-{name}.png", + "05-play": { + "file": "layers/{name}.05-play.png", "z": 5, - "scroll": 1.0 - }, - "06-near-rails": { - "file": "images/06-near-rails-{name}.png", - "z": 6, "scroll": 1.0, - "dy": 47, - "why": "Attached to the bank (24 Oct, Alexander; the crossings collage: the railing stands on the path's creek-side edge). The plate was painted 47 px off the ground: its post feet at y 519, the bank's coping at 566. Per chunk at scroll 1, so it never slides against the bank." + "optional": true }, - "07-foliage": { - "file": "layers/rusty-creek.07-foliage.{tile}.png", + "07-foreground": { + "file": "layers/{name}.07-foreground.png", "z": 7, - "scroll": 1.15, - "region": true, - "rest": "art/stages/rusty-creek/images/07-foliage-{name}.png", - "dy": 47, - "why": "The lens foliage in front (not on the bank), with the same 47 px Y correction as the railing (24 Oct, Alexander)." + "scroll": 1.0, + "optional": true }, - "04-water": { - "file": "images/04-water-{name}.png", - "z": 4, - "scroll": 1.0 + "05-tears": { + "file": "tears/{name}.png", + "z": 5, + "scroll": 1.0, + "optional": true }, "05-arena": { "file": "arena/{name}.png", "z": 5, "scroll": 1.0, "optional": true, - "why": "Jenny's arena platforms (playtest J6): two beams of the maze's own girder, 84 px over her floor – reachable with a full jump, high enough that she drives under them. An overlay: drawn in the game, left out of the masters (creek_layers.py pins them) and of --verify.", - "overlay": true + "overlay": true, + "why": "Jenny's arena platforms (playtest J6), on chains from the railway girder" } }, "states": { + "clean": [ + "00-sky", + "01-far", + "02-mid", + "03-rear", + "04-water", + "05-play", + "07-foreground" + ], "anomaly": [ - "01-distance", - "03-bank", - "02-supports", - "05-traversal", + "00-sky", + "01-far", + "02-mid", + "03-rear", + "04-water", + "05-play", + "05-tears", "05-arena", - "04-water" - ], - "clean": [ - "01-distance", - "clean-architecture", - "03-bank", - "06-near-rails", - "07-foliage", - "04-water" + "07-foreground" ] }, "composed": { - "anomaly": "images/after-{name}.png", - "clean": "images/before-{name}.png" - }, - "aliases": "media-sources.json" + "clean": "images/{name}.png" + } } diff --git a/art/stages/rusty-creek/fills/rc-0-0.00-sky.png b/art/stages/rusty-creek/fills/rc-0-0.00-sky.png new file mode 100644 index 0000000..024b1b9 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-0-0.00-sky.png differ diff --git a/art/stages/rusty-creek/fills/rc-0-1.00-sky.png b/art/stages/rusty-creek/fills/rc-0-1.00-sky.png new file mode 100644 index 0000000..ac04b13 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-0-1.00-sky.png differ diff --git a/art/stages/rusty-creek/fills/rc-0-2.03-rear.png b/art/stages/rusty-creek/fills/rc-0-2.03-rear.png new file mode 100644 index 0000000..6c3a9c4 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-0-2.03-rear.png differ diff --git a/art/stages/rusty-creek/fills/rc-0-2.04-water.png b/art/stages/rusty-creek/fills/rc-0-2.04-water.png new file mode 100644 index 0000000..aaa4c4c Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-0-2.04-water.png differ diff --git a/art/stages/rusty-creek/fills/rc-1-0.00-sky.png b/art/stages/rusty-creek/fills/rc-1-0.00-sky.png new file mode 100644 index 0000000..8b7643c Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-1-0.00-sky.png differ diff --git a/art/stages/rusty-creek/fills/rc-1-1.00-sky.png b/art/stages/rusty-creek/fills/rc-1-1.00-sky.png new file mode 100644 index 0000000..9898dfa Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-1-1.00-sky.png differ diff --git a/art/stages/rusty-creek/fills/rc-1-2.03-rear.png b/art/stages/rusty-creek/fills/rc-1-2.03-rear.png new file mode 100644 index 0000000..9740559 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-1-2.03-rear.png differ diff --git a/art/stages/rusty-creek/fills/rc-1-2.04-water.png b/art/stages/rusty-creek/fills/rc-1-2.04-water.png new file mode 100644 index 0000000..3b8a242 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-1-2.04-water.png differ diff --git a/art/stages/rusty-creek/fills/rc-2-0.00-sky.png b/art/stages/rusty-creek/fills/rc-2-0.00-sky.png new file mode 100644 index 0000000..d0943e6 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-2-0.00-sky.png differ diff --git a/art/stages/rusty-creek/fills/rc-2-1.00-sky.png b/art/stages/rusty-creek/fills/rc-2-1.00-sky.png new file mode 100644 index 0000000..360fe55 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-2-1.00-sky.png differ diff --git a/art/stages/rusty-creek/fills/rc-2-2.03-rear.png b/art/stages/rusty-creek/fills/rc-2-2.03-rear.png new file mode 100644 index 0000000..ead8311 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-2-2.03-rear.png differ diff --git a/art/stages/rusty-creek/fills/rc-2-2.04-water.png b/art/stages/rusty-creek/fills/rc-2-2.04-water.png new file mode 100644 index 0000000..0e8c731 Binary files /dev/null and b/art/stages/rusty-creek/fills/rc-2-2.04-water.png differ diff --git a/art/stages/rusty-creek/images/01-distance-center.png b/art/stages/rusty-creek/images/01-distance-center.png deleted file mode 100644 index d751e70..0000000 Binary files a/art/stages/rusty-creek/images/01-distance-center.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/01-distance-left.png b/art/stages/rusty-creek/images/01-distance-left.png deleted file mode 100644 index 1ce837c..0000000 Binary files a/art/stages/rusty-creek/images/01-distance-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/02-supports-center.png b/art/stages/rusty-creek/images/02-supports-center.png deleted file mode 100644 index 391afe6..0000000 Binary files a/art/stages/rusty-creek/images/02-supports-center.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/02-supports-left.png b/art/stages/rusty-creek/images/02-supports-left.png deleted file mode 100644 index 0312bcb..0000000 Binary files a/art/stages/rusty-creek/images/02-supports-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/02-supports-right.png b/art/stages/rusty-creek/images/02-supports-right.png deleted file mode 100644 index eaaa450..0000000 Binary files a/art/stages/rusty-creek/images/02-supports-right.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/03-bank-center.png b/art/stages/rusty-creek/images/03-bank-center.png deleted file mode 100644 index 313417e..0000000 Binary files a/art/stages/rusty-creek/images/03-bank-center.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/03-bank-left.png b/art/stages/rusty-creek/images/03-bank-left.png deleted file mode 100644 index 4cfdb0c..0000000 Binary files a/art/stages/rusty-creek/images/03-bank-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/04-water-center.png b/art/stages/rusty-creek/images/04-water-center.png deleted file mode 100644 index 4bbe057..0000000 Binary files a/art/stages/rusty-creek/images/04-water-center.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/04-water-left.png b/art/stages/rusty-creek/images/04-water-left.png deleted file mode 100644 index f89c9ab..0000000 Binary files a/art/stages/rusty-creek/images/04-water-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/05-traversal-center.png b/art/stages/rusty-creek/images/05-traversal-center.png deleted file mode 100644 index a54789d..0000000 Binary files a/art/stages/rusty-creek/images/05-traversal-center.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/05-traversal-left.png b/art/stages/rusty-creek/images/05-traversal-left.png deleted file mode 100644 index bf163af..0000000 Binary files a/art/stages/rusty-creek/images/05-traversal-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/05-traversal-right.png b/art/stages/rusty-creek/images/05-traversal-right.png deleted file mode 100644 index e403d5a..0000000 Binary files a/art/stages/rusty-creek/images/05-traversal-right.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/06-near-rails-center.png b/art/stages/rusty-creek/images/06-near-rails-center.png deleted file mode 100644 index 21a4a7a..0000000 Binary files a/art/stages/rusty-creek/images/06-near-rails-center.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/06-near-rails-left.png b/art/stages/rusty-creek/images/06-near-rails-left.png deleted file mode 100644 index 0808a9c..0000000 Binary files a/art/stages/rusty-creek/images/06-near-rails-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/07-foliage-center.png b/art/stages/rusty-creek/images/07-foliage-center.png deleted file mode 100644 index fc6cf5e..0000000 Binary files a/art/stages/rusty-creek/images/07-foliage-center.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/07-foliage-left.png b/art/stages/rusty-creek/images/07-foliage-left.png deleted file mode 100644 index 29e735c..0000000 Binary files a/art/stages/rusty-creek/images/07-foliage-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/07-foliage-right.png b/art/stages/rusty-creek/images/07-foliage-right.png deleted file mode 100644 index 8fb1eea..0000000 Binary files a/art/stages/rusty-creek/images/07-foliage-right.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/before-left.png b/art/stages/rusty-creek/images/before-left.png deleted file mode 100644 index 81dccf7..0000000 Binary files a/art/stages/rusty-creek/images/before-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/before-right.png b/art/stages/rusty-creek/images/before-right.png deleted file mode 100644 index 0b56136..0000000 Binary files a/art/stages/rusty-creek/images/before-right.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/clean-architecture-center.png b/art/stages/rusty-creek/images/clean-architecture-center.png deleted file mode 100644 index 99876f6..0000000 Binary files a/art/stages/rusty-creek/images/clean-architecture-center.png and /dev/null differ diff --git a/art/stages/rusty-creek/images/clean-architecture-left.png b/art/stages/rusty-creek/images/clean-architecture-left.png deleted file mode 100644 index 5ca29ee..0000000 Binary files a/art/stages/rusty-creek/images/clean-architecture-left.png and /dev/null differ diff --git a/art/zones/rusty-creek/images/rcz-0-0.png b/art/stages/rusty-creek/images/rc-0-0.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-0-0.png rename to art/stages/rusty-creek/images/rc-0-0.png diff --git a/art/zones/rusty-creek/images/rcz-0-1.png b/art/stages/rusty-creek/images/rc-0-1.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-0-1.png rename to art/stages/rusty-creek/images/rc-0-1.png diff --git a/art/zones/rusty-creek/images/rcz-0-2.png b/art/stages/rusty-creek/images/rc-0-2.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-0-2.png rename to art/stages/rusty-creek/images/rc-0-2.png diff --git a/art/zones/rusty-creek/images/rcz-1-0.png b/art/stages/rusty-creek/images/rc-1-0.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-1-0.png rename to art/stages/rusty-creek/images/rc-1-0.png diff --git a/art/zones/rusty-creek/images/rcz-1-1.png b/art/stages/rusty-creek/images/rc-1-1.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-1-1.png rename to art/stages/rusty-creek/images/rc-1-1.png diff --git a/art/zones/rusty-creek/images/rcz-1-2.png b/art/stages/rusty-creek/images/rc-1-2.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-1-2.png rename to art/stages/rusty-creek/images/rc-1-2.png diff --git a/art/zones/rusty-creek/images/rcz-2-0.png b/art/stages/rusty-creek/images/rc-2-0.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-2-0.png rename to art/stages/rusty-creek/images/rc-2-0.png diff --git a/art/zones/rusty-creek/images/rcz-2-1.png b/art/stages/rusty-creek/images/rc-2-1.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-2-1.png rename to art/stages/rusty-creek/images/rc-2-1.png diff --git a/art/zones/rusty-creek/images/rcz-2-2.png b/art/stages/rusty-creek/images/rc-2-2.png similarity index 100% rename from art/zones/rusty-creek/images/rcz-2-2.png rename to art/stages/rusty-creek/images/rc-2-2.png diff --git a/art/stages/rusty-creek/inputs/depth-01-far.png b/art/stages/rusty-creek/inputs/depth-01-far.png deleted file mode 100644 index 8ba80b3..0000000 Binary files a/art/stages/rusty-creek/inputs/depth-01-far.png and /dev/null differ diff --git a/art/stages/rusty-creek/inputs/depth-02-structure.png b/art/stages/rusty-creek/inputs/depth-02-structure.png deleted file mode 100644 index cf4b172..0000000 Binary files a/art/stages/rusty-creek/inputs/depth-02-structure.png and /dev/null differ diff --git a/art/stages/rusty-creek/inputs/depth-03-bank.png b/art/stages/rusty-creek/inputs/depth-03-bank.png deleted file mode 100644 index 54fa7ff..0000000 Binary files a/art/stages/rusty-creek/inputs/depth-03-bank.png and /dev/null differ diff --git a/art/stages/rusty-creek/inputs/depth-04-water.png b/art/stages/rusty-creek/inputs/depth-04-water.png deleted file mode 100644 index fbaa737..0000000 Binary files a/art/stages/rusty-creek/inputs/depth-04-water.png and /dev/null differ diff --git a/art/stages/rusty-creek/inputs/depth-06-rails.png b/art/stages/rusty-creek/inputs/depth-06-rails.png deleted file mode 100644 index 0997610..0000000 Binary files a/art/stages/rusty-creek/inputs/depth-06-rails.png and /dev/null differ diff --git a/art/stages/rusty-creek/inputs/maze-left.png b/art/stages/rusty-creek/inputs/maze-left.png deleted file mode 100644 index 2674ddd..0000000 Binary files a/art/stages/rusty-creek/inputs/maze-left.png and /dev/null differ diff --git a/art/stages/rusty-creek/inputs/maze-right.png b/art/stages/rusty-creek/inputs/maze-right.png deleted file mode 100644 index 80ae7d7..0000000 Binary files a/art/stages/rusty-creek/inputs/maze-right.png and /dev/null differ diff --git a/art/stages/rusty-creek/layers.json b/art/stages/rusty-creek/layers.json new file mode 100644 index 0000000..3eda4ea --- /dev/null +++ b/art/stages/rusty-creek/layers.json @@ -0,0 +1,245 @@ +{ + "note": "Rusty Creek from its zone (art/zones/rusty-creek, scripts/zones/rusty_creek_zone.py --stage).", + "chunks": { + "rc-0-0": { + "states": { + "clean": "images/rc-0-0.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "00-sky", + "alpha": "masks/rc-0-0.00-sky.png" + }, + { + "layer": "01-far", + "alpha": "masks/rc-0-0.01-far.png" + }, + { + "layer": "02-mid", + "alpha": "masks/rc-0-0.02-mid.png" + }, + { + "layer": "04-water", + "alpha": "masks/rc-0-0.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-0-0.05-play.png" + }, + { + "layer": "07-foreground", + "alpha": "masks/rc-0-0.07-foreground.png" + } + ] + }, + "rc-1-0": { + "states": { + "clean": "images/rc-1-0.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "00-sky", + "alpha": "masks/rc-1-0.00-sky.png" + }, + { + "layer": "01-far", + "alpha": "masks/rc-1-0.01-far.png" + }, + { + "layer": "02-mid", + "alpha": "masks/rc-1-0.02-mid.png" + }, + { + "layer": "04-water", + "alpha": "masks/rc-1-0.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-1-0.05-play.png" + }, + { + "layer": "07-foreground", + "alpha": "masks/rc-1-0.07-foreground.png" + } + ] + }, + "rc-2-0": { + "states": { + "clean": "images/rc-2-0.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "00-sky", + "alpha": "masks/rc-2-0.00-sky.png" + }, + { + "layer": "01-far", + "alpha": "masks/rc-2-0.01-far.png" + }, + { + "layer": "02-mid", + "alpha": "masks/rc-2-0.02-mid.png" + }, + { + "layer": "04-water", + "alpha": "masks/rc-2-0.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-2-0.05-play.png" + }, + { + "layer": "07-foreground", + "alpha": "masks/rc-2-0.07-foreground.png" + } + ] + }, + "rc-0-1": { + "states": { + "clean": "images/rc-0-1.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "00-sky", + "alpha": "masks/rc-0-1.00-sky.png" + }, + { + "layer": "01-far", + "alpha": "masks/rc-0-1.01-far.png" + }, + { + "layer": "02-mid", + "alpha": "masks/rc-0-1.02-mid.png" + }, + { + "layer": "04-water", + "alpha": "masks/rc-0-1.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-0-1.05-play.png" + }, + { + "layer": "07-foreground", + "alpha": "masks/rc-0-1.07-foreground.png" + } + ] + }, + "rc-1-1": { + "states": { + "clean": "images/rc-1-1.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "00-sky", + "alpha": "masks/rc-1-1.00-sky.png" + }, + { + "layer": "01-far", + "alpha": "masks/rc-1-1.01-far.png" + }, + { + "layer": "02-mid", + "alpha": "masks/rc-1-1.02-mid.png" + }, + { + "layer": "04-water", + "alpha": "masks/rc-1-1.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-1-1.05-play.png" + }, + { + "layer": "07-foreground", + "alpha": "masks/rc-1-1.07-foreground.png" + } + ] + }, + "rc-2-1": { + "states": { + "clean": "images/rc-2-1.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "00-sky", + "alpha": "masks/rc-2-1.00-sky.png" + }, + { + "layer": "01-far", + "alpha": "masks/rc-2-1.01-far.png" + }, + { + "layer": "02-mid", + "alpha": "masks/rc-2-1.02-mid.png" + }, + { + "layer": "04-water", + "alpha": "masks/rc-2-1.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-2-1.05-play.png" + }, + { + "layer": "07-foreground", + "alpha": "masks/rc-2-1.07-foreground.png" + } + ] + }, + "rc-0-2": { + "states": { + "clean": "images/rc-0-2.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "04-water", + "alpha": "masks/rc-0-2.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-0-2.05-play.png" + } + ] + }, + "rc-1-2": { + "states": { + "clean": "images/rc-1-2.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "04-water", + "alpha": "masks/rc-1-2.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-1-2.05-play.png" + } + ] + }, + "rc-2-2": { + "states": { + "clean": "images/rc-2-2.png" + }, + "default": "03-rear", + "rules": [ + { + "layer": "04-water", + "alpha": "masks/rc-2-2.04-water.png" + }, + { + "layer": "05-play", + "alpha": "masks/rc-2-2.05-play.png" + } + ] + } + } +} diff --git a/art/stages/rusty-creek/layers/rc-0-0.00-sky.png b/art/stages/rusty-creek/layers/rc-0-0.00-sky.png new file mode 100644 index 0000000..d54212e Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-0.00-sky.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-0.01-far.png b/art/stages/rusty-creek/layers/rc-0-0.01-far.png new file mode 100644 index 0000000..410b86f Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-0.01-far.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-0.02-mid.png b/art/stages/rusty-creek/layers/rc-0-0.02-mid.png new file mode 100644 index 0000000..45150d9 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-0.02-mid.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-0.03-rear.png b/art/stages/rusty-creek/layers/rc-0-0.03-rear.png new file mode 100644 index 0000000..0965126 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-0.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-0.04-water.png b/art/stages/rusty-creek/layers/rc-0-0.04-water.png new file mode 100644 index 0000000..54ae240 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-0.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-0.05-play.png b/art/stages/rusty-creek/layers/rc-0-0.05-play.png new file mode 100644 index 0000000..5b2a165 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-0.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-0.07-foreground.png b/art/stages/rusty-creek/layers/rc-0-0.07-foreground.png new file mode 100644 index 0000000..49f63c3 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-0.07-foreground.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-1.00-sky.png b/art/stages/rusty-creek/layers/rc-0-1.00-sky.png new file mode 100644 index 0000000..1069dd1 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-1.00-sky.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-1.01-far.png b/art/stages/rusty-creek/layers/rc-0-1.01-far.png new file mode 100644 index 0000000..1cf94c0 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-1.01-far.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-1.02-mid.png b/art/stages/rusty-creek/layers/rc-0-1.02-mid.png new file mode 100644 index 0000000..6563ccf Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-1.02-mid.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-1.03-rear.png b/art/stages/rusty-creek/layers/rc-0-1.03-rear.png new file mode 100644 index 0000000..7ce4eac Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-1.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-1.04-water.png b/art/stages/rusty-creek/layers/rc-0-1.04-water.png new file mode 100644 index 0000000..a58858e Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-1.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-1.05-play.png b/art/stages/rusty-creek/layers/rc-0-1.05-play.png new file mode 100644 index 0000000..6e6a814 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-1.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-1.07-foreground.png b/art/stages/rusty-creek/layers/rc-0-1.07-foreground.png new file mode 100644 index 0000000..dbdd31f Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-1.07-foreground.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-2.03-rear.png b/art/stages/rusty-creek/layers/rc-0-2.03-rear.png new file mode 100644 index 0000000..1681ff3 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-2.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-2.04-water.png b/art/stages/rusty-creek/layers/rc-0-2.04-water.png new file mode 100644 index 0000000..76681a6 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-2.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-0-2.05-play.png b/art/stages/rusty-creek/layers/rc-0-2.05-play.png new file mode 100644 index 0000000..bd9ef8d Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-0-2.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-0.00-sky.png b/art/stages/rusty-creek/layers/rc-1-0.00-sky.png new file mode 100644 index 0000000..b610ac5 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-0.00-sky.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-0.01-far.png b/art/stages/rusty-creek/layers/rc-1-0.01-far.png new file mode 100644 index 0000000..0884c87 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-0.01-far.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-0.02-mid.png b/art/stages/rusty-creek/layers/rc-1-0.02-mid.png new file mode 100644 index 0000000..630e8f9 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-0.02-mid.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-0.03-rear.png b/art/stages/rusty-creek/layers/rc-1-0.03-rear.png new file mode 100644 index 0000000..9def39c Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-0.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-0.04-water.png b/art/stages/rusty-creek/layers/rc-1-0.04-water.png new file mode 100644 index 0000000..bd1daac Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-0.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-0.05-play.png b/art/stages/rusty-creek/layers/rc-1-0.05-play.png new file mode 100644 index 0000000..b6843cc Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-0.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-0.07-foreground.png b/art/stages/rusty-creek/layers/rc-1-0.07-foreground.png new file mode 100644 index 0000000..e1aa5a2 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-0.07-foreground.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-1.00-sky.png b/art/stages/rusty-creek/layers/rc-1-1.00-sky.png new file mode 100644 index 0000000..28c8e66 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-1.00-sky.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-1.01-far.png b/art/stages/rusty-creek/layers/rc-1-1.01-far.png new file mode 100644 index 0000000..5ce7e72 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-1.01-far.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-1.02-mid.png b/art/stages/rusty-creek/layers/rc-1-1.02-mid.png new file mode 100644 index 0000000..190127f Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-1.02-mid.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-1.03-rear.png b/art/stages/rusty-creek/layers/rc-1-1.03-rear.png new file mode 100644 index 0000000..d457072 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-1.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-1.04-water.png b/art/stages/rusty-creek/layers/rc-1-1.04-water.png new file mode 100644 index 0000000..4fa4d53 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-1.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-1.05-play.png b/art/stages/rusty-creek/layers/rc-1-1.05-play.png new file mode 100644 index 0000000..632aef7 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-1.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-1.07-foreground.png b/art/stages/rusty-creek/layers/rc-1-1.07-foreground.png new file mode 100644 index 0000000..f375f3d Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-1.07-foreground.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-2.03-rear.png b/art/stages/rusty-creek/layers/rc-1-2.03-rear.png new file mode 100644 index 0000000..5830065 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-2.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-2.04-water.png b/art/stages/rusty-creek/layers/rc-1-2.04-water.png new file mode 100644 index 0000000..a2ad6ee Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-2.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-1-2.05-play.png b/art/stages/rusty-creek/layers/rc-1-2.05-play.png new file mode 100644 index 0000000..844d620 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-1-2.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-0.00-sky.png b/art/stages/rusty-creek/layers/rc-2-0.00-sky.png new file mode 100644 index 0000000..08238ee Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-0.00-sky.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-0.01-far.png b/art/stages/rusty-creek/layers/rc-2-0.01-far.png new file mode 100644 index 0000000..4b08a7c Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-0.01-far.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-0.02-mid.png b/art/stages/rusty-creek/layers/rc-2-0.02-mid.png new file mode 100644 index 0000000..01115fb Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-0.02-mid.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-0.03-rear.png b/art/stages/rusty-creek/layers/rc-2-0.03-rear.png new file mode 100644 index 0000000..0967ec1 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-0.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-0.04-water.png b/art/stages/rusty-creek/layers/rc-2-0.04-water.png new file mode 100644 index 0000000..0a30611 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-0.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-0.05-play.png b/art/stages/rusty-creek/layers/rc-2-0.05-play.png new file mode 100644 index 0000000..459c3d9 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-0.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-0.07-foreground.png b/art/stages/rusty-creek/layers/rc-2-0.07-foreground.png new file mode 100644 index 0000000..7e92a5e Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-0.07-foreground.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-1.00-sky.png b/art/stages/rusty-creek/layers/rc-2-1.00-sky.png new file mode 100644 index 0000000..39ebe0d Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-1.00-sky.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-1.01-far.png b/art/stages/rusty-creek/layers/rc-2-1.01-far.png new file mode 100644 index 0000000..01c24c5 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-1.01-far.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-1.02-mid.png b/art/stages/rusty-creek/layers/rc-2-1.02-mid.png new file mode 100644 index 0000000..31780df Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-1.02-mid.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-1.03-rear.png b/art/stages/rusty-creek/layers/rc-2-1.03-rear.png new file mode 100644 index 0000000..b87dde0 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-1.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-1.04-water.png b/art/stages/rusty-creek/layers/rc-2-1.04-water.png new file mode 100644 index 0000000..6919aaf Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-1.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-1.05-play.png b/art/stages/rusty-creek/layers/rc-2-1.05-play.png new file mode 100644 index 0000000..e7863e6 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-1.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-1.07-foreground.png b/art/stages/rusty-creek/layers/rc-2-1.07-foreground.png new file mode 100644 index 0000000..7433359 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-1.07-foreground.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-2.03-rear.png b/art/stages/rusty-creek/layers/rc-2-2.03-rear.png new file mode 100644 index 0000000..17ce8c6 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-2.03-rear.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-2.04-water.png b/art/stages/rusty-creek/layers/rc-2-2.04-water.png new file mode 100644 index 0000000..873ba1b Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-2.04-water.png differ diff --git a/art/stages/rusty-creek/layers/rc-2-2.05-play.png b/art/stages/rusty-creek/layers/rc-2-2.05-play.png new file mode 100644 index 0000000..b4509d0 Binary files /dev/null and b/art/stages/rusty-creek/layers/rc-2-2.05-play.png differ diff --git a/art/stages/rusty-creek/layers/rusty-creek.01-distance.0.png b/art/stages/rusty-creek/layers/rusty-creek.01-distance.0.png deleted file mode 100644 index 663a26b..0000000 Binary files a/art/stages/rusty-creek/layers/rusty-creek.01-distance.0.png and /dev/null differ diff --git a/art/stages/rusty-creek/layers/rusty-creek.01-distance.1.png b/art/stages/rusty-creek/layers/rusty-creek.01-distance.1.png deleted file mode 100644 index 7871916..0000000 Binary files a/art/stages/rusty-creek/layers/rusty-creek.01-distance.1.png and /dev/null differ diff --git a/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.0.png b/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.0.png deleted file mode 100644 index 702fea7..0000000 Binary files a/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.0.png and /dev/null differ diff --git a/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.1.png b/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.1.png deleted file mode 100644 index e268fff..0000000 Binary files a/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.1.png and /dev/null differ diff --git a/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.2.png b/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.2.png deleted file mode 100644 index 5cee465..0000000 Binary files a/art/stages/rusty-creek/layers/rusty-creek.06-near-rails.2.png and /dev/null differ diff --git a/art/stages/rusty-creek/layers/rusty-creek.07-foliage.0.png b/art/stages/rusty-creek/layers/rusty-creek.07-foliage.0.png deleted file mode 100644 index 964b13f..0000000 Binary files a/art/stages/rusty-creek/layers/rusty-creek.07-foliage.0.png and /dev/null differ diff --git a/art/stages/rusty-creek/layers/rusty-creek.07-foliage.1.png b/art/stages/rusty-creek/layers/rusty-creek.07-foliage.1.png deleted file mode 100644 index eff63b8..0000000 Binary files a/art/stages/rusty-creek/layers/rusty-creek.07-foliage.1.png and /dev/null differ diff --git a/art/stages/rusty-creek/layers/rusty-creek.07-foliage.2.png b/art/stages/rusty-creek/layers/rusty-creek.07-foliage.2.png deleted file mode 100644 index 28fd529..0000000 Binary files a/art/stages/rusty-creek/layers/rusty-creek.07-foliage.2.png and /dev/null differ diff --git a/art/stages/rusty-creek/masks/rc-0-0.00-sky.png b/art/stages/rusty-creek/masks/rc-0-0.00-sky.png new file mode 100644 index 0000000..6fce475 Binary files /dev/null and b/art/stages/rusty-creek/masks/rc-0-0.00-sky.png differ diff --git a/art/zones/rusty-creek/masks/rcz-0-0.01-far.png b/art/stages/rusty-creek/masks/rc-0-0.01-far.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-0.01-far.png rename to art/stages/rusty-creek/masks/rc-0-0.01-far.png diff --git a/art/zones/rusty-creek/masks/rcz-0-0.02-mid.png b/art/stages/rusty-creek/masks/rc-0-0.02-mid.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-0.02-mid.png rename to art/stages/rusty-creek/masks/rc-0-0.02-mid.png diff --git a/art/zones/rusty-creek/masks/rcz-0-0.04-water.png b/art/stages/rusty-creek/masks/rc-0-0.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-0.04-water.png rename to art/stages/rusty-creek/masks/rc-0-0.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-0-0.05-play.png b/art/stages/rusty-creek/masks/rc-0-0.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-0.05-play.png rename to art/stages/rusty-creek/masks/rc-0-0.05-play.png diff --git a/art/zones/rusty-creek/masks/rcz-0-0.07-foreground.png b/art/stages/rusty-creek/masks/rc-0-0.07-foreground.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-0.07-foreground.png rename to art/stages/rusty-creek/masks/rc-0-0.07-foreground.png diff --git a/art/stages/rusty-creek/masks/rc-0-1.00-sky.png b/art/stages/rusty-creek/masks/rc-0-1.00-sky.png new file mode 100644 index 0000000..62793ed Binary files /dev/null and b/art/stages/rusty-creek/masks/rc-0-1.00-sky.png differ diff --git a/art/zones/rusty-creek/masks/rcz-0-1.01-far.png b/art/stages/rusty-creek/masks/rc-0-1.01-far.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-1.01-far.png rename to art/stages/rusty-creek/masks/rc-0-1.01-far.png diff --git a/art/zones/rusty-creek/masks/rcz-0-1.02-mid.png b/art/stages/rusty-creek/masks/rc-0-1.02-mid.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-1.02-mid.png rename to art/stages/rusty-creek/masks/rc-0-1.02-mid.png diff --git a/art/zones/rusty-creek/masks/rcz-0-1.04-water.png b/art/stages/rusty-creek/masks/rc-0-1.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-1.04-water.png rename to art/stages/rusty-creek/masks/rc-0-1.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-0-1.05-play.png b/art/stages/rusty-creek/masks/rc-0-1.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-1.05-play.png rename to art/stages/rusty-creek/masks/rc-0-1.05-play.png diff --git a/art/zones/rusty-creek/masks/rcz-0-1.07-foreground.png b/art/stages/rusty-creek/masks/rc-0-1.07-foreground.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-1.07-foreground.png rename to art/stages/rusty-creek/masks/rc-0-1.07-foreground.png diff --git a/art/zones/rusty-creek/masks/rcz-0-2.04-water.png b/art/stages/rusty-creek/masks/rc-0-2.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-2.04-water.png rename to art/stages/rusty-creek/masks/rc-0-2.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-0-2.05-play.png b/art/stages/rusty-creek/masks/rc-0-2.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-0-2.05-play.png rename to art/stages/rusty-creek/masks/rc-0-2.05-play.png diff --git a/art/stages/rusty-creek/masks/rc-1-0.00-sky.png b/art/stages/rusty-creek/masks/rc-1-0.00-sky.png new file mode 100644 index 0000000..abe34e1 Binary files /dev/null and b/art/stages/rusty-creek/masks/rc-1-0.00-sky.png differ diff --git a/art/zones/rusty-creek/masks/rcz-1-0.01-far.png b/art/stages/rusty-creek/masks/rc-1-0.01-far.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-0.01-far.png rename to art/stages/rusty-creek/masks/rc-1-0.01-far.png diff --git a/art/zones/rusty-creek/masks/rcz-1-0.02-mid.png b/art/stages/rusty-creek/masks/rc-1-0.02-mid.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-0.02-mid.png rename to art/stages/rusty-creek/masks/rc-1-0.02-mid.png diff --git a/art/zones/rusty-creek/masks/rcz-1-0.04-water.png b/art/stages/rusty-creek/masks/rc-1-0.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-0.04-water.png rename to art/stages/rusty-creek/masks/rc-1-0.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-1-0.05-play.png b/art/stages/rusty-creek/masks/rc-1-0.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-0.05-play.png rename to art/stages/rusty-creek/masks/rc-1-0.05-play.png diff --git a/art/zones/rusty-creek/masks/rcz-1-0.07-foreground.png b/art/stages/rusty-creek/masks/rc-1-0.07-foreground.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-0.07-foreground.png rename to art/stages/rusty-creek/masks/rc-1-0.07-foreground.png diff --git a/art/stages/rusty-creek/masks/rc-1-1.00-sky.png b/art/stages/rusty-creek/masks/rc-1-1.00-sky.png new file mode 100644 index 0000000..a20bbcf Binary files /dev/null and b/art/stages/rusty-creek/masks/rc-1-1.00-sky.png differ diff --git a/art/zones/rusty-creek/masks/rcz-1-1.01-far.png b/art/stages/rusty-creek/masks/rc-1-1.01-far.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-1.01-far.png rename to art/stages/rusty-creek/masks/rc-1-1.01-far.png diff --git a/art/zones/rusty-creek/masks/rcz-1-1.02-mid.png b/art/stages/rusty-creek/masks/rc-1-1.02-mid.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-1.02-mid.png rename to art/stages/rusty-creek/masks/rc-1-1.02-mid.png diff --git a/art/zones/rusty-creek/masks/rcz-1-1.04-water.png b/art/stages/rusty-creek/masks/rc-1-1.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-1.04-water.png rename to art/stages/rusty-creek/masks/rc-1-1.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-1-1.05-play.png b/art/stages/rusty-creek/masks/rc-1-1.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-1.05-play.png rename to art/stages/rusty-creek/masks/rc-1-1.05-play.png diff --git a/art/zones/rusty-creek/masks/rcz-1-1.07-foreground.png b/art/stages/rusty-creek/masks/rc-1-1.07-foreground.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-1.07-foreground.png rename to art/stages/rusty-creek/masks/rc-1-1.07-foreground.png diff --git a/art/zones/rusty-creek/masks/rcz-1-2.04-water.png b/art/stages/rusty-creek/masks/rc-1-2.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-2.04-water.png rename to art/stages/rusty-creek/masks/rc-1-2.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-1-2.05-play.png b/art/stages/rusty-creek/masks/rc-1-2.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-1-2.05-play.png rename to art/stages/rusty-creek/masks/rc-1-2.05-play.png diff --git a/art/stages/rusty-creek/masks/rc-2-0.00-sky.png b/art/stages/rusty-creek/masks/rc-2-0.00-sky.png new file mode 100644 index 0000000..6c7add0 Binary files /dev/null and b/art/stages/rusty-creek/masks/rc-2-0.00-sky.png differ diff --git a/art/zones/rusty-creek/masks/rcz-2-0.01-far.png b/art/stages/rusty-creek/masks/rc-2-0.01-far.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-0.01-far.png rename to art/stages/rusty-creek/masks/rc-2-0.01-far.png diff --git a/art/zones/rusty-creek/masks/rcz-2-0.02-mid.png b/art/stages/rusty-creek/masks/rc-2-0.02-mid.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-0.02-mid.png rename to art/stages/rusty-creek/masks/rc-2-0.02-mid.png diff --git a/art/zones/rusty-creek/masks/rcz-2-0.04-water.png b/art/stages/rusty-creek/masks/rc-2-0.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-0.04-water.png rename to art/stages/rusty-creek/masks/rc-2-0.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-2-0.05-play.png b/art/stages/rusty-creek/masks/rc-2-0.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-0.05-play.png rename to art/stages/rusty-creek/masks/rc-2-0.05-play.png diff --git a/art/zones/rusty-creek/masks/rcz-2-0.07-foreground.png b/art/stages/rusty-creek/masks/rc-2-0.07-foreground.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-0.07-foreground.png rename to art/stages/rusty-creek/masks/rc-2-0.07-foreground.png diff --git a/art/stages/rusty-creek/masks/rc-2-1.00-sky.png b/art/stages/rusty-creek/masks/rc-2-1.00-sky.png new file mode 100644 index 0000000..b86faf7 Binary files /dev/null and b/art/stages/rusty-creek/masks/rc-2-1.00-sky.png differ diff --git a/art/zones/rusty-creek/masks/rcz-2-1.01-far.png b/art/stages/rusty-creek/masks/rc-2-1.01-far.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-1.01-far.png rename to art/stages/rusty-creek/masks/rc-2-1.01-far.png diff --git a/art/zones/rusty-creek/masks/rcz-2-1.02-mid.png b/art/stages/rusty-creek/masks/rc-2-1.02-mid.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-1.02-mid.png rename to art/stages/rusty-creek/masks/rc-2-1.02-mid.png diff --git a/art/zones/rusty-creek/masks/rcz-2-1.04-water.png b/art/stages/rusty-creek/masks/rc-2-1.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-1.04-water.png rename to art/stages/rusty-creek/masks/rc-2-1.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-2-1.05-play.png b/art/stages/rusty-creek/masks/rc-2-1.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-1.05-play.png rename to art/stages/rusty-creek/masks/rc-2-1.05-play.png diff --git a/art/zones/rusty-creek/masks/rcz-2-1.07-foreground.png b/art/stages/rusty-creek/masks/rc-2-1.07-foreground.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-1.07-foreground.png rename to art/stages/rusty-creek/masks/rc-2-1.07-foreground.png diff --git a/art/zones/rusty-creek/masks/rcz-2-2.04-water.png b/art/stages/rusty-creek/masks/rc-2-2.04-water.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-2.04-water.png rename to art/stages/rusty-creek/masks/rc-2-2.04-water.png diff --git a/art/zones/rusty-creek/masks/rcz-2-2.05-play.png b/art/stages/rusty-creek/masks/rc-2-2.05-play.png similarity index 100% rename from art/zones/rusty-creek/masks/rcz-2-2.05-play.png rename to art/stages/rusty-creek/masks/rc-2-2.05-play.png diff --git a/art/stages/rusty-creek/media-sources.json b/art/stages/rusty-creek/media-sources.json deleted file mode 100644 index a34cb9e..0000000 --- a/art/stages/rusty-creek/media-sources.json +++ /dev/null @@ -1,590 +0,0 @@ -{ - "date": "2026-10-23", - "method": "Built-in image generation; exact prompts in prompts.json. Deterministic masks and assembly in scripts/creek_layers.py.", - "images": [ - { - "file": "images/01-distance-center.png", - "sha256": "daca8373929b1ff78e666e4ee8baf28c27d9fdb37c1f109676bb6a5329a134ab", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 255, - 255 - ] - }, - { - "file": "images/01-distance-left.png", - "sha256": "9c5e674c08acf69c30f236c603cd703d717a298f52059d5a4b6dbb70435eb441", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 255, - 255 - ] - }, - { - "file": "images/02-supports-center.png", - "sha256": "497699d909fad8d0e8edd97c9d281b7f69a9feba8e4e7322e7d0b56bdb1f51fb", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/02-supports-left.png", - "sha256": "5bb25b83a4fe356583a0d5e91e7a7fc7888953f5b802bd32db61c1ac70e4ba60", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/02-supports-right.png", - "sha256": "2a488663aeffa3416f2802ee64292403bd14ae33b983d06da402c1b68faa93a5", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/03-bank-center.png", - "sha256": "91615a80ef092f7b6718a17686702aa230a82ec934d445b786ad926d330f5968", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/03-bank-left.png", - "sha256": "43c706c64b4b0acd0e39a1ff68d5fa7860a0321417ee1bcc76983c42143d36bc", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/04-water-center.png", - "sha256": "dfbc3545c334d42e54ee749ab832192c35a94204ed26d9a381b07734d72edefe", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 254 - ] - }, - { - "file": "images/04-water-left.png", - "sha256": "209cc4112cc2c79a894ae66c5b2bb76e048a0609f71288463ebdf8d89f4ca269", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 254 - ] - }, - { - "file": "images/05-traversal-center.png", - "sha256": "d6d585ec82ed76cc453666b9937fbb730d2c9dbcabb7706f273a9ca6c2d49a79", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/05-traversal-left.png", - "sha256": "dc9d89acfbcc2c5c70b7e06a8c906b47dfc6b8abf41c499c29efbf349d9c0393", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/05-traversal-right.png", - "sha256": "adbaeab111e6a35f5bfbdcfcba600e4b168a3f00988ded7741e00ed120afbc17", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/06-near-rails-center.png", - "sha256": "9f04ebb7822d097efb350f317a7e92dacff9648845785b828b4af8bfcab56b7b", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/06-near-rails-left.png", - "sha256": "1b1d8443cf3e81085cd7570e095e6be179e6a6473340fe20d579d6c310207958", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/07-foliage-center.png", - "sha256": "0f8b4b1304edbcffb43bf825b4eb295d5eeea92943c8917a2cd9f6fa54726875", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/07-foliage-left.png", - "sha256": "235dcd2a454d91f9d2068b8f80fca2686073208a329239a0c45267d7aee1110d", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/07-foliage-right.png", - "sha256": "d362f85c692b97227e486f745b0852f1df8727e7d8589973ed684663ddbf8282", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/after-center.png", - "sha256": "3daa7427b2d034cb7601fce273bc9c58e203ffb96042caa26d15e7695660d0ed", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGB", - "alpha_extrema": null - }, - { - "file": "images/after-left.png", - "sha256": "24e3e22faa87f5f29064ec9d8135d570b45911f71b3aaadd2e1028e3e048fafc", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGB", - "alpha_extrema": null - }, - { - "file": "images/after-right.png", - "sha256": "8675501c603c8c8222a2a1599886b5da6d74f79a35545594cc08c1c22462d507", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGB", - "alpha_extrema": null - }, - { - "file": "images/before-center.png", - "sha256": "60256972211fd1745c97284932b187cd4a7ce57c64891af8ba8b5939e16d916e", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGB", - "alpha_extrema": null - }, - { - "file": "images/before-left.png", - "sha256": "3d41e7088eddb54b30272a13a1fb39bd556fc8bd17089cc1a90c9bc64eeb8857", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGB", - "alpha_extrema": null - }, - { - "file": "images/before-right.png", - "sha256": "2fd236fc5fc09361937b03d9a22c4fb989eeff651d79bfcc88b344a994fd28f5", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGB", - "alpha_extrema": null - }, - { - "file": "images/clean-architecture-center.png", - "sha256": "27db299ab720cb82a53e244f596653252c99be299f8106add56e122ceae8d36d", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "images/clean-architecture-left.png", - "sha256": "4287597c3e2c8f25932598b4c14da23861e6b7f24df5b93c4d94d866d5715fee", - "dimensions": [ - 2160, - 720 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "sources/center.png", - "sha256": "5ea6cc9267a38673431b6f92a34f152adf6595b3c81205c98a997e9f7145cd17", - "dimensions": [ - 2172, - 724 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "sources/left.png", - "sha256": "ecfb982c97c2d696d960e8e77f9138f6799773c166f901b2291e58784f092703", - "dimensions": [ - 2172, - 724 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "sources/plants.png", - "sha256": "eaa77ca6b343e3c2211f9c08040ff5fec55ee4064efc421d2e19b284a04c173b", - "dimensions": [ - 2172, - 724 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "sources/right.png", - "sha256": "3c822b406cd8f71612e7dbaac928222cf0b64dbb897aa8eb5e0ea150f3c66d17", - "dimensions": [ - 2172, - 724 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "sources/structure--center--right-candidate.png", - "sha256": "6c1f64a1502711f7e5d04e98bd4d58996d03c985bc8a6dc31345ebe338642166", - "dimensions": [ - 2172, - 724 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - }, - { - "file": "sources/structure--left--center-candidate.png", - "sha256": "c2959d99b9a96e8fadd44fe9fd87aace3942afe6dfbb874b7d8769e67b240ca6", - "dimensions": [ - 2172, - 724 - ], - "mode": "RGBA", - "alpha_extrema": [ - 0, - 255 - ] - } - ], - "source_inputs": [ - { - "project_file": "art/stages/rusty-creek/inputs/depth-01-far.png", - "sha256": "7e4c6412262835f4773ee833bd8261e598dc72d989f2ec282f96198d6aa2d50e" - }, - { - "project_file": "art/stages/rusty-creek/inputs/depth-02-structure.png", - "sha256": "7d8f9a496dd0f2b9df181fb230310b5a8ee2711563d9303906903b984f96c26d" - }, - { - "project_file": "art/stages/rusty-creek/inputs/depth-03-bank.png", - "sha256": "8d2198d4c16c8fb34377750dbe5c1aa85239205700c936ffc0db55e3fcd2d250" - }, - { - "project_file": "art/stages/rusty-creek/inputs/depth-04-water.png", - "sha256": "e8066555a380ab5f00f176205504f75a10a56cda00d897ddd9caac20ed531033" - }, - { - "project_file": "art/stages/rusty-creek/inputs/depth-06-rails.png", - "sha256": "865947d12d0b3889bf4d286bb64fe4efc997a0bf3b9222ded7b1a92a5bbbdf19" - }, - { - "project_file": "references/campus/images/crossings.png", - "sha256": "1ebf3b8dd8791a5a2bb9f3d7023b3d8721f513b021334b66cd3813c3e60b1102" - }, - { - "project_file": "art/stages/rusty-creek/inputs/maze-left.png", - "sha256": "504d7e65bbfb91766f6722004889780a9bbfa17b9a641163c23a0484e43a7966" - }, - { - "project_file": "art/stages/rusty-creek/inputs/maze-center.png", - "sha256": "755ad4b57e457496c5aba12b4bbf9cc298e69a96138402ea678d8fe08c659bc0" - }, - { - "project_file": "art/stages/rusty-creek/inputs/maze-right.png", - "sha256": "d2dbfa146797fa147f561485f95a8034bcd9930e259cd0c502d40875ff995240" - } - ], - "aliases": { - "01-distance-right.png": "01-distance-left.png", - "03-bank-right.png": "03-bank-left.png", - "04-water-right.png": "04-water-left.png", - "06-near-rails-right.png": "06-near-rails-left.png", - "clean-architecture-right.png": "clean-architecture-left.png" - }, - "layer_order": [ - "01-distance", - "02-supports", - "03-bank", - "04-water", - "05-traversal", - "06-near-rails", - "07-foliage" - ], - "shared_roles": [ - "01-distance", - "03-bank", - "04-water", - "06-near-rails", - "07-foliage" - ], - "packet": { - "version": 1, - "config_sha256": "765700b16a4fc7b73bf85ef93c35a71bc335014c4f12884945d520da77aa2195", - "panel_size": [ - 2160, - 720 - ], - "world_size": [ - 6480, - 720 - ], - "chunks": [ - "left", - "center", - "right" - ], - "chunk_origins": { - "left": [ - 0, - 0 - ], - "center": [ - 2160, - 0 - ], - "right": [ - 4320, - 0 - ] - }, - "model": "gpt-image-2.5-sunburst", - "layers": [ - { - "id": "structure", - "role": "scene-first broad steel and masonry; separate after seam repair", - "world": "structure-before.png", - "sha256": "47108c4573dd1423a469b16734404013bd6b92ff2cd5b873b2960c638fbadf5a", - "inputs": [ - { - "chunk": "left", - "file": "tmp/stages/rusty-creek/left-normalized.png", - "sha256": "3d2bba0475a97c8db7db861f04d27e63b3999faf1eabd2f13bf1d4616a0ac11c", - "native_size": [ - 2160, - 720 - ], - "normalized_size": [ - 2160, - 720 - ] - }, - { - "chunk": "center", - "file": "tmp/stages/rusty-creek/center-normalized.png", - "sha256": "2d9d31a326cfb3aeec774ef723ca967b71c927416271b25717b75060ac15ff3b", - "native_size": [ - 2160, - 720 - ], - "normalized_size": [ - 2160, - 720 - ] - }, - { - "chunk": "right", - "file": "tmp/stages/rusty-creek/right-normalized.png", - "sha256": "c8d9e0e51bfbddf1ce65f934aec9bf04d83d43f0480b26a153900d53e0f9048f", - "native_size": [ - 2160, - 720 - ], - "normalized_size": [ - 2160, - 720 - ] - } - ] - } - ], - "jobs": [ - { - "id": "structure--left--center", - "layer": "structure", - "context_origin": [ - 1080, - 0 - ], - "copy_box": [ - 824, - 0, - 1336, - 720 - ], - "context_sha256": "3d305e3a57c6877ba142d9517e166c83ce48b802c7b170702ff2105518f28f57", - "edit_mask_sha256": "95826b60f01e78a45f0c3a46a0b442699f726f7a2e91106ffb3903f84e568259", - "copy_mask_sha256": "51d67caede94e8374e62a1a26a67b86eddcecf469db6bdf2db7a640986c03ebe", - "prompt_sha256": "6708719bf9b17d0f9eebfbdad4a72241c4d83739913706f15a28292332485775", - "request_sha256": "2e7ba325b9fcb357d0ca26a0f6aa76d2bd332e171d95a6ad046fd9f3c588cf38" - }, - { - "id": "structure--center--right", - "layer": "structure", - "context_origin": [ - 3240, - 0 - ], - "copy_box": [ - 824, - 0, - 1336, - 720 - ], - "context_sha256": "0968aabf6cb5cbe2cd0bd40bd156d3fd26888b77e39d4d55053b25eee1855e5b", - "edit_mask_sha256": "95826b60f01e78a45f0c3a46a0b442699f726f7a2e91106ffb3903f84e568259", - "copy_mask_sha256": "51d67caede94e8374e62a1a26a67b86eddcecf469db6bdf2db7a640986c03ebe", - "prompt_sha256": "6708719bf9b17d0f9eebfbdad4a72241c4d83739913706f15a28292332485775", - "request_sha256": "2e7ba325b9fcb357d0ca26a0f6aa76d2bd332e171d95a6ad046fd9f3c588cf38" - } - ] - }, - "configuration_hashes": { - "assembly.json": "4da4c25f2c58d760a82b67c2f56c7116c296426ac6bda3ae5bb31fba036d1bb0", - "route.json": "776f569f43a5c26202caae463677e37e3377e428fee42b192adb02e817a83ac6", - "stage.json": "ad559d4626da752d9e32604a1f084683cff265a5b539c5c4a762bfb0b67e14e9", - "prompts.json": "04a5792149fd1db92c27bbe8c2946015555ebcc526c0a560ceec9240d498cf2d" - }, - "source_graph": { - "architecture": "sources/{chunk}.png -> explicit normalization/matte cleanup -> bounded repairs -> disjoint masks -> role/chunk exports", - "shared_nature": "earlier fixed source -> explicit offset/mirroring -> same role export in both states", - "foliage": "sources/plants.png -> explicit vertical scale/offset and boss alpha window -> shared role7", - "masters": "registered exports in assembly draw order; clean swaps role2 and omits role5" - }, - "acceptance": { - "team_art_approval": false, - "physics_verified": false, - "per_object_rigs": false - } -} diff --git a/art/stages/rusty-creek/packet.json b/art/stages/rusty-creek/packet.json deleted file mode 100644 index dd0c7c8..0000000 --- a/art/stages/rusty-creek/packet.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "version": 1, - "config_sha256": "765700b16a4fc7b73bf85ef93c35a71bc335014c4f12884945d520da77aa2195", - "panel_size": [ - 2160, - 720 - ], - "world_size": [ - 6480, - 720 - ], - "chunks": [ - "left", - "center", - "right" - ], - "chunk_origins": { - "left": [ - 0, - 0 - ], - "center": [ - 2160, - 0 - ], - "right": [ - 4320, - 0 - ] - }, - "model": "gpt-image-2.5-sunburst", - "layers": [ - { - "id": "structure", - "role": "scene-first broad steel and masonry; separate after seam repair", - "world": "structure-before.png", - "sha256": "47108c4573dd1423a469b16734404013bd6b92ff2cd5b873b2960c638fbadf5a", - "inputs": [ - { - "chunk": "left", - "file": "tmp/stages/rusty-creek/left-normalized.png", - "sha256": "3d2bba0475a97c8db7db861f04d27e63b3999faf1eabd2f13bf1d4616a0ac11c", - "native_size": [ - 2160, - 720 - ], - "normalized_size": [ - 2160, - 720 - ] - }, - { - "chunk": "center", - "file": "tmp/stages/rusty-creek/center-normalized.png", - "sha256": "2d9d31a326cfb3aeec774ef723ca967b71c927416271b25717b75060ac15ff3b", - "native_size": [ - 2160, - 720 - ], - "normalized_size": [ - 2160, - 720 - ] - }, - { - "chunk": "right", - "file": "tmp/stages/rusty-creek/right-normalized.png", - "sha256": "c8d9e0e51bfbddf1ce65f934aec9bf04d83d43f0480b26a153900d53e0f9048f", - "native_size": [ - 2160, - 720 - ], - "normalized_size": [ - 2160, - 720 - ] - } - ] - } - ], - "jobs": [ - { - "id": "structure--left--center", - "layer": "structure", - "context_origin": [ - 1080, - 0 - ], - "copy_box": [ - 824, - 0, - 1336, - 720 - ], - "context_sha256": "3d305e3a57c6877ba142d9517e166c83ce48b802c7b170702ff2105518f28f57", - "edit_mask_sha256": "95826b60f01e78a45f0c3a46a0b442699f726f7a2e91106ffb3903f84e568259", - "copy_mask_sha256": "51d67caede94e8374e62a1a26a67b86eddcecf469db6bdf2db7a640986c03ebe", - "prompt_sha256": "6708719bf9b17d0f9eebfbdad4a72241c4d83739913706f15a28292332485775", - "request_sha256": "2e7ba325b9fcb357d0ca26a0f6aa76d2bd332e171d95a6ad046fd9f3c588cf38" - }, - { - "id": "structure--center--right", - "layer": "structure", - "context_origin": [ - 3240, - 0 - ], - "copy_box": [ - 824, - 0, - 1336, - 720 - ], - "context_sha256": "0968aabf6cb5cbe2cd0bd40bd156d3fd26888b77e39d4d55053b25eee1855e5b", - "edit_mask_sha256": "95826b60f01e78a45f0c3a46a0b442699f726f7a2e91106ffb3903f84e568259", - "copy_mask_sha256": "51d67caede94e8374e62a1a26a67b86eddcecf469db6bdf2db7a640986c03ebe", - "prompt_sha256": "6708719bf9b17d0f9eebfbdad4a72241c4d83739913706f15a28292332485775", - "request_sha256": "2e7ba325b9fcb357d0ca26a0f6aa76d2bd332e171d95a6ad046fd9f3c588cf38" - } - ] -} diff --git a/art/stages/rusty-creek/previews/arena-platforms.png b/art/stages/rusty-creek/previews/arena-platforms.png deleted file mode 100644 index e62807c..0000000 Binary files a/art/stages/rusty-creek/previews/arena-platforms.png and /dev/null differ diff --git a/art/stages/rusty-creek/previews/parallax.png b/art/stages/rusty-creek/previews/parallax.png deleted file mode 100644 index abee86e..0000000 Binary files a/art/stages/rusty-creek/previews/parallax.png and /dev/null differ diff --git a/art/stages/rusty-creek/prompts.json b/art/stages/rusty-creek/prompts.json deleted file mode 100644 index 0009d78..0000000 --- a/art/stages/rusty-creek/prompts.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "method": "Built-in image generation; model identifier unavailable. No paid API execution.", - "prompts": { - "center": "Use case: precise-object-edit. Asset type: transparent side-scroller environment plate, wide 3:1 canvas 2160x720. Input 1 is the preferred substantial maze (edit target); input 2 the photographic material reference. Preserve the maze's broad pale blue-green riveted girder platforms, tall stone shafts, connected horizontal bridges, meaningful empty chambers, ladders and side branches. NOT thin pipes beneath a giant bridge. Refine this CENTER maze into a readable journey: broad bottom entry on left at y=530; two tall climbable ladder shafts; open central reconnection court with an elevated optional dead-end balcony; long upper bridge; generous headroom above all walks, connected lower return path; broad right exit at y=530. Side elevation, no vanishing point. Keep substantial concrete buttresses rooted at y=610; water and creek will be composited separately, so do NOT draw any water, reflections, sky, far trees or ground beneath this structure. Keep outermost 160 pixels on BOTH sides a simple level broad girder walkway at top y=530 with footings beneath to y=610, no ladders or tall projections in those edge zones, so modules connect. Every ladder must meet a platform at both ends. Architecture mostly occupies y=120..610, leaving sky headroom. Pixel art, crisp rounded vegetation and readable materials matching reference. Remove ALL plants, vines, moss clumps and railings from the foreground plate; subtle moss stains in stone are fine. No gates, characters, text, labels, checkerboard, glow or FX. Transparent empty spaces and background. Render an art plate, not a diagram.", - "left": "Use case: precise-object-edit. Asset type: transparent side-scroller environment plate, wide 3:1 canvas 2160x720. Input 1 is the preferred substantial maze (edit target); input 2 the photographic material reference. Preserve the maze's broad pale blue-green riveted girder platforms, tall stone shafts, connected horizontal bridges, meaningful empty chambers, ladders and side branches. NOT thin pipes beneath a giant bridge. Refine this CENTER maze into a readable journey: broad bottom entry on left at y=530; two tall climbable ladder shafts; open central reconnection court with an elevated optional dead-end balcony; long upper bridge; generous headroom above all walks, connected lower return path; broad right exit at y=530. Side elevation, no vanishing point. Keep substantial concrete buttresses rooted at y=610; water and creek will be composited separately, so do NOT draw any water, reflections, sky, far trees or ground beneath this structure. Keep outermost 160 pixels on BOTH sides a simple level broad girder walkway at top y=530 with footings beneath to y=610, no ladders or tall projections in those edge zones, so modules connect. Every ladder must meet a platform at both ends. Architecture mostly occupies y=120..610, leaving sky headroom. Pixel art, crisp rounded vegetation and readable materials matching reference. Remove ALL plants, vines, moss clumps and railings from the foreground plate; subtle moss stains in stone are fine. No gates, characters, text, labels, checkerboard, glow or FX. Transparent empty spaces and background. Render an art plate, not a diagram.\nThis is the LEFT continuation, not a copy of the center. Input1 is the center geometry/style authority; input2 earlier left layout inspiration; input3 photo materials. Match both edge walkway TOPS to the center image's actual y=450 in a 2160x720 coordinate system, deck thickness about40px, footings down to620. ENTRY sector: open quiet low forecourt in the first400px, then one major climbing tower, a looping high observation bridge and a short optional dead-end ledge; reconnect low at right.\nDo not copy red or yellow alpha fringes from the input. No solid red border pixels, no plants, no railings. Export genuine transparent background.", - "right": "Use case: precise-object-edit. Asset type: transparent side-scroller environment plate, wide 3:1 canvas 2160x720. Input 1 is the preferred substantial maze (edit target); input 2 the photographic material reference. Preserve the maze's broad pale blue-green riveted girder platforms, tall stone shafts, connected horizontal bridges, meaningful empty chambers, ladders and side branches. NOT thin pipes beneath a giant bridge. Refine this CENTER maze into a readable journey: broad bottom entry on left at y=530; two tall climbable ladder shafts; open central reconnection court with an elevated optional dead-end balcony; long upper bridge; generous headroom above all walks, connected lower return path; broad right exit at y=530. Side elevation, no vanishing point. Keep substantial concrete buttresses rooted at y=610; water and creek will be composited separately, so do NOT draw any water, reflections, sky, far trees or ground beneath this structure. Keep outermost 160 pixels on BOTH sides a simple level broad girder walkway at top y=530 with footings beneath to y=610, no ladders or tall projections in those edge zones, so modules connect. Every ladder must meet a platform at both ends. Architecture mostly occupies y=120..610, leaving sky headroom. Pixel art, crisp rounded vegetation and readable materials matching reference. Remove ALL plants, vines, moss clumps and railings from the foreground plate; subtle moss stains in stone are fine. No gates, characters, text, labels, checkerboard, glow or FX. Transparent empty spaces and background. Render an art plate, not a diagram.\nThis is the RIGHT continuation, not a copy of the center. Input1 is the center geometry/style authority; input2 earlier right layout inspiration; input3 photo materials. Match both edge walkway TOPS to the center image's actual y=450 in a 2160x720 coordinate system, deck thickness about40px, footings down to620. EXIT sector: first700px continues ladders and branching exploration, then an OPEN BOSS CLEARING with a wide flat low floor from x=1000 to1750, no columns in this arena, and a final small ascent/exit at right. Keep the center of the boss clearing spacious.\nDo not copy red or yellow alpha fringes from the input. No solid red border pixels, no plants, no railings. Export genuine transparent background.", - "plants": "Use case: background-extraction. Asset type: transparent wide 3:1 pixel-art foliage plate 2160x720. References are the rusted creek maze and photographic material collage. Draw ONLY separate green/golden ivy and leafy clumps that can be placed over stone buttresses and creek bank. Keep the top 420 pixels empty. Place low mounds and hanging clumps in the bottom y=460..620 with large transparent gaps between them. NO structures, stone, metal, columns, ladders, dark rectangles, ground, water, red outlines, solid shadows or backdrop. Opaque colorful leaf interiors with genuinely clean transparent perimeter. This is a foreground layer, so each clump must have a crisp independent silhouette. Not a sheet of unrelated props: compose a single continuous loose overgrown riverbank edge. Match the lush warm pixel painting, no text.", - "repair-left-center": "Repair one actual join of the scene-first broad steel and masonry; separate after seam repair layer in a flat side-scrolling pixel-art stage. Image 1 is the exact staggered context canvas, not a style reference. The seam lies at x=1080. Change only the band x=[824,1336); image 2 shows the edit mask (transparent means editable). Continue existing silhouettes, steel edges, foliage, waterlines or reflections as appropriate; connect matching platform ends without deleting branches or inventing a new camera. Keep every pixel outside the band, original scale, palette and flat projection. Transparent holes stay transparent; no matte, labels, HUD, glow or new scenery layer. Output the complete 2160x720 context canvas, not a tight crop. Connect the broad low deck at y=460 across this join, preserving footings down to y=630 and matching edge heights at both sides of the editable band. No thin bars, foliage, red matte fringes, water, sky or new towers. Keep opening/headroom and transparent background.\r\n\nEdit target image1 is the exact join context; supporting image2 is edit mask. Keep canvas 2160x720. Repair only x824..1336: a continuous broad riveted low bridge top, including its rooted stone plinth, connects the two panels. Preserve all other image geometry; transparency in empty areas. Match the TOP SURFACE at both protected edges of that band; a gentle step if needed, not a floating disconnected deck. Remove red/yellow matte-colored fringe in the editable band. No sky, trees, water, new structures or plants.", - "repair-center-right": "Repair one actual join of the scene-first broad steel and masonry; separate after seam repair layer in a flat side-scrolling pixel-art stage. Image 1 is the exact staggered context canvas, not a style reference. The seam lies at x=1080. Change only the band x=[824,1336); image 2 shows the edit mask (transparent means editable). Continue existing silhouettes, steel edges, foliage, waterlines or reflections as appropriate; connect matching platform ends without deleting branches or inventing a new camera. Keep every pixel outside the band, original scale, palette and flat projection. Transparent holes stay transparent; no matte, labels, HUD, glow or new scenery layer. Output the complete 2160x720 context canvas, not a tight crop. Connect the broad low deck at y=460 across this join, preserving footings down to y=630 and matching edge heights at both sides of the editable band. No thin bars, foliage, red matte fringes, water, sky or new towers. Keep opening/headroom and transparent background.\r\n\nEdit target image1 is the exact join context; supporting image2 is edit mask. Keep canvas 2160x720. Repair only x824..1336: a continuous broad riveted low bridge top, including its rooted stone plinth, connects the two panels. Preserve all other image geometry; transparency in empty areas. Match the TOP SURFACE at both protected edges of that band; a gentle step if needed, not a floating disconnected deck. Remove red/yellow matte-colored fringe in the editable band. No sky, trees, water, new structures or plants." - } -} diff --git a/art/stages/rusty-creek/images/after-center.png b/art/stages/rusty-creek/prototype/after-center.png similarity index 100% rename from art/stages/rusty-creek/images/after-center.png rename to art/stages/rusty-creek/prototype/after-center.png diff --git a/art/stages/rusty-creek/images/after-left.png b/art/stages/rusty-creek/prototype/after-left.png similarity index 100% rename from art/stages/rusty-creek/images/after-left.png rename to art/stages/rusty-creek/prototype/after-left.png diff --git a/art/stages/rusty-creek/images/after-right.png b/art/stages/rusty-creek/prototype/after-right.png similarity index 100% rename from art/stages/rusty-creek/images/after-right.png rename to art/stages/rusty-creek/prototype/after-right.png diff --git a/art/stages/rusty-creek/images/before-center.png b/art/stages/rusty-creek/prototype/before-center.png similarity index 100% rename from art/stages/rusty-creek/images/before-center.png rename to art/stages/rusty-creek/prototype/before-center.png diff --git a/art/stages/rusty-creek/arena/girder-reference.png b/art/stages/rusty-creek/prototype/girder-reference.png similarity index 100% rename from art/stages/rusty-creek/arena/girder-reference.png rename to art/stages/rusty-creek/prototype/girder-reference.png diff --git a/art/stages/rusty-creek/inputs/maze-center.png b/art/stages/rusty-creek/prototype/maze-center.png similarity index 100% rename from art/stages/rusty-creek/inputs/maze-center.png rename to art/stages/rusty-creek/prototype/maze-center.png diff --git a/art/stages/rusty-creek/rc-0-0.anomaly.collision.json b/art/stages/rusty-creek/rc-0-0.anomaly.collision.json index ab6539a..17e4764 100644 --- a/art/stages/rusty-creek/rc-0-0.anomaly.collision.json +++ b/art/stages/rusty-creek/rc-0-0.anomaly.collision.json @@ -8,321 +8,201 @@ "walk": [ [ [ - 0, - 461 + 80, + 327 ], [ - 430, - 461 - ], - [ - 490, - 508 + 304, + 327 ] ], [ [ - 490, - 508 + 132, + 524 ], [ - 898, - 508 + 780, + 524 ] ], [ [ - 898, - 557 + 360, + 208 ], [ - 1098, - 557 + 544, + 208 ] ], [ [ - 1136, - 505 + 880, + 473 ], [ - 1378, - 505 + 1136, + 473 ] ], [ [ - 1378, - 557 + 1136, + 448 ], [ - 1490, - 557 + 1408, + 448 ] ], [ [ - 1490, - 515 - ], - [ - 1720, - 515 - ], - [ - 1786, - 461 + 1440, + 287 ], [ 2160, - 461 + 287 ] ] ], "slide": [], - "oneWay": [ - [ - [ - 415, - 363 - ], - [ - 595, - 363 - ] - ], - [ - [ - 575, - 126 - ], - [ - 762, - 126 - ] - ], - [ - [ - 630, - 302 - ], - [ - 778, - 302 - ] - ], - [ - [ - 720, - 165 - ], - [ - 1345, - 165 - ] - ], - [ - [ - 780, - 387 - ], - [ - 1135, - 387 - ] - ], - [ - [ - 1015, - 275 - ], - [ - 1135, - 275 - ] - ], - [ - [ - 1300, - 83 - ], - [ - 1519, - 83 - ] - ], - [ - [ - 1300, - 368 - ], - [ - 1525, - 368 - ] - ], - [ - [ - 1525, - 189 - ], - [ - 1663, - 189 - ] - ], - [ - [ - 1665, - 299 - ], - [ - 1777, - 299 - ] - ] - ], + "oneWay": [], "climb": [ { - "id": "ladder-entry", - "kind": "ladder", - "x": 468, - "y": 360, - "w": 28, - "h": 150 - }, - { - "id": "ladder-tall", - "kind": "ladder", - "x": 596, - "y": 120, - "w": 32, - "h": 390 - }, - { - "id": "ladder-spur", - "kind": "ladder", - "x": 895, - "y": 384, - "w": 28, - "h": 175 - }, - { - "id": "ladder-lookout", - "kind": "ladder", - "x": 1030, - "y": 272, - "w": 30, - "h": 118 - }, - { - "id": "ladder-return", + "x": 495, + "y": 208, + "w": 33, + "h": 316, "kind": "ladder", - "x": 1336, - "y": 80, - "w": 34, - "h": 427 + "id": "rcz-0-0-ladder-0" }, { - "id": "ladder-east", + "x": 1619, + "y": 287, + "w": 33, + "h": 433, "kind": "ladder", - "x": 1703, - "y": 296, - "w": 32, - "h": 221 - } - ], - "solid": [ - { - "x": 0, - "y": 0, - "w": 8, - "h": 720 - }, - { - "x": 1099, - "y": 390, - "w": 36, - "h": 167 - } - ], - "noGo": [ - { - "x": 0, - "y": 600, - "kind": "water", - "w": 2160, - "h": 120 + "id": "rcz-0-0-ladder-1" } ], + "solid": [], + "noGo": [], "hazard": [], "interact": [ - { - "id": "chair", - "kind": "pickup", - "item": "chair", - "x": 316, - "y": 425, - "w": 40, - "h": 36 - }, { "id": "muffin-1", "kind": "pickup", "item": "muffin", - "x": 1060, - "y": 247, + "x": 1500, + "y": 259, "w": 24, "h": 28 - }, - { - "id": "note-1", - "kind": "pickup", - "item": "note-1", - "x": 1100, - "y": 251, - "w": 24, - "h": 24 } ], "spawn": [ { - "id": "player", - "kind": "player", - "x": 120, - "y": 461 - }, - { - "id": "rover-1", - "kind": "rover", - "x": 760, - "y": 508, - "patrol": [ - 640, - 880 - ] - }, - { - "id": "rover-4", + "id": "rover-5", "kind": "rover", - "x": 1250, - "y": 505, + "x": 1800, + "y": 287, "patrol": [ - 1150, - 1370 + 1560, + 2040 ] }, { - "id": "rover-5", + "id": "rover-6", "kind": "rover", - "x": 1950, - "y": 461, + "x": 450, + "y": 524, "patrol": [ - 1820, - 2120 + 220, + 700 ] } ], "ledge": [], - "glideLift": [] + "glideLift": [], + "terrain": [ + { + "x": [ + 80, + 304 + ], + "y": [ + 315, + 339 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 132, + 780 + ], + "y": [ + 512, + 536 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 360, + 544 + ], + "y": [ + 196, + 220 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 880, + 1136 + ], + "y": [ + 461, + 485 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 1136, + 1408 + ], + "y": [ + 436, + 460 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 1440, + 2160 + ], + "y": [ + 275, + 299 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + } + ] } diff --git a/art/stages/rusty-creek/rc-0-0.clean.collision.json b/art/stages/rusty-creek/rc-0-0.clean.collision.json index 727f072..757ac5e 100644 --- a/art/stages/rusty-creek/rc-0-0.clean.collision.json +++ b/art/stages/rusty-creek/rc-0-0.clean.collision.json @@ -8,46 +8,170 @@ "walk": [ [ [ - 0, - 566 + 80, + 327 + ], + [ + 304, + 327 + ] + ], + [ + [ + 132, + 524 + ], + [ + 780, + 524 + ] + ], + [ + [ + 360, + 208 + ], + [ + 544, + 208 + ] + ], + [ + [ + 880, + 473 + ], + [ + 1136, + 473 + ] + ], + [ + [ + 1136, + 448 + ], + [ + 1408, + 448 + ] + ], + [ + [ + 1440, + 287 ], [ 2160, - 566 + 287 ] ] ], "slide": [], "oneWay": [], - "climb": [], - "solid": [ + "climb": [ { - "x": 0, - "y": 0, - "w": 8, - "h": 720 - } - ], - "noGo": [ + "x": 495, + "y": 208, + "w": 33, + "h": 316, + "kind": "ladder", + "id": "rcz-0-0-ladder-0" + }, { - "x": 0, - "y": 600, - "kind": "water", - "w": 2160, - "h": 120 + "x": 1619, + "y": 287, + "w": 33, + "h": 433, + "kind": "ladder", + "id": "rcz-0-0-ladder-1" } ], + "solid": [], + "noGo": [], "hazard": [], "interact": [], - "spawn": [ + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 80, + 304 + ], + "y": [ + 315, + 339 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 132, + 780 + ], + "y": [ + 512, + 536 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, { - "id": "player", - "kind": "player", - "x": 600, - "y": 566, - "note": "The 404 lands the hero on the creek path under the rail bridge (P5)" + "x": [ + 360, + 544 + ], + "y": [ + 196, + 220 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 880, + 1136 + ], + "y": [ + 461, + 485 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 1136, + 1408 + ], + "y": [ + 436, + 460 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 1440, + 2160 + ], + "y": [ + 275, + 299 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" } - ], - "ledge": [], - "glideLift": [] + ] } diff --git a/art/stages/rusty-creek/rc-0-1.anomaly.collision.json b/art/stages/rusty-creek/rc-0-1.anomaly.collision.json new file mode 100644 index 0000000..059e750 --- /dev/null +++ b/art/stages/rusty-creek/rc-0-1.anomaly.collision.json @@ -0,0 +1,139 @@ +{ + "chunk": "rc-0-1", + "state": "anomaly", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 522 + ], + [ + 2160, + 522 + ] + ], + [ + [ + 0, + 62 + ], + [ + 2160, + 62 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [ + { + "x": 330, + "y": 54, + "w": 42, + "h": 468, + "kind": "ladder", + "id": "rcz-0-1-pier-ladder" + }, + { + "x": 1619, + "y": 0, + "w": 33, + "h": 62, + "kind": "ladder", + "id": "rcz-0-0-ladder-1-on" + } + ], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 600, + "w": 2160, + "h": 120, + "kind": "water" + } + ], + "hazard": [], + "interact": [ + { + "id": "chair", + "kind": "pickup", + "item": "chair", + "x": 520, + "y": 486, + "w": 40, + "h": 36 + }, + { + "id": "note-1", + "kind": "pickup", + "item": "note-1", + "x": 1200, + "y": 38, + "w": 24, + "h": 24 + } + ], + "spawn": [ + { + "id": "player", + "kind": "player", + "x": 200, + "y": 522 + }, + { + "id": "rover-1", + "kind": "rover", + "x": 900, + "y": 522, + "patrol": [ + 780, + 1020 + ] + }, + { + "id": "rover-4", + "kind": "rover", + "x": 1500, + "y": 522, + "patrol": [ + 1380, + 1620 + ] + } + ], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 2160 + ], + "y": [ + 510, + 534 + ], + "kind": "ground", + "material": "stone", + "note": "the creek path" + }, + { + "x": [ + 0, + 2160 + ], + "y": [ + 50, + 74 + ], + "kind": "plank", + "material": "steel", + "note": "the railway girder's deck" + } + ] +} diff --git a/art/stages/rusty-creek/rc-0-1.clean.collision.json b/art/stages/rusty-creek/rc-0-1.clean.collision.json new file mode 100644 index 0000000..509ae87 --- /dev/null +++ b/art/stages/rusty-creek/rc-0-1.clean.collision.json @@ -0,0 +1,101 @@ +{ + "chunk": "rc-0-1", + "state": "clean", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 522 + ], + [ + 2160, + 522 + ] + ], + [ + [ + 0, + 62 + ], + [ + 2160, + 62 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [ + { + "x": 330, + "y": 54, + "w": 42, + "h": 468, + "kind": "ladder", + "id": "rcz-0-1-pier-ladder" + }, + { + "x": 1619, + "y": 0, + "w": 33, + "h": 62, + "kind": "ladder", + "id": "rcz-0-0-ladder-1-on" + } + ], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 600, + "w": 2160, + "h": 120, + "kind": "water" + } + ], + "hazard": [], + "interact": [], + "spawn": [ + { + "id": "player", + "kind": "player", + "x": 300, + "y": 522, + "note": "The 404 lands the hero on the creek path under the rail bridge (P5)" + } + ], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 2160 + ], + "y": [ + 510, + 534 + ], + "kind": "ground", + "material": "stone", + "note": "the creek path" + }, + { + "x": [ + 0, + 2160 + ], + "y": [ + 50, + 74 + ], + "kind": "plank", + "material": "steel", + "note": "the railway girder's deck" + } + ] +} diff --git a/art/stages/rusty-creek/rc-0-2.anomaly.collision.json b/art/stages/rusty-creek/rc-0-2.anomaly.collision.json new file mode 100644 index 0000000..1cfd8d7 --- /dev/null +++ b/art/stages/rusty-creek/rc-0-2.anomaly.collision.json @@ -0,0 +1,272 @@ +{ + "chunk": "rc-0-2", + "state": "anomaly", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 196 + ], + [ + 16, + 197 + ], + [ + 40, + 198 + ], + [ + 48, + 198 + ], + [ + 56, + 198 + ] + ], + [ + [ + 0, + 164 + ], + [ + 32, + 163 + ], + [ + 48, + 163 + ], + [ + 88, + 162 + ], + [ + 96, + 162 + ], + [ + 144, + 162 + ], + [ + 192, + 162 + ], + [ + 240, + 162 + ], + [ + 288, + 162 + ], + [ + 336, + 162 + ], + [ + 384, + 162 + ], + [ + 432, + 162 + ], + [ + 480, + 162 + ], + [ + 528, + 162 + ], + [ + 576, + 162 + ], + [ + 624, + 162 + ], + [ + 672, + 162 + ], + [ + 720, + 162 + ], + [ + 768, + 162 + ], + [ + 816, + 162 + ], + [ + 864, + 162 + ], + [ + 912, + 162 + ], + [ + 960, + 162 + ], + [ + 1008, + 162 + ], + [ + 1056, + 162 + ], + [ + 1104, + 162 + ], + [ + 1152, + 162 + ], + [ + 1200, + 162 + ], + [ + 1248, + 162 + ], + [ + 1296, + 162 + ], + [ + 1344, + 162 + ], + [ + 1392, + 162 + ], + [ + 1440, + 162 + ], + [ + 1488, + 162 + ], + [ + 1536, + 162 + ], + [ + 1584, + 162 + ], + [ + 1632, + 162 + ], + [ + 1680, + 162 + ], + [ + 1728, + 162 + ], + [ + 1776, + 162 + ], + [ + 1824, + 162 + ], + [ + 1872, + 162 + ], + [ + 1920, + 162 + ], + [ + 1968, + 162 + ], + [ + 2016, + 162 + ], + [ + 2064, + 162 + ], + [ + 2112, + 162 + ], + [ + 2160, + 162 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 331, + "w": 2160, + "h": 389, + "kind": "water" + } + ], + "hazard": [], + "interact": [], + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 56 + ], + "y": [ + 184, + 210 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 0, + 2160 + ], + "y": [ + 150, + 176 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + } + ] +} diff --git a/art/stages/rusty-creek/rc-0-2.clean.collision.json b/art/stages/rusty-creek/rc-0-2.clean.collision.json new file mode 100644 index 0000000..01a9895 --- /dev/null +++ b/art/stages/rusty-creek/rc-0-2.clean.collision.json @@ -0,0 +1,272 @@ +{ + "chunk": "rc-0-2", + "state": "clean", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 196 + ], + [ + 16, + 197 + ], + [ + 40, + 198 + ], + [ + 48, + 198 + ], + [ + 56, + 198 + ] + ], + [ + [ + 0, + 164 + ], + [ + 32, + 163 + ], + [ + 48, + 163 + ], + [ + 88, + 162 + ], + [ + 96, + 162 + ], + [ + 144, + 162 + ], + [ + 192, + 162 + ], + [ + 240, + 162 + ], + [ + 288, + 162 + ], + [ + 336, + 162 + ], + [ + 384, + 162 + ], + [ + 432, + 162 + ], + [ + 480, + 162 + ], + [ + 528, + 162 + ], + [ + 576, + 162 + ], + [ + 624, + 162 + ], + [ + 672, + 162 + ], + [ + 720, + 162 + ], + [ + 768, + 162 + ], + [ + 816, + 162 + ], + [ + 864, + 162 + ], + [ + 912, + 162 + ], + [ + 960, + 162 + ], + [ + 1008, + 162 + ], + [ + 1056, + 162 + ], + [ + 1104, + 162 + ], + [ + 1152, + 162 + ], + [ + 1200, + 162 + ], + [ + 1248, + 162 + ], + [ + 1296, + 162 + ], + [ + 1344, + 162 + ], + [ + 1392, + 162 + ], + [ + 1440, + 162 + ], + [ + 1488, + 162 + ], + [ + 1536, + 162 + ], + [ + 1584, + 162 + ], + [ + 1632, + 162 + ], + [ + 1680, + 162 + ], + [ + 1728, + 162 + ], + [ + 1776, + 162 + ], + [ + 1824, + 162 + ], + [ + 1872, + 162 + ], + [ + 1920, + 162 + ], + [ + 1968, + 162 + ], + [ + 2016, + 162 + ], + [ + 2064, + 162 + ], + [ + 2112, + 162 + ], + [ + 2160, + 162 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 331, + "w": 2160, + "h": 389, + "kind": "water" + } + ], + "hazard": [], + "interact": [], + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 56 + ], + "y": [ + 184, + 210 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 0, + 2160 + ], + "y": [ + 150, + 176 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + } + ] +} diff --git a/art/stages/rusty-creek/rc-1-0.anomaly.collision.json b/art/stages/rusty-creek/rc-1-0.anomaly.collision.json index 21b03fc..fd78d6c 100644 --- a/art/stages/rusty-creek/rc-1-0.anomaly.collision.json +++ b/art/stages/rusty-creek/rc-1-0.anomaly.collision.json @@ -9,351 +9,195 @@ [ [ 0, - 456 + 657 ], [ - 335, - 456 + 680, + 657 ] ], [ [ - 335, - 489 + 164, + 331 ], [ - 710, - 489 + 1860, + 331 ] ], [ [ - 710, - 569 - ], - [ - 1032, - 569 - ] - ], - [ - [ - 1032, + 868, 536 ], [ - 1240, + 1612, 536 ] ], [ [ - 1240, - 570 + 1628, + 658 ], [ - 1550, - 570 + 1736, + 658 ] ], [ [ - 1580, - 563 - ], - [ - 1700, - 563 - ], - [ - 1745, - 537 - ], - [ - 1840, - 537 - ], - [ - 1885, - 500 - ], - [ - 1920, - 500 - ] - ], - [ - [ - 1920, - 455 + 2084, + 658 ], [ 2160, - 455 - ] - ] - ], - "slide": [], - "oneWay": [ - [ - [ - 340, - 341 - ], - [ - 715, - 341 - ] - ], - [ - [ - 570, - 208 - ], - [ - 925, - 208 - ] - ], - [ - [ - 700, - 400 - ], - [ - 905, - 400 + 658 ] ], [ [ - 925, - 135 + 1736, + 605 ], [ - 1345, - 135 + 2084, + 605 ] ], [ [ - 925, - 343 + 1912, + 378 ], [ - 1262, - 343 - ] - ], - [ - [ - 1115, - 241 - ], - [ - 1220, - 241 - ] - ], - [ - [ - 1210, - 400 - ], - [ - 1550, - 400 - ] - ], - [ - [ - 1340, - 65 - ], - [ - 1520, - 65 - ] - ], - [ - [ - 1340, - 273 - ], - [ - 1680, - 273 - ] - ], - [ - [ - 1460, - 135 - ], - [ - 1840, - 135 - ] - ], - [ - [ - 1551, - 460 - ], - [ - 1640, - 460 - ] - ], - [ - [ - 1715, - 343 - ], - [ - 1870, - 343 + 2160, + 378 ] ] ], + "slide": [], + "oneWay": [], "climb": [ { - "id": "ladder-west", + "x": 1878, + "y": 605, + "w": 19, + "h": 115, "kind": "ladder", - "x": 603, - "y": 200, - "w": 30, - "h": 292 - }, - { - "id": "ladder-loop", - "kind": "ladder", - "x": 963, - "y": 130, - "w": 30, - "h": 440 - }, - { - "id": "ladder-cache", - "kind": "ladder", - "x": 1140, - "y": 238, - "w": 26, - "h": 108 - }, - { - "id": "ladder-tower", - "kind": "ladder", - "x": 1397, - "y": 60, - "w": 26, - "h": 342 - }, - { - "id": "ladder-reconnect", - "kind": "ladder", - "x": 1735, - "y": 130, - "w": 28, - "h": 410 - }, - { - "id": "ladder-east", - "kind": "ladder", - "x": 1835, - "y": 130, - "w": 22, - "h": 215 + "id": "rcz-1-0-ladder-0" } ], "solid": [], - "noGo": [ + "noGo": [], + "hazard": [], + "interact": [], + "spawn": [ { - "x": 0, - "y": 600, - "kind": "water", - "w": 2160, - "h": 120 + "id": "crab-1", + "kind": "crab", + "x": 1200, + "y": 536, + "patrol": [ + 950, + 1530 + ] } ], - "hazard": [], - "interact": [ + "ledge": [], + "glideLift": [], + "terrain": [ { - "id": "coffee-1", - "kind": "coffee-machine", - "x": 1770, - "y": 457, - "w": 40, - "h": 80 + "x": [ + 0, + 680 + ], + "y": [ + 645, + 669 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "leberkaese-1", - "kind": "pickup", - "item": "leberkaese", - "x": 1180, - "y": 213, - "w": 24, - "h": 28 - } - ], - "spawn": [ - { - "id": "rover-2", - "kind": "rover", - "x": 880, - "y": 569, - "patrol": [ - 740, - 1020 - ] + "x": [ + 164, + 1860 + ], + "y": [ + 319, + 343 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "rover-3", - "kind": "rover", - "x": 1400, - "y": 570, - "patrol": [ - 1260, - 1540 - ] + "x": [ + 868, + 1612 + ], + "y": [ + 524, + 548 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "drone-1", - "kind": "drone", - "x": 1150, - "y": 470, - "patrol": [ - 900, - 1500 - ] + "x": [ + 1628, + 1736 + ], + "y": [ + 646, + 670 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "crab-1", - "kind": "crab", - "x": 1200, - "y": 135, - "patrol": [ - 1050, - 1330 - ] + "x": [ + 2084, + 2160 + ], + "y": [ + 646, + 670 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "dexter-1", - "kind": "dexter", - "x": 1820, - "y": 537 + "x": [ + 1736, + 2084 + ], + "y": [ + 593, + 617 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "rover-6", - "kind": "rover", - "x": 520, - "y": 489, - "patrol": [ - 380, - 690 - ] + "x": [ + 1912, + 2160 + ], + "y": [ + 366, + 390 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" } - ], - "ledge": [], - "glideLift": [] + ] } diff --git a/art/stages/rusty-creek/rc-1-0.clean.collision.json b/art/stages/rusty-creek/rc-1-0.clean.collision.json index c88b9f0..c3721a1 100644 --- a/art/stages/rusty-creek/rc-1-0.clean.collision.json +++ b/art/stages/rusty-creek/rc-1-0.clean.collision.json @@ -9,40 +9,184 @@ [ [ 0, - 566 + 657 + ], + [ + 680, + 657 + ] + ], + [ + [ + 164, + 331 + ], + [ + 1860, + 331 + ] + ], + [ + [ + 868, + 536 + ], + [ + 1612, + 536 + ] + ], + [ + [ + 1628, + 658 + ], + [ + 1736, + 658 + ] + ], + [ + [ + 2084, + 658 + ], + [ + 2160, + 658 + ] + ], + [ + [ + 1736, + 605 + ], + [ + 2084, + 605 + ] + ], + [ + [ + 1912, + 378 ], [ 2160, - 566 + 378 ] ] ], "slide": [], "oneWay": [], - "climb": [], - "solid": [], - "noGo": [ + "climb": [ { - "x": 0, - "y": 600, - "kind": "water", - "w": 2160, - "h": 120 + "x": 1878, + "y": 605, + "w": 19, + "h": 115, + "kind": "ladder", + "id": "rcz-1-0-ladder-0" } ], + "solid": [], + "noGo": [], "hazard": [], - "interact": [ - { - "id": "jenny-ram", - "kind": "jenny-ram", - "x": 1080, - "y": 474, - "w": 40, - "h": 92, - "note": "Jenny comes down the creek path and rams the hero; the region turns (M4-S1 #54, P5)" - } - ], + "interact": [], "spawn": [], "ledge": [], - "glideLift": [] + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 680 + ], + "y": [ + 645, + 669 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 164, + 1860 + ], + "y": [ + 319, + 343 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 868, + 1612 + ], + "y": [ + 524, + 548 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 1628, + 1736 + ], + "y": [ + 646, + 670 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 2084, + 2160 + ], + "y": [ + 646, + 670 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 1736, + 2084 + ], + "y": [ + 593, + 617 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 1912, + 2160 + ], + "y": [ + 366, + 390 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + } + ] } diff --git a/art/stages/rusty-creek/rc-1-1.anomaly.collision.json b/art/stages/rusty-creek/rc-1-1.anomaly.collision.json new file mode 100644 index 0000000..9ae3bd3 --- /dev/null +++ b/art/stages/rusty-creek/rc-1-1.anomaly.collision.json @@ -0,0 +1,148 @@ +{ + "chunk": "rc-1-1", + "state": "anomaly", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 522 + ], + [ + 2160, + 522 + ] + ], + [ + [ + 0, + 63 + ], + [ + 2160, + 63 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [ + { + "x": 1062, + "y": 55, + "w": 44, + "h": 467, + "kind": "ladder", + "id": "rcz-1-1-pier-ladder" + }, + { + "x": 1878, + "y": 0, + "w": 19, + "h": 63, + "kind": "ladder", + "id": "rcz-1-0-ladder-0-on" + } + ], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 600, + "w": 2160, + "h": 120, + "kind": "water" + } + ], + "hazard": [], + "interact": [ + { + "id": "coffee-1", + "kind": "coffee-machine", + "x": 1770, + "y": 442, + "w": 40, + "h": 80 + }, + { + "id": "leberkaese-1", + "kind": "pickup", + "item": "leberkaese", + "x": 1400, + "y": 35, + "w": 24, + "h": 28 + } + ], + "spawn": [ + { + "id": "rover-2", + "kind": "rover", + "x": 500, + "y": 522, + "patrol": [ + 360, + 640 + ] + }, + { + "id": "rover-3", + "kind": "rover", + "x": 1350, + "y": 522, + "patrol": [ + 1220, + 1480 + ] + }, + { + "id": "drone-1", + "kind": "drone", + "x": 1150, + "y": 427, + "patrol": [ + 900, + 1500 + ] + }, + { + "id": "dexter-1", + "kind": "dexter", + "x": 1820, + "y": 522 + } + ], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 2160 + ], + "y": [ + 510, + 534 + ], + "kind": "ground", + "material": "stone", + "note": "the creek path" + }, + { + "x": [ + 0, + 2160 + ], + "y": [ + 51, + 75 + ], + "kind": "plank", + "material": "steel", + "note": "the railway girder's deck" + } + ] +} diff --git a/art/stages/rusty-creek/rc-1-1.clean.collision.json b/art/stages/rusty-creek/rc-1-1.clean.collision.json new file mode 100644 index 0000000..8e0d1ed --- /dev/null +++ b/art/stages/rusty-creek/rc-1-1.clean.collision.json @@ -0,0 +1,103 @@ +{ + "chunk": "rc-1-1", + "state": "clean", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 522 + ], + [ + 2160, + 522 + ] + ], + [ + [ + 0, + 63 + ], + [ + 2160, + 63 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [ + { + "x": 1062, + "y": 55, + "w": 44, + "h": 467, + "kind": "ladder", + "id": "rcz-1-1-pier-ladder" + }, + { + "x": 1878, + "y": 0, + "w": 19, + "h": 63, + "kind": "ladder", + "id": "rcz-1-0-ladder-0-on" + } + ], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 600, + "w": 2160, + "h": 120, + "kind": "water" + } + ], + "hazard": [], + "interact": [ + { + "id": "jenny-ram", + "kind": "jenny-ram", + "x": 1080, + "y": 430, + "w": 40, + "h": 92, + "note": "Jenny comes down the creek path and rams the hero; the region turns (M4-S1 #54, P5)" + } + ], + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 2160 + ], + "y": [ + 510, + 534 + ], + "kind": "ground", + "material": "stone", + "note": "the creek path" + }, + { + "x": [ + 0, + 2160 + ], + "y": [ + 51, + 75 + ], + "kind": "plank", + "material": "steel", + "note": "the railway girder's deck" + } + ] +} diff --git a/art/stages/rusty-creek/rc-1-2.anomaly.collision.json b/art/stages/rusty-creek/rc-1-2.anomaly.collision.json new file mode 100644 index 0000000..c11a82c --- /dev/null +++ b/art/stages/rusty-creek/rc-1-2.anomaly.collision.json @@ -0,0 +1,61 @@ +{ + "chunk": "rc-1-2", + "state": "anomaly", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 197 + ], + [ + 1960, + 197 + ], + [ + 2050, + 270 + ], + [ + 2160, + 278 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 584, + "w": 2160, + "h": 136, + "kind": "water" + } + ], + "hazard": [], + "interact": [], + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 2160 + ], + "y": [ + 185, + 290 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + } + ] +} diff --git a/art/stages/rusty-creek/rc-1-2.clean.collision.json b/art/stages/rusty-creek/rc-1-2.clean.collision.json new file mode 100644 index 0000000..61a98b8 --- /dev/null +++ b/art/stages/rusty-creek/rc-1-2.clean.collision.json @@ -0,0 +1,61 @@ +{ + "chunk": "rc-1-2", + "state": "clean", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 197 + ], + [ + 1960, + 197 + ], + [ + 2050, + 270 + ], + [ + 2160, + 278 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 584, + "w": 2160, + "h": 136, + "kind": "water" + } + ], + "hazard": [], + "interact": [], + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 2160 + ], + "y": [ + 185, + 290 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + } + ] +} diff --git a/art/stages/rusty-creek/rc-2-0.anomaly.collision.json b/art/stages/rusty-creek/rc-2-0.anomaly.collision.json index 4f2cbf6..cfd608d 100644 --- a/art/stages/rusty-creek/rc-2-0.anomaly.collision.json +++ b/art/stages/rusty-creek/rc-2-0.anomaly.collision.json @@ -9,352 +9,146 @@ [ [ 0, - 455 + 378 ], [ - 200, - 455 + 168, + 378 ] ], [ [ - 245, - 528 + 120, + 522 ], [ - 455, - 528 + 272, + 522 ] ], [ [ - 540, - 536 + 168, + 303 ], [ - 850, - 536 + 632, + 303 ] ], [ [ - 850, - 571 - ], - [ - 935, - 571 - ] - ], - [ - [ - 935, - 555 + 696, + 376 ], [ 1080, - 555 - ], - [ - 1100, - 565 + 376 ] ], [ [ - 1100, - 565 - ], - [ - 1676, - 565 - ], - [ - 1704, - 548 - ] - ], - [ - [ - 1704, - 548 - ], - [ - 1760, - 548 - ], - [ - 1850, - 520 - ], - [ - 1900, - 500 - ], - [ - 2020, - 477 + 1420, + 450 ], [ 2160, - 477 + 450 ] ] ], "slide": [], - "oneWay": [ - [ - [ - 200, - 385 - ], - [ - 455, - 385 - ] - ], - [ - [ - 338, - 236 - ], - [ - 510, - 236 - ] - ], - [ - [ - 462, - 441 - ], - [ - 512, - 441 - ] - ], - [ - [ - 510, - 163 - ], - [ - 740, - 163 - ] - ], - [ - [ - 540, - 385 - ], - [ - 850, - 385 - ] - ], - [ - [ - 700, - 191 - ], - [ - 1060, - 191 - ] - ], - [ - [ - 763, - 298 - ], - [ - 844, - 298 - ] - ], - [ - [ - 1000, - 108 - ], - [ - 1181, - 108 - ] - ], - [ - [ - 1040, - 158 - ], - [ - 1717, - 158 - ] - ], - [ - [ - 1074, - 312 - ], - [ - 1169, - 312 - ] - ], - [ - [ - 1700, - 323 - ], - [ - 1893, - 323 - ] - ], - [ - [ - 1745, - 129 - ], - [ - 1852, - 129 - ] - ], - [ - [ - 1180, - 476 - ], - [ - 1379, - 476 - ] - ], - [ - [ - 1430, - 476 - ], - [ - 1629, - 476 - ] - ] - ], + "oneWay": [], "climb": [ { - "id": "ladder-foot", - "kind": "ladder", - "x": 355, - "y": 233, - "w": 28, - "h": 300 - }, - { - "id": "ladder-upper", - "kind": "ladder", - "x": 560, - "y": 160, - "w": 26, - "h": 230 - }, - { - "id": "ladder-return", - "kind": "ladder", - "x": 1040, - "y": 105, - "w": 28, - "h": 455 - }, - { - "id": "ladder-overlook", + "x": 708, + "y": 376, + "w": 34, + "h": 344, "kind": "ladder", - "x": 1700, - "y": 125, - "w": 26, - "h": 200 + "id": "rcz-2-0-ladder-1" }, { - "id": "ladder-arena", + "x": 2008, + "y": 450, + "w": 33, + "h": 270, "kind": "ladder", - "x": 1830, - "y": 320, - "w": 28, - "h": 230 - } - ], - "solid": [ - { - "x": 2152, - "y": 0, - "w": 8, - "h": 720 - } - ], - "noGo": [ - { - "x": 0, - "y": 600, - "kind": "water", - "w": 2160, - "h": 120 + "id": "rcz-2-0-ladder-4" } ], + "solid": [], + "noGo": [], "hazard": [], - "interact": [ + "interact": [], + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ { - "id": "boss-gate", - "kind": "boss-gate", - "x": 1096, - "y": 465, - "w": 30, - "h": 100 + "x": [ + 0, + 168 + ], + "y": [ + 366, + 390 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "note-2", - "kind": "pickup", - "item": "note-2", - "x": 1800, - "y": 105, - "w": 24, - "h": 24 + "x": [ + 120, + 272 + ], + "y": [ + 510, + 534 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "exit-anomaly", - "kind": "chunk-exit", - "x": 2060, - "y": 397, - "w": 60, - "h": 80 - } - ], - "spawn": [ - { - "id": "jenny", - "kind": "jenny", - "x": 1440, - "y": 565 + "x": [ + 168, + 632 + ], + "y": [ + 291, + 315 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "dexter-2", - "kind": "dexter", - "x": 1640, - "y": 565 + "x": [ + 696, + 1080 + ], + "y": [ + 364, + 388 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" }, { - "id": "rover-7", - "kind": "rover", - "x": 700, - "y": 536, - "patrol": [ - 560, - 830 - ] + "x": [ + 1420, + 2160 + ], + "y": [ + 438, + 462 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" } - ], - "ledge": [], - "glideLift": [] + ] } diff --git a/art/stages/rusty-creek/rc-2-0.clean.collision.json b/art/stages/rusty-creek/rc-2-0.clean.collision.json index 32fe613..f6a0fc5 100644 --- a/art/stages/rusty-creek/rc-2-0.clean.collision.json +++ b/art/stages/rusty-creek/rc-2-0.clean.collision.json @@ -9,37 +9,146 @@ [ [ 0, - 566 + 378 + ], + [ + 168, + 378 + ] + ], + [ + [ + 120, + 522 + ], + [ + 272, + 522 + ] + ], + [ + [ + 168, + 303 + ], + [ + 632, + 303 + ] + ], + [ + [ + 696, + 376 + ], + [ + 1080, + 376 + ] + ], + [ + [ + 1420, + 450 ], [ 2160, - 566 + 450 ] ] ], "slide": [], "oneWay": [], - "climb": [], - "solid": [ + "climb": [ { - "x": 2152, - "y": 0, - "w": 8, - "h": 720 - } - ], - "noGo": [ + "x": 708, + "y": 376, + "w": 34, + "h": 344, + "kind": "ladder", + "id": "rcz-2-0-ladder-1" + }, { - "x": 0, - "y": 600, - "kind": "water", - "w": 2160, - "h": 120 + "x": 2008, + "y": 450, + "w": 33, + "h": 270, + "kind": "ladder", + "id": "rcz-2-0-ladder-4" } ], + "solid": [], + "noGo": [], "hazard": [], "interact": [], "spawn": [], "ledge": [], - "glideLift": [] + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 168 + ], + "y": [ + 366, + 390 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 120, + 272 + ], + "y": [ + 510, + 534 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 168, + 632 + ], + "y": [ + 291, + 315 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 696, + 1080 + ], + "y": [ + 364, + 388 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + }, + { + "x": [ + 1420, + 2160 + ], + "y": [ + 438, + 462 + ], + "kind": "plank", + "material": "steel", + "note": "a girder of the rust maze" + } + ] } diff --git a/art/stages/rusty-creek/rc-2-1.anomaly.collision.json b/art/stages/rusty-creek/rc-2-1.anomaly.collision.json new file mode 100644 index 0000000..e79d1a9 --- /dev/null +++ b/art/stages/rusty-creek/rc-2-1.anomaly.collision.json @@ -0,0 +1,211 @@ +{ + "chunk": "rc-2-1", + "state": "anomaly", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 522 + ], + [ + 1690, + 522 + ] + ], + [ + [ + 1690, + 522 + ], + [ + 2160, + 522 + ] + ], + [ + [ + 0, + 65 + ], + [ + 2160, + 65 + ] + ] + ], + "slide": [], + "oneWay": [ + [ + [ + 1180, + 435 + ], + [ + 1382, + 435 + ] + ], + [ + [ + 1430, + 435 + ], + [ + 1632, + 435 + ] + ] + ], + "climb": [ + { + "x": 1706, + "y": 57, + "w": 50, + "h": 465, + "kind": "ladder", + "id": "rcz-2-1-pier-ladder" + }, + { + "x": 708, + "y": 0, + "w": 34, + "h": 65, + "kind": "ladder", + "id": "rcz-2-0-ladder-0-on" + }, + { + "x": 2008, + "y": 0, + "w": 33, + "h": 65, + "kind": "ladder", + "id": "rcz-2-0-ladder-1-on" + } + ], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 600, + "w": 2160, + "h": 120, + "kind": "water" + } + ], + "hazard": [], + "interact": [ + { + "x": 340, + "y": 446, + "w": 130, + "h": 76, + "kind": "door", + "id": "culvert", + "to": "drain-door", + "note": "The lit culvert mouth in the bank: down into the drains." + }, + { + "id": "boss-gate", + "kind": "boss-gate", + "x": 1096, + "y": 422, + "w": 30, + "h": 100 + }, + { + "id": "exit-anomaly", + "kind": "chunk-exit", + "x": 2060, + "y": 442, + "w": 60, + "h": 80 + } + ], + "spawn": [ + { + "id": "jenny", + "kind": "jenny", + "x": 1440, + "y": 522 + }, + { + "id": "dexter-2", + "kind": "dexter", + "x": 1640, + "y": 522 + } + ], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 1180, + 1382 + ], + "y": [ + 423, + 447 + ], + "kind": "plank", + "material": "steel", + "note": "an arena platform on its chains" + }, + { + "x": [ + 1430, + 1632 + ], + "y": [ + 423, + 447 + ], + "kind": "plank", + "material": "steel", + "note": "an arena platform on its chains" + }, + { + "x": [ + 0, + 1690 + ], + "y": [ + 510, + 534 + ], + "kind": "ground", + "material": "stone", + "note": "the creek path" + }, + { + "x": [ + 1690, + 2160 + ], + "y": [ + 510, + 534 + ], + "kind": "ground", + "material": "stone", + "note": "the creek path" + }, + { + "x": [ + 0, + 2160 + ], + "y": [ + 53, + 77 + ], + "kind": "plank", + "material": "steel", + "note": "the railway girder's deck" + } + ] +} diff --git a/art/stages/rusty-creek/rc-2-1.clean.collision.json b/art/stages/rusty-creek/rc-2-1.clean.collision.json new file mode 100644 index 0000000..8356e2f --- /dev/null +++ b/art/stages/rusty-creek/rc-2-1.clean.collision.json @@ -0,0 +1,112 @@ +{ + "chunk": "rc-2-1", + "state": "clean", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 522 + ], + [ + 2160, + 522 + ] + ], + [ + [ + 0, + 65 + ], + [ + 2160, + 65 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [ + { + "x": 1706, + "y": 57, + "w": 50, + "h": 465, + "kind": "ladder", + "id": "rcz-2-1-pier-ladder" + }, + { + "x": 708, + "y": 0, + "w": 34, + "h": 65, + "kind": "ladder", + "id": "rcz-2-0-ladder-0-on" + }, + { + "x": 2008, + "y": 0, + "w": 33, + "h": 65, + "kind": "ladder", + "id": "rcz-2-0-ladder-1-on" + } + ], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 600, + "w": 2160, + "h": 120, + "kind": "water" + } + ], + "hazard": [], + "interact": [ + { + "x": 340, + "y": 446, + "w": 130, + "h": 76, + "kind": "door", + "id": "culvert", + "to": "drain-door", + "note": "The lit culvert mouth in the bank: down into the drains." + } + ], + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 2160 + ], + "y": [ + 510, + 534 + ], + "kind": "ground", + "material": "stone", + "note": "the creek path" + }, + { + "x": [ + 0, + 2160 + ], + "y": [ + 53, + 77 + ], + "kind": "plank", + "material": "steel", + "note": "the railway girder's deck" + } + ] +} diff --git a/art/stages/rusty-creek/rc-2-2.anomaly.collision.json b/art/stages/rusty-creek/rc-2-2.anomaly.collision.json new file mode 100644 index 0000000..bd71cff --- /dev/null +++ b/art/stages/rusty-creek/rc-2-2.anomaly.collision.json @@ -0,0 +1,696 @@ +{ + "chunk": "rc-2-2", + "state": "anomaly", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 283 + ], + [ + 48, + 283 + ], + [ + 64, + 284 + ], + [ + 88, + 285 + ], + [ + 96, + 285 + ], + [ + 104, + 282 + ], + [ + 112, + 279 + ], + [ + 120, + 276 + ] + ], + [ + [ + 212, + 236 + ], + [ + 244, + 235 + ], + [ + 260, + 235 + ], + [ + 268, + 236 + ], + [ + 276, + 238 + ], + [ + 284, + 239 + ], + [ + 292, + 240 + ], + [ + 300, + 242 + ], + [ + 308, + 243 + ], + [ + 324, + 242 + ], + [ + 336, + 242 + ] + ], + [ + [ + 336, + 233 + ], + [ + 352, + 234 + ], + [ + 376, + 235 + ], + [ + 384, + 235 + ], + [ + 432, + 235 + ], + [ + 440, + 233 + ], + [ + 448, + 231 + ], + [ + 456, + 228 + ], + [ + 464, + 226 + ], + [ + 472, + 224 + ], + [ + 480, + 222 + ], + [ + 528, + 222 + ], + [ + 576, + 222 + ], + [ + 584, + 224 + ], + [ + 592, + 225 + ], + [ + 600, + 227 + ], + [ + 608, + 229 + ], + [ + 616, + 230 + ], + [ + 624, + 232 + ], + [ + 632, + 234 + ], + [ + 640, + 237 + ], + [ + 648, + 240 + ], + [ + 664, + 242 + ] + ], + [ + [ + 664, + 234 + ], + [ + 696, + 233 + ], + [ + 712, + 233 + ], + [ + 720, + 234 + ], + [ + 728, + 236 + ], + [ + 736, + 238 + ], + [ + 744, + 239 + ], + [ + 752, + 240 + ], + [ + 760, + 242 + ], + [ + 772, + 242 + ] + ], + [ + [ + 772, + 232 + ], + [ + 804, + 233 + ], + [ + 820, + 233 + ], + [ + 868, + 233 + ], + [ + 916, + 233 + ], + [ + 964, + 233 + ], + [ + 988, + 232 + ], + [ + 1012, + 232 + ], + [ + 1060, + 232 + ], + [ + 1108, + 232 + ], + [ + 1156, + 232 + ], + [ + 1204, + 232 + ], + [ + 1252, + 232 + ], + [ + 1260, + 234 + ], + [ + 1268, + 235 + ], + [ + 1276, + 237 + ], + [ + 1284, + 239 + ], + [ + 1292, + 240 + ], + [ + 1300, + 242 + ], + [ + 1308, + 240 + ], + [ + 1316, + 239 + ], + [ + 1324, + 238 + ], + [ + 1332, + 236 + ], + [ + 1340, + 234 + ], + [ + 1348, + 233 + ], + [ + 1372, + 234 + ], + [ + 1396, + 234 + ], + [ + 1404, + 233 + ], + [ + 1412, + 232 + ], + [ + 1428, + 231 + ], + [ + 1436, + 230 + ], + [ + 1444, + 229 + ], + [ + 1452, + 228 + ], + [ + 1460, + 226 + ], + [ + 1468, + 225 + ], + [ + 1476, + 224 + ], + [ + 1484, + 222 + ], + [ + 1492, + 221 + ], + [ + 1540, + 221 + ], + [ + 1588, + 221 + ], + [ + 1596, + 224 + ], + [ + 1604, + 227 + ], + [ + 1612, + 230 + ], + [ + 1620, + 232 + ], + [ + 1628, + 235 + ], + [ + 1636, + 238 + ], + [ + 1644, + 237 + ], + [ + 1652, + 236 + ], + [ + 1668, + 235 + ], + [ + 1676, + 234 + ], + [ + 1684, + 233 + ], + [ + 1700, + 232 + ], + [ + 1724, + 231 + ], + [ + 1732, + 231 + ], + [ + 1740, + 233 + ], + [ + 1748, + 235 + ], + [ + 1756, + 236 + ], + [ + 1764, + 238 + ], + [ + 1772, + 240 + ], + [ + 1780, + 242 + ], + [ + 1788, + 240 + ], + [ + 1796, + 239 + ], + [ + 1804, + 238 + ], + [ + 1812, + 236 + ], + [ + 1820, + 234 + ], + [ + 1828, + 233 + ], + [ + 1852, + 232 + ], + [ + 1876, + 232 + ], + [ + 1908, + 231 + ], + [ + 1924, + 231 + ], + [ + 1948, + 232 + ], + [ + 1972, + 232 + ], + [ + 1988, + 233 + ], + [ + 1996, + 234 + ], + [ + 2020, + 235 + ], + [ + 2028, + 236 + ], + [ + 2044, + 237 + ], + [ + 2052, + 238 + ], + [ + 2068, + 239 + ], + [ + 2076, + 240 + ], + [ + 2100, + 241 + ], + [ + 2108, + 242 + ], + [ + 2116, + 242 + ], + [ + 2124, + 240 + ], + [ + 2132, + 239 + ], + [ + 2140, + 237 + ], + [ + 2148, + 235 + ], + [ + 2160, + 233 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 612, + "w": 2160, + "h": 108, + "kind": "water" + } + ], + "hazard": [], + "interact": [ + { + "x": 340, + "y": 159, + "w": 130, + "h": 76, + "kind": "door", + "id": "drain-door", + "to": "culvert", + "note": "Back up through the culvert to the creek path." + }, + { + "id": "note-2", + "kind": "pickup", + "item": "note-2", + "x": 1900, + "y": 197, + "w": 24, + "h": 24 + } + ], + "spawn": [ + { + "id": "rover-7", + "kind": "rover", + "x": 1300, + "y": 221, + "patrol": [ + 1000, + 1700 + ] + } + ], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 120 + ], + "y": [ + 264, + 297 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 212, + 336 + ], + "y": [ + 223, + 255 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 336, + 664 + ], + "y": [ + 210, + 254 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 664, + 772 + ], + "y": [ + 221, + 254 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 772, + 2160 + ], + "y": [ + 209, + 254 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + } + ] +} diff --git a/art/stages/rusty-creek/rc-2-2.clean.collision.json b/art/stages/rusty-creek/rc-2-2.clean.collision.json new file mode 100644 index 0000000..b3437f7 --- /dev/null +++ b/art/stages/rusty-creek/rc-2-2.clean.collision.json @@ -0,0 +1,676 @@ +{ + "chunk": "rc-2-2", + "state": "clean", + "size": [ + 2160, + 720 + ], + "walk": [ + [ + [ + 0, + 283 + ], + [ + 48, + 283 + ], + [ + 64, + 284 + ], + [ + 88, + 285 + ], + [ + 96, + 285 + ], + [ + 104, + 282 + ], + [ + 112, + 279 + ], + [ + 120, + 276 + ] + ], + [ + [ + 212, + 236 + ], + [ + 244, + 235 + ], + [ + 260, + 235 + ], + [ + 268, + 236 + ], + [ + 276, + 238 + ], + [ + 284, + 239 + ], + [ + 292, + 240 + ], + [ + 300, + 242 + ], + [ + 308, + 243 + ], + [ + 324, + 242 + ], + [ + 336, + 242 + ] + ], + [ + [ + 336, + 233 + ], + [ + 352, + 234 + ], + [ + 376, + 235 + ], + [ + 384, + 235 + ], + [ + 432, + 235 + ], + [ + 440, + 233 + ], + [ + 448, + 231 + ], + [ + 456, + 228 + ], + [ + 464, + 226 + ], + [ + 472, + 224 + ], + [ + 480, + 222 + ], + [ + 528, + 222 + ], + [ + 576, + 222 + ], + [ + 584, + 224 + ], + [ + 592, + 225 + ], + [ + 600, + 227 + ], + [ + 608, + 229 + ], + [ + 616, + 230 + ], + [ + 624, + 232 + ], + [ + 632, + 234 + ], + [ + 640, + 237 + ], + [ + 648, + 240 + ], + [ + 664, + 242 + ] + ], + [ + [ + 664, + 234 + ], + [ + 696, + 233 + ], + [ + 712, + 233 + ], + [ + 720, + 234 + ], + [ + 728, + 236 + ], + [ + 736, + 238 + ], + [ + 744, + 239 + ], + [ + 752, + 240 + ], + [ + 760, + 242 + ], + [ + 772, + 242 + ] + ], + [ + [ + 772, + 232 + ], + [ + 804, + 233 + ], + [ + 820, + 233 + ], + [ + 868, + 233 + ], + [ + 916, + 233 + ], + [ + 964, + 233 + ], + [ + 988, + 232 + ], + [ + 1012, + 232 + ], + [ + 1060, + 232 + ], + [ + 1108, + 232 + ], + [ + 1156, + 232 + ], + [ + 1204, + 232 + ], + [ + 1252, + 232 + ], + [ + 1260, + 234 + ], + [ + 1268, + 235 + ], + [ + 1276, + 237 + ], + [ + 1284, + 239 + ], + [ + 1292, + 240 + ], + [ + 1300, + 242 + ], + [ + 1308, + 240 + ], + [ + 1316, + 239 + ], + [ + 1324, + 238 + ], + [ + 1332, + 236 + ], + [ + 1340, + 234 + ], + [ + 1348, + 233 + ], + [ + 1372, + 234 + ], + [ + 1396, + 234 + ], + [ + 1404, + 233 + ], + [ + 1412, + 232 + ], + [ + 1428, + 231 + ], + [ + 1436, + 230 + ], + [ + 1444, + 229 + ], + [ + 1452, + 228 + ], + [ + 1460, + 226 + ], + [ + 1468, + 225 + ], + [ + 1476, + 224 + ], + [ + 1484, + 222 + ], + [ + 1492, + 221 + ], + [ + 1540, + 221 + ], + [ + 1588, + 221 + ], + [ + 1596, + 224 + ], + [ + 1604, + 227 + ], + [ + 1612, + 230 + ], + [ + 1620, + 232 + ], + [ + 1628, + 235 + ], + [ + 1636, + 238 + ], + [ + 1644, + 237 + ], + [ + 1652, + 236 + ], + [ + 1668, + 235 + ], + [ + 1676, + 234 + ], + [ + 1684, + 233 + ], + [ + 1700, + 232 + ], + [ + 1724, + 231 + ], + [ + 1732, + 231 + ], + [ + 1740, + 233 + ], + [ + 1748, + 235 + ], + [ + 1756, + 236 + ], + [ + 1764, + 238 + ], + [ + 1772, + 240 + ], + [ + 1780, + 242 + ], + [ + 1788, + 240 + ], + [ + 1796, + 239 + ], + [ + 1804, + 238 + ], + [ + 1812, + 236 + ], + [ + 1820, + 234 + ], + [ + 1828, + 233 + ], + [ + 1852, + 232 + ], + [ + 1876, + 232 + ], + [ + 1908, + 231 + ], + [ + 1924, + 231 + ], + [ + 1948, + 232 + ], + [ + 1972, + 232 + ], + [ + 1988, + 233 + ], + [ + 1996, + 234 + ], + [ + 2020, + 235 + ], + [ + 2028, + 236 + ], + [ + 2044, + 237 + ], + [ + 2052, + 238 + ], + [ + 2068, + 239 + ], + [ + 2076, + 240 + ], + [ + 2100, + 241 + ], + [ + 2108, + 242 + ], + [ + 2116, + 242 + ], + [ + 2124, + 240 + ], + [ + 2132, + 239 + ], + [ + 2140, + 237 + ], + [ + 2148, + 235 + ], + [ + 2160, + 233 + ] + ] + ], + "slide": [], + "oneWay": [], + "climb": [], + "solid": [], + "noGo": [ + { + "x": 0, + "y": 612, + "w": 2160, + "h": 108, + "kind": "water" + } + ], + "hazard": [], + "interact": [ + { + "x": 340, + "y": 159, + "w": 130, + "h": 76, + "kind": "door", + "id": "drain-door", + "to": "culvert", + "note": "Back up through the culvert to the creek path." + } + ], + "spawn": [], + "ledge": [], + "glideLift": [], + "terrain": [ + { + "x": [ + 0, + 120 + ], + "y": [ + 264, + 297 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 212, + 336 + ], + "y": [ + 223, + 255 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 336, + 664 + ], + "y": [ + 210, + 254 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 664, + 772 + ], + "y": [ + 221, + 254 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + }, + { + "x": [ + 772, + 2160 + ], + "y": [ + 209, + 254 + ], + "kind": "ground", + "material": "stone", + "note": "the drains' floor" + } + ] +} diff --git a/art/stages/rusty-creek/repair-report.json b/art/stages/rusty-creek/repair-report.json deleted file mode 100644 index 12a130f..0000000 --- a/art/stages/rusty-creek/repair-report.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "automatic_art_approval": false, - "visual_seams_approved": false, - "packet_sha256": "a457614e0029d74d0357955f6b076216dcc5a9480ce7635a109f3f91b7b871e3", - "layers": [ - { - "id": "structure", - "file": "structure-repaired.png", - "sha256": "8793e7606a61bc670a9833e78ce4f70b4c1c56946a0eb15f8f41cd380a6fa9fd", - "dimensions": [ - 6480, - 720 - ], - "outside_repair_changed_pixels": 0 - } - ], - "repairs": [ - { - "job": "structure--left--center", - "candidate_sha256": "c2959d99b9a96e8fadd44fe9fd87aace3942afe6dfbb874b7d8769e67b240ca6", - "native_size": [ - 2172, - 724 - ], - "applied_size": [ - 2160, - 720 - ], - "normalization": "nearest-neighbor", - "world_box": [ - 1904, - 0, - 2416, - 720 - ] - }, - { - "job": "structure--center--right", - "candidate_sha256": "6c1f64a1502711f7e5d04e98bd4d58996d03c985bc8a6dc31345ebe338642166", - "native_size": [ - 2172, - 724 - ], - "applied_size": [ - 2160, - 720 - ], - "normalization": "nearest-neighbor", - "world_box": [ - 4064, - 0, - 4576, - 720 - ] - } - ] -} diff --git a/art/stages/rusty-creek/route.json b/art/stages/rusty-creek/route.json deleted file mode 100644 index f949d75..0000000 --- a/art/stages/rusty-creek/route.json +++ /dev/null @@ -1,853 +0,0 @@ -{ - "version": 2, - "world_size": [ - 6480, - 720 - ], - "body_size": [ - 18, - 32 - ], - "proposed_jump": { - "max_horizontal": 180, - "max_rise": 120 - }, - "entry": "entry", - "exit": "exit", - "boss": "boss", - "nodes": [ - { - "id": "entry", - "at": [ - 80, - 460 - ], - "purpose": "entry" - }, - { - "id": "l-approach", - "at": [ - 410, - 460 - ] - }, - { - "id": "l-slope", - "at": [ - 480, - 505 - ] - }, - { - "id": "l-ladder-foot", - "at": [ - 610, - 505 - ] - }, - { - "id": "l-ladder-top", - "at": [ - 610, - 145 - ] - }, - { - "id": "l-upper-step", - "at": [ - 735, - 165 - ] - }, - { - "id": "l-return-top", - "at": [ - 1350, - 165 - ] - }, - { - "id": "l-return-foot", - "at": [ - 1350, - 495 - ] - }, - { - "id": "l-low", - "at": [ - 1530, - 520 - ] - }, - { - "id": "l-ramp", - "at": [ - 1770, - 460 - ] - }, - { - "id": "join-lc", - "at": [ - 2160, - 460 - ], - "purpose": "boundary" - }, - { - "id": "c-entry", - "at": [ - 2480, - 460 - ] - }, - { - "id": "c-foot", - "at": [ - 2780, - 500 - ] - }, - { - "id": "c-climb", - "at": [ - 2780, - 220 - ] - }, - { - "id": "c-tower-jump", - "at": [ - 3060, - 220 - ] - }, - { - "id": "c-upper", - "at": [ - 3120, - 145 - ] - }, - { - "id": "c-return-top", - "at": [ - 3570, - 145 - ] - }, - { - "id": "c-return-foot", - "at": [ - 3570, - 405 - ] - }, - { - "id": "c-middle", - "at": [ - 3740, - 405 - ] - }, - { - "id": "c-step", - "at": [ - 3790, - 465 - ] - }, - { - "id": "c-low-ladder", - "at": [ - 3910, - 465 - ] - }, - { - "id": "c-low", - "at": [ - 3910, - 540 - ] - }, - { - "id": "c-ramp", - "at": [ - 4100, - 465 - ] - }, - { - "id": "join-cr", - "at": [ - 4320, - 465 - ], - "purpose": "boundary" - }, - { - "id": "r-approach", - "at": [ - 4510, - 480 - ] - }, - { - "id": "r-foot", - "at": [ - 4690, - 520 - ] - }, - { - "id": "r-climb", - "at": [ - 4690, - 250 - ] - }, - { - "id": "r-jump-start", - "at": [ - 4830, - 250 - ] - }, - { - "id": "r-upper", - "at": [ - 4890, - 180 - ] - }, - { - "id": "r-return-top", - "at": [ - 5370, - 180 - ] - }, - { - "id": "r-return-foot", - "at": [ - 5370, - 565 - ] - }, - { - "id": "arena-entry", - "at": [ - 5500, - 565 - ] - }, - { - "id": "boss", - "at": [ - 5760, - 565 - ], - "purpose": "boss clearing" - }, - { - "id": "arena-exit", - "at": [ - 6050, - 565 - ] - }, - { - "id": "r-exit-ramp", - "at": [ - 6280, - 480 - ] - }, - { - "id": "exit", - "at": [ - 6400, - 480 - ], - "purpose": "exit" - }, - { - "id": "l-lookout", - "at": [ - 1120, - 285 - ], - "purpose": "optional dead end" - }, - { - "id": "c-cache", - "at": [ - 3380, - 245 - ], - "purpose": "optional dead end" - }, - { - "id": "r-overlook", - "at": [ - 6040, - 180 - ], - "purpose": "optional dead end" - }, - { - "id": "c-loop-a", - "at": [ - 2780, - 355 - ] - }, - { - "id": "c-loop-b", - "at": [ - 3120, - 355 - ] - }, - { - "id": "l-spur-base", - "at": [ - 875, - 505 - ] - }, - { - "id": "l-spur-climb", - "at": [ - 875, - 400 - ] - }, - { - "id": "l-spur-foot", - "at": [ - 1040, - 400 - ] - }, - { - "id": "l-spur-top", - "at": [ - 1040, - 285 - ] - }, - { - "id": "c-spur-foot", - "at": [ - 3300, - 355 - ] - }, - { - "id": "c-spur-top", - "at": [ - 3300, - 245 - ] - } - ], - "edges": [ - { - "from": "entry", - "to": "l-approach", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-approach", - "to": "l-slope", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-slope", - "to": "l-ladder-foot", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-ladder-foot", - "to": "l-ladder-top", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "l-ladder-top", - "to": "l-upper-step", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-upper-step", - "to": "l-return-top", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-return-top", - "to": "l-return-foot", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "l-return-foot", - "to": "l-low", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-low", - "to": "l-ramp", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-ramp", - "to": "join-lc", - "kind": "walk", - "bidirectional": true - }, - { - "from": "join-lc", - "to": "c-entry", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-entry", - "to": "c-foot", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-foot", - "to": "c-climb", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "c-climb", - "to": "c-tower-jump", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-tower-jump", - "to": "c-upper", - "kind": "jump", - "bidirectional": true - }, - { - "from": "c-upper", - "to": "c-return-top", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-return-top", - "to": "c-return-foot", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "c-return-foot", - "to": "c-middle", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-middle", - "to": "c-step", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-step", - "to": "c-low-ladder", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-low-ladder", - "to": "c-low", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "c-low", - "to": "c-ramp", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-ramp", - "to": "join-cr", - "kind": "walk", - "bidirectional": true - }, - { - "from": "join-cr", - "to": "r-approach", - "kind": "walk", - "bidirectional": true - }, - { - "from": "r-approach", - "to": "r-foot", - "kind": "walk", - "bidirectional": true - }, - { - "from": "r-foot", - "to": "r-climb", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "r-climb", - "to": "r-jump-start", - "kind": "walk", - "bidirectional": true - }, - { - "from": "r-jump-start", - "to": "r-upper", - "kind": "jump", - "bidirectional": true - }, - { - "from": "r-upper", - "to": "r-return-top", - "kind": "walk", - "bidirectional": true - }, - { - "from": "r-return-top", - "to": "r-return-foot", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "r-return-foot", - "to": "arena-entry", - "kind": "walk", - "bidirectional": true - }, - { - "from": "arena-entry", - "to": "boss", - "kind": "walk", - "bidirectional": true - }, - { - "from": "boss", - "to": "arena-exit", - "kind": "walk", - "bidirectional": true - }, - { - "from": "arena-exit", - "to": "r-exit-ramp", - "kind": "walk", - "bidirectional": true - }, - { - "from": "r-exit-ramp", - "to": "exit", - "kind": "walk", - "bidirectional": true - }, - { - "from": "r-return-top", - "to": "r-overlook", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-climb", - "to": "c-loop-a", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "c-loop-a", - "to": "c-loop-b", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-loop-b", - "to": "c-upper", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "l-ladder-foot", - "to": "l-spur-base", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-spur-base", - "to": "l-spur-climb", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "l-spur-climb", - "to": "l-spur-foot", - "kind": "walk", - "bidirectional": true - }, - { - "from": "l-spur-foot", - "to": "l-spur-top", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "l-spur-top", - "to": "l-lookout", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-loop-b", - "to": "c-spur-foot", - "kind": "walk", - "bidirectional": true - }, - { - "from": "c-spur-foot", - "to": "c-spur-top", - "kind": "ladder", - "bidirectional": true - }, - { - "from": "c-spur-top", - "to": "c-cache", - "kind": "walk", - "bidirectional": true - } - ], - "notes": [ - "Authoring intent traced over the generated structure; not collision geometry or a physics playtest.", - "Spurs have intermediate walk/climb anchors; every segment still needs pixel-to-collider and headroom review.", - "Boss clearing is reserved space; no boss or encounter is implemented.", - "All mutation is disabled while inspecting the clean location. Physical route activation requires a separate safe checkpoint transition." - ], - "interaction_anchors": [ - { - "id": "l-ladder-foot--l-ladder-top", - "role": "climb", - "feet_start": [ - 610, - 505 - ], - "feet_end": [ - 610, - 145 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "l-return-top--l-return-foot", - "role": "climb", - "feet_start": [ - 1350, - 165 - ], - "feet_end": [ - 1350, - 495 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "c-foot--c-climb", - "role": "climb", - "feet_start": [ - 2780, - 500 - ], - "feet_end": [ - 2780, - 220 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "c-return-top--c-return-foot", - "role": "climb", - "feet_start": [ - 3570, - 145 - ], - "feet_end": [ - 3570, - 405 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "c-low-ladder--c-low", - "role": "climb", - "feet_start": [ - 3910, - 465 - ], - "feet_end": [ - 3910, - 540 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "r-foot--r-climb", - "role": "climb", - "feet_start": [ - 4690, - 520 - ], - "feet_end": [ - 4690, - 250 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "r-return-top--r-return-foot", - "role": "climb", - "feet_start": [ - 5370, - 180 - ], - "feet_end": [ - 5370, - 565 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "c-climb--c-loop-a", - "role": "climb", - "feet_start": [ - 2780, - 220 - ], - "feet_end": [ - 2780, - 355 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "c-loop-b--c-upper", - "role": "climb", - "feet_start": [ - 3120, - 355 - ], - "feet_end": [ - 3120, - 145 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "l-spur-base--l-spur-climb", - "role": "climb", - "feet_start": [ - 875, - 505 - ], - "feet_end": [ - 875, - 400 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "l-spur-foot--l-spur-top", - "role": "climb", - "feet_start": [ - 1040, - 400 - ], - "feet_end": [ - 1040, - 285 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - }, - { - "id": "c-spur-foot--c-spur-top", - "role": "climb", - "feet_start": [ - 3300, - 355 - ], - "feet_end": [ - 3300, - 245 - ], - "body_size": [ - 18, - 32 - ], - "status": "proposed; not collision-verified" - } - ] -} diff --git a/art/stages/rusty-creek/sources/center.png b/art/stages/rusty-creek/sources/center.png deleted file mode 100644 index 23cf757..0000000 Binary files a/art/stages/rusty-creek/sources/center.png and /dev/null differ diff --git a/art/stages/rusty-creek/sources/left.png b/art/stages/rusty-creek/sources/left.png deleted file mode 100644 index eb4fb27..0000000 Binary files a/art/stages/rusty-creek/sources/left.png and /dev/null differ diff --git a/art/stages/rusty-creek/sources/plants.png b/art/stages/rusty-creek/sources/plants.png deleted file mode 100644 index 10f4b07..0000000 Binary files a/art/stages/rusty-creek/sources/plants.png and /dev/null differ diff --git a/art/stages/rusty-creek/sources/right.png b/art/stages/rusty-creek/sources/right.png deleted file mode 100644 index 9220052..0000000 Binary files a/art/stages/rusty-creek/sources/right.png and /dev/null differ diff --git a/art/stages/rusty-creek/sources/structure--center--right-candidate.png b/art/stages/rusty-creek/sources/structure--center--right-candidate.png deleted file mode 100644 index 9cc6df0..0000000 Binary files a/art/stages/rusty-creek/sources/structure--center--right-candidate.png and /dev/null differ diff --git a/art/stages/rusty-creek/sources/structure--left--center-candidate.png b/art/stages/rusty-creek/sources/structure--left--center-candidate.png deleted file mode 100644 index b06b1aa..0000000 Binary files a/art/stages/rusty-creek/sources/structure--left--center-candidate.png and /dev/null differ diff --git a/art/stages/rusty-creek/stage.json b/art/stages/rusty-creek/stage.json deleted file mode 100644 index 67fe89d..0000000 --- a/art/stages/rusty-creek/stage.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "panel_size": [ - 2160, - 720 - ], - "model": "gpt-image-2.5-sunburst", - "normalize_inputs": false, - "chunks": [ - "left", - "center", - "right" - ], - "layers": [ - { - "id": "structure", - "role": "scene-first broad steel and masonry; separate after seam repair", - "transparent": true, - "repair_direction": "Connect the broad low deck at y=460 across this join, preserving footings down to y=630 and matching edge heights at both sides of the editable band. No thin bars, foliage, red matte fringes, water, sky or new towers. Keep opening/headroom and transparent background.", - "panels": { - "left": "tmp/stages/rusty-creek/left-normalized.png", - "center": "tmp/stages/rusty-creek/center-normalized.png", - "right": "tmp/stages/rusty-creek/right-normalized.png" - } - } - ] -} diff --git a/art/stages/rusty-creek/surfaces.json b/art/stages/rusty-creek/surfaces.json index 85d75b9..fe4e6b4 100644 --- a/art/stages/rusty-creek/surfaces.json +++ b/art/stages/rusty-creek/surfaces.json @@ -7,8 +7,55 @@ "stone": {"sink": 1, "cover": 0, "puff": {"sprite": "dust", "shape": "dust", "colors": ["#b9b3a3", "#d9d3c2", "#8a857a"], "count": 3}} }, "chunks": { - "rc-0-0": [{"x": [0, 2160], "y": [490, 720], "states": ["anomaly"], "material": "stone", "note": "bank blocks"}], - "rc-1-0": [{"x": [0, 2160], "y": [490, 720], "states": ["anomaly"], "material": "stone", "note": "bank blocks"}], - "rc-2-0": [{"x": [0, 2160], "y": [490, 720], "states": ["anomaly"], "material": "stone", "note": "bank blocks"}] + "rc-0-0": [ + {"x": [80, 304], "y": [315, 339], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [132, 780], "y": [512, 536], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [360, 544], "y": [196, 220], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [880, 1136], "y": [461, 485], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [1136, 1408], "y": [436, 460], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [1440, 2160], "y": [275, 299], "material": "steel", "note": "plank: a girder of the rust maze"} + ], + "rc-1-0": [ + {"x": [0, 680], "y": [645, 669], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [164, 1860], "y": [319, 343], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [868, 1612], "y": [524, 548], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [1628, 1736], "y": [646, 670], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [2084, 2160], "y": [646, 670], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [1736, 2084], "y": [593, 617], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [1912, 2160], "y": [366, 390], "material": "steel", "note": "plank: a girder of the rust maze"} + ], + "rc-2-0": [ + {"x": [0, 168], "y": [366, 390], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [120, 272], "y": [510, 534], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [168, 632], "y": [291, 315], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [696, 1080], "y": [364, 388], "material": "steel", "note": "plank: a girder of the rust maze"}, + {"x": [1420, 2160], "y": [438, 462], "material": "steel", "note": "plank: a girder of the rust maze"} + ], + "rc-0-1": [ + {"x": [0, 2160], "y": [510, 534], "material": "stone", "note": "ground: the creek path"}, + {"x": [0, 2160], "y": [50, 74], "material": "steel", "note": "plank: the railway girder's deck"} + ], + "rc-0-2": [ + {"x": [0, 56], "y": [184, 210], "material": "stone", "note": "ground: the drains' floor"}, + {"x": [0, 2160], "y": [150, 176], "material": "stone", "note": "ground: the drains' floor"} + ], + "rc-1-1": [ + {"x": [0, 2160], "y": [510, 534], "material": "stone", "note": "ground: the creek path"}, + {"x": [0, 2160], "y": [51, 75], "material": "steel", "note": "plank: the railway girder's deck"} + ], + "rc-1-2": [ + {"x": [0, 2160], "y": [185, 290], "material": "stone", "note": "ground: the drains' floor"} + ], + "rc-2-1": [ + {"x": [0, 2160], "y": [510, 534], "material": "stone", "note": "ground: the creek path"}, + {"x": [0, 2160], "y": [53, 77], "material": "steel", "note": "plank: the railway girder's deck"} + ], + "rc-2-2": [ + {"x": [0, 120], "y": [264, 297], "material": "stone", "note": "ground: the drains' floor"}, + {"x": [212, 336], "y": [223, 255], "material": "stone", "note": "ground: the drains' floor"}, + {"x": [336, 664], "y": [210, 254], "material": "stone", "note": "ground: the drains' floor"}, + {"x": [664, 772], "y": [221, 254], "material": "stone", "note": "ground: the drains' floor"}, + {"x": [772, 2160], "y": [209, 254], "material": "stone", "note": "ground: the drains' floor"} + ] } } diff --git a/art/stages/rusty-creek/tears/rc-0-0.png b/art/stages/rusty-creek/tears/rc-0-0.png new file mode 100644 index 0000000..1417912 Binary files /dev/null and b/art/stages/rusty-creek/tears/rc-0-0.png differ diff --git a/art/stages/rusty-creek/tears/rc-1-0.png b/art/stages/rusty-creek/tears/rc-1-0.png new file mode 100644 index 0000000..1156dda Binary files /dev/null and b/art/stages/rusty-creek/tears/rc-1-0.png differ diff --git a/art/stages/rusty-creek/tears/rc-2-0.png b/art/stages/rusty-creek/tears/rc-2-0.png new file mode 100644 index 0000000..7789706 Binary files /dev/null and b/art/stages/rusty-creek/tears/rc-2-0.png differ diff --git a/art/stages/rusty-creek/verification.json b/art/stages/rusty-creek/verification.json deleted file mode 100644 index 947fbcf..0000000 --- a/art/stages/rusty-creek/verification.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "world_size": [ - 6480, - 720 - ], - "layer_chunks": 21, - "structure_partition_changed_pixels": 0, - "outside_repair_changed_pixels": 0, - "shared_role_source_differences": 0, - "red_matte_pixels_removed": { - "left": 3022, - "center": 1786, - "right": 3026, - "post_repair": 360 - }, - "route_graph_errors": [], - "graph_is_not_physics": true, - "repair_report": { - "automatic_art_approval": false, - "visual_seams_approved": false, - "packet_sha256": "a457614e0029d74d0357955f6b076216dcc5a9480ce7635a109f3f91b7b871e3", - "layers": [ - { - "id": "structure", - "file": "structure-repaired.png", - "sha256": "8793e7606a61bc670a9833e78ce4f70b4c1c56946a0eb15f8f41cd380a6fa9fd", - "dimensions": [ - 6480, - 720 - ], - "outside_repair_changed_pixels": 0 - } - ], - "repairs": [ - { - "job": "structure--left--center", - "candidate_sha256": "c2959d99b9a96e8fadd44fe9fd87aace3942afe6dfbb874b7d8769e67b240ca6", - "native_size": [ - 2172, - 724 - ], - "applied_size": [ - 2160, - 720 - ], - "normalization": "nearest-neighbor", - "world_box": [ - 1904, - 0, - 2416, - 720 - ] - }, - { - "job": "structure--center--right", - "candidate_sha256": "6c1f64a1502711f7e5d04e98bd4d58996d03c985bc8a6dc31345ebe338642166", - "native_size": [ - 2172, - 724 - ], - "applied_size": [ - 2160, - 720 - ], - "normalization": "nearest-neighbor", - "world_box": [ - 4064, - 0, - 4576, - 720 - ] - } - ] - } -} diff --git a/art/zones/rusty-creek/blockout/rcz-0-0.png b/art/zones/rusty-creek/blockout/rcz-0-0.png index e4447f4..1fa6e0c 100644 Binary files a/art/zones/rusty-creek/blockout/rcz-0-0.png and b/art/zones/rusty-creek/blockout/rcz-0-0.png differ diff --git a/art/zones/rusty-creek/blockout/rcz-1-0.png b/art/zones/rusty-creek/blockout/rcz-1-0.png index 5d009e3..c0cbdc2 100644 Binary files a/art/zones/rusty-creek/blockout/rcz-1-0.png and b/art/zones/rusty-creek/blockout/rcz-1-0.png differ diff --git a/art/zones/rusty-creek/blockout/rcz-2-0.png b/art/zones/rusty-creek/blockout/rcz-2-0.png index b51673b..08d3c36 100644 Binary files a/art/zones/rusty-creek/blockout/rcz-2-0.png and b/art/zones/rusty-creek/blockout/rcz-2-0.png differ diff --git a/art/zones/rusty-creek/collision/rcz-0-0.collision.json b/art/zones/rusty-creek/collision/rcz-0-0.collision.json index 5227caa..be4926d 100644 --- a/art/zones/rusty-creek/collision/rcz-0-0.collision.json +++ b/art/zones/rusty-creek/collision/rcz-0-0.collision.json @@ -11,438 +11,34 @@ 80, 327 ], - [ - 128, - 327 - ], - [ - 176, - 327 - ], - [ - 224, - 327 - ], - [ - 272, - 327 - ], - [ - 280, - 331 - ], - [ - 288, - 334 - ], - [ - 296, - 338 - ], [ 304, - 342 + 327 ] ], [ [ 132, - 522 - ], - [ - 148, - 523 - ], - [ - 172, - 524 - ], - [ - 180, 524 ], - [ - 228, - 524 - ], - [ - 276, - 524 - ], - [ - 324, - 524 - ], - [ - 372, - 524 - ], - [ - 420, - 524 - ], - [ - 468, - 524 - ], - [ - 516, - 524 - ], - [ - 564, - 524 - ], - [ - 612, - 524 - ], - [ - 644, - 525 - ], - [ - 660, - 525 - ], - [ - 684, - 526 - ], - [ - 708, - 526 - ], - [ - 740, - 527 - ], - [ - 756, - 527 - ], - [ - 772, - 528 - ], [ 780, - 528 + 524 ] ], [ [ 360, - 206 - ], - [ - 408, - 206 - ], - [ - 440, - 207 - ], - [ - 456, - 207 - ], - [ - 472, 208 ], - [ - 496, - 209 - ], - [ - 504, - 209 - ], - [ - 520, - 210 - ], [ 544, - 210 - ] - ], - [ - [ - 2092, - 57 - ], - [ - 2100, - 56 - ], - [ - 2124, - 55 - ], - [ - 2132, - 54 - ], - [ - 2140, - 54 - ], - [ - 2156, - 53 - ], - [ - 2160, - 53 - ] - ], - [ - [ - 412, - 0 - ], - [ - 460, - 0 - ], - [ - 508, - 0 - ], - [ - 556, - 0 - ], - [ - 604, - 0 - ], - [ - 652, - 0 - ], - [ - 676, - 0 - ] - ], - [ - [ - 544, - 193 - ], - [ - 552, - 192 - ], - [ - 560, - 191 - ], - [ - 568, - 190 - ], - [ - 584, - 189 - ], - [ - 592, - 188 - ], - [ - 600, - 187 - ], - [ - 608, - 186 - ], - [ - 624, - 185 - ], - [ - 632, - 184 - ], - [ - 640, - 183 - ], - [ - 648, - 181 - ], - [ - 656, - 179 - ], - [ - 664, - 177 - ], - [ - 672, - 175 - ], - [ - 680, - 173 - ], - [ - 688, - 171 - ], - [ - 696, - 162 - ], - [ - 704, - 154 - ] - ], - [ - [ - 676, - 21 - ], - [ - 724, - 21 - ], - [ - 772, - 21 - ], - [ - 820, - 21 - ], - [ - 868, - 21 - ], - [ - 916, - 21 - ], - [ - 964, - 21 - ], - [ - 1012, - 21 - ], - [ - 1060, - 21 - ], - [ - 1108, - 21 - ], - [ - 1156, - 21 - ], - [ - 1204, - 21 - ], - [ - 1252, - 21 - ], - [ - 1300, - 21 - ], - [ - 1348, - 21 - ], - [ - 1396, - 21 - ], - [ - 1444, - 21 - ], - [ - 1492, - 21 - ], - [ - 1540, - 21 - ], - [ - 1588, - 21 - ], - [ - 1612, - 20 - ], - [ - 1636, - 20 - ], - [ - 1652, - 19 - ], - [ - 1676, - 18 - ], - [ - 1684, - 18 - ], - [ - 1704, - 18 + 208 ] ], [ [ 880, - 471 - ], - [ - 896, - 472 - ], - [ - 920, - 473 - ], - [ - 928, - 473 - ], - [ - 976, - 473 - ], - [ - 1024, - 473 - ], - [ - 1072, - 473 - ], - [ - 1120, 473 ], [ @@ -453,63 +49,11 @@ [ [ 1136, - 456 - ], - [ - 1144, - 454 - ], - [ - 1152, - 453 - ], - [ - 1160, - 451 - ], - [ - 1168, - 449 - ], - [ - 1176, - 448 - ], - [ - 1184, - 446 - ], - [ - 1200, - 447 - ], - [ - 1224, - 448 - ], - [ - 1232, - 448 - ], - [ - 1280, 448 ], - [ - 1328, - 448 - ], - [ - 1376, - 448 - ], - [ - 1400, - 447 - ], [ 1408, - 447 + 448 ] ], [ @@ -517,132 +61,28 @@ 1440, 287 ], - [ - 1488, - 287 - ], - [ - 1536, - 287 - ], - [ - 1584, - 287 - ], - [ - 1632, - 287 - ], - [ - 1680, - 287 - ], - [ - 1728, - 287 - ], - [ - 1776, - 287 - ], - [ - 1824, - 287 - ], - [ - 1872, - 287 - ], - [ - 1920, - 287 - ], - [ - 1968, - 287 - ], - [ - 2016, - 287 - ], - [ - 2064, - 287 - ], - [ - 2112, - 287 - ], [ 2160, 287 ] - ], - [ - [ - 1704, - 0 - ], - [ - 1752, - 0 - ], - [ - 1800, - 0 - ], - [ - 1848, - 0 - ], - [ - 1896, - 0 - ], - [ - 1916, - 0 - ] - ], - [ - [ - 1916, - 21 - ], - [ - 1940, - 22 - ], - [ - 1964, - 22 - ], - [ - 2012, - 22 - ], - [ - 2044, - 23 - ], - [ - 2060, - 23 - ], - [ - 2092, - 23 - ] ] ], "slide": [], "oneWay": [], "climb": [ + { + "x": 495, + "y": 208, + "w": 33, + "h": 316, + "kind": "ladder", + "id": "rcz-0-0-ladder-0" + }, { "x": 1619, - "y": 23, + "y": 287, "w": 33, - "h": 697, + "h": 433, "kind": "ladder", "id": "rcz-0-0-ladder-1" } diff --git a/art/zones/rusty-creek/collision/rcz-1-0.collision.json b/art/zones/rusty-creek/collision/rcz-1-0.collision.json index 69c3ca3..e0aa127 100644 --- a/art/zones/rusty-creek/collision/rcz-1-0.collision.json +++ b/art/zones/rusty-creek/collision/rcz-1-0.collision.json @@ -9,278 +9,16 @@ [ [ 0, - 60 - ], - [ - 48, - 60 - ], - [ - 80, - 59 - ], - [ - 96, - 59 - ], - [ - 144, - 59 - ] - ], - [ - [ - 0, - 648 - ], - [ - 24, - 647 - ], - [ - 48, - 647 - ], - [ - 72, - 646 - ], - [ - 96, - 646 - ], - [ - 144, - 646 - ], - [ - 192, - 646 - ], - [ - 240, - 648 - ], - [ - 248, - 650 - ], - [ - 256, - 652 - ], - [ - 264, - 655 - ], - [ - 272, 657 ], - [ - 280, - 659 - ], - [ - 288, - 659 - ], - [ - 336, - 659 - ], - [ - 384, - 659 - ], - [ - 432, - 659 - ], - [ - 480, - 659 - ], - [ - 528, - 659 - ], - [ - 576, - 659 - ], - [ - 624, - 659 - ], - [ - 672, - 660 - ], [ 680, - 661 + 657 ] ], [ [ 164, - 333 - ], - [ - 180, - 332 - ], - [ - 204, - 331 - ], - [ - 212, - 331 - ], - [ - 260, - 331 - ], - [ - 308, - 331 - ], - [ - 356, - 331 - ], - [ - 404, - 331 - ], - [ - 452, - 331 - ], - [ - 500, - 331 - ], - [ - 548, - 331 - ], - [ - 596, - 331 - ], - [ - 644, - 331 - ], - [ - 692, - 331 - ], - [ - 740, - 331 - ], - [ - 788, - 331 - ], - [ - 836, - 331 - ], - [ - 884, - 331 - ], - [ - 932, - 331 - ], - [ - 980, - 331 - ], - [ - 1028, - 331 - ], - [ - 1076, - 331 - ], - [ - 1124, - 331 - ], - [ - 1172, - 331 - ], - [ - 1220, - 331 - ], - [ - 1268, - 331 - ], - [ - 1316, - 331 - ], - [ - 1364, - 331 - ], - [ - 1412, - 331 - ], - [ - 1460, - 331 - ], - [ - 1508, - 331 - ], - [ - 1556, - 331 - ], - [ - 1604, - 331 - ], - [ - 1652, - 331 - ], - [ - 1700, - 331 - ], - [ - 1724, - 332 - ], - [ - 1748, - 332 - ], - [ - 1796, - 332 - ], - [ - 1828, - 331 - ], - [ - 1844, 331 ], [ @@ -288,425 +26,19 @@ 331 ] ], - [ - [ - 264, - 0 - ], - [ - 312, - 0 - ], - [ - 360, - 0 - ], - [ - 408, - 0 - ], - [ - 456, - 0 - ], - [ - 504, - 0 - ], - [ - 552, - 0 - ], - [ - 600, - 0 - ], - [ - 648, - 0 - ], - [ - 696, - 0 - ], - [ - 744, - 0 - ], - [ - 792, - 0 - ], - [ - 840, - 0 - ], - [ - 888, - 0 - ], - [ - 936, - 0 - ], - [ - 984, - 0 - ], - [ - 1032, - 0 - ], - [ - 1080, - 0 - ], - [ - 1128, - 0 - ], - [ - 1176, - 0 - ], - [ - 1224, - 0 - ], - [ - 1272, - 0 - ], - [ - 1320, - 0 - ], - [ - 1368, - 0 - ], - [ - 1416, - 0 - ], - [ - 1464, - 0 - ], - [ - 1512, - 0 - ], - [ - 1560, - 0 - ], - [ - 1608, - 0 - ], - [ - 1656, - 0 - ], - [ - 1704, - 0 - ], - [ - 1752, - 0 - ], - [ - 1800, - 0 - ], - [ - 1848, - 0 - ], - [ - 1896, - 0 - ], - [ - 1944, - 0 - ], - [ - 1992, - 0 - ], - [ - 2040, - 0 - ], - [ - 2088, - 0 - ], - [ - 2136, - 0 - ], - [ - 2160, - 0 - ] - ], - [ - [ - 264, - 163 - ], - [ - 312, - 163 - ], - [ - 360, - 163 - ], - [ - 408, - 163 - ], - [ - 432, - 162 - ], - [ - 456, - 162 - ], - [ - 504, - 162 - ], - [ - 520, - 161 - ], - [ - 544, - 160 - ], - [ - 552, - 160 - ], - [ - 600, - 160 - ], - [ - 648, - 160 - ], - [ - 696, - 160 - ], - [ - 744, - 160 - ], - [ - 760, - 161 - ], - [ - 768, - 162 - ], - [ - 776, - 162 - ] - ], [ [ 868, 536 ], - [ - 916, - 536 - ], - [ - 964, - 536 - ], - [ - 1012, - 536 - ], - [ - 1060, - 536 - ], - [ - 1108, - 536 - ], - [ - 1156, - 536 - ], - [ - 1204, - 536 - ], - [ - 1252, - 536 - ], - [ - 1300, - 536 - ], - [ - 1348, - 536 - ], - [ - 1396, - 536 - ], - [ - 1444, - 536 - ], - [ - 1492, - 536 - ], - [ - 1540, - 536 - ], - [ - 1588, - 536 - ], [ 1612, 536 ] ], - [ - [ - 968, - 186 - ], - [ - 984, - 185 - ], - [ - 1008, - 184 - ], - [ - 1016, - 184 - ], - [ - 1064, - 184 - ], - [ - 1112, - 184 - ], - [ - 1160, - 184 - ], - [ - 1208, - 184 - ], - [ - 1256, - 184 - ], - [ - 1304, - 184 - ], - [ - 1352, - 184 - ], - [ - 1400, - 184 - ], - [ - 1448, - 184 - ], - [ - 1496, - 184 - ], - [ - 1544, - 184 - ], - [ - 1592, - 184 - ], - [ - 1640, - 184 - ], - [ - 1688, - 184 - ], - [ - 1736, - 184 - ], - [ - 1784, - 184 - ], - [ - 1832, - 184 - ], - [ - 1840, - 185 - ] - ], [ [ 1628, - 659 - ], - [ - 1644, - 658 - ], - [ - 1668, - 657 - ], - [ - 1676, - 657 - ], - [ - 1700, - 658 - ], - [ - 1724, 658 ], [ @@ -719,10 +51,6 @@ 2084, 658 ], - [ - 2132, - 658 - ], [ 2160, 658 @@ -733,30 +61,6 @@ 1736, 605 ], - [ - 1784, - 605 - ], - [ - 1832, - 605 - ], - [ - 1880, - 605 - ], - [ - 1928, - 605 - ], - [ - 1976, - 605 - ], - [ - 2024, - 605 - ], [ 2084, 605 @@ -767,26 +71,6 @@ 1912, 378 ], - [ - 1960, - 378 - ], - [ - 2008, - 378 - ], - [ - 2056, - 378 - ], - [ - 2104, - 378 - ], - [ - 2152, - 378 - ], [ 2160, 378 @@ -798,9 +82,9 @@ "climb": [ { "x": 1878, - "y": 22, + "y": 605, "w": 19, - "h": 698, + "h": 115, "kind": "ladder", "id": "rcz-1-0-ladder-0" } diff --git a/art/zones/rusty-creek/collision/rcz-1-2.collision.json b/art/zones/rusty-creek/collision/rcz-1-2.collision.json index ff80072..9fc48dd 100644 --- a/art/zones/rusty-creek/collision/rcz-1-2.collision.json +++ b/art/zones/rusty-creek/collision/rcz-1-2.collision.json @@ -27,24 +27,7 @@ ], "slide": [], "oneWay": [], - "climb": [ - { - "x": 896, - "y": 0, - "w": 18, - "h": 216, - "kind": "ladder", - "id": "rcz-1-2-ladder-4" - }, - { - "x": 1249, - "y": 0, - "w": 18, - "h": 217, - "kind": "ladder", - "id": "rcz-1-2-ladder-5" - } - ], + "climb": [], "solid": [], "noGo": [ { diff --git a/art/zones/rusty-creek/collision/rcz-2-0.collision.json b/art/zones/rusty-creek/collision/rcz-2-0.collision.json index d1ab40d..c0a86ba 100644 --- a/art/zones/rusty-creek/collision/rcz-2-0.collision.json +++ b/art/zones/rusty-creek/collision/rcz-2-0.collision.json @@ -9,40 +9,6 @@ [ [ 0, - 0 - ], - [ - 48, - 0 - ], - [ - 96, - 0 - ], - [ - 144, - 0 - ], - [ - 192, - 0 - ], - [ - 228, - 0 - ] - ], - [ - [ - 0, - 378 - ], - [ - 48, - 378 - ], - [ - 96, 378 ], [ @@ -53,578 +19,42 @@ [ [ 120, - 550 - ], - [ - 128, - 544 - ], - [ - 136, - 539 - ], - [ - 144, - 534 - ], - [ - 152, - 528 - ], - [ - 160, 522 ], - [ - 168, - 517 - ], - [ - 216, - 517 - ], - [ - 224, - 518 - ], - [ - 248, - 519 - ], - [ - 256, - 520 - ], - [ - 264, - 520 - ], [ 272, - 526 - ] - ], - [ - [ - 228, - 66 - ], - [ - 276, - 66 - ], - [ - 324, - 66 - ], - [ - 372, - 66 - ], - [ - 420, - 66 - ], - [ - 448, - 66 - ] - ], - [ - [ - 644, - 66 - ], - [ - 692, - 66 - ], - [ - 740, - 66 - ], - [ - 788, - 66 - ], - [ - 836, - 66 - ], - [ - 884, - 66 - ], - [ - 932, - 66 - ], - [ - 980, - 66 - ], - [ - 1028, - 66 - ], - [ - 1076, - 66 + 522 ] ], [ [ 168, - 302 - ], - [ - 216, - 302 - ], - [ - 248, - 303 - ], - [ - 264, - 303 - ], - [ - 312, - 303 - ], - [ - 360, - 303 - ], - [ - 408, - 303 - ], - [ - 456, 303 ], - [ - 504, - 303 - ], - [ - 552, - 303 - ], - [ - 576, - 302 - ], - [ - 600, - 302 - ], [ 632, - 302 - ] - ], - [ - [ - 448, - 0 - ], - [ - 496, - 0 - ], - [ - 544, - 0 - ], - [ - 592, - 0 - ], - [ - 644, - 0 + 303 ] ], [ [ 696, - 371 - ], - [ - 704, - 372 - ], - [ - 728, - 373 - ], - [ - 736, - 374 - ], - [ - 744, - 374 - ], - [ - 752, - 375 - ], - [ - 768, - 376 - ], - [ - 776, - 377 - ], - [ - 792, - 378 - ], - [ - 840, - 378 - ], - [ - 888, - 378 - ], - [ - 936, - 378 - ], - [ - 984, - 378 - ], - [ - 1032, - 378 - ], - [ - 1040, - 377 - ], - [ - 1056, 376 ], - [ - 1064, - 375 - ], [ 1080, - 374 - ] - ], - [ - [ - 1076, - 0 - ], - [ - 1124, - 0 - ], - [ - 1172, - 0 - ], - [ - 1180, - 7 - ], - [ - 1188, - 14 - ], - [ - 1196, - 20 - ], - [ - 1204, - 27 - ], - [ - 1212, - 34 - ], - [ - 1220, - 41 - ], - [ - 1228, - 45 - ], - [ - 1236, - 49 - ], - [ - 1244, - 54 - ], - [ - 1252, - 58 - ], - [ - 1260, - 62 - ], - [ - 1268, - 66 - ], - [ - 1316, - 66 - ], - [ - 1364, - 66 - ], - [ - 1392, - 66 - ] - ], - [ - [ - 1392, - 0 - ], - [ - 1440, - 0 - ], - [ - 1488, - 0 - ], - [ - 1536, - 0 - ], - [ - 1584, - 0 - ], - [ - 1632, - 0 - ], - [ - 1640, - 0 + 376 ] ], [ [ 1420, - 444 - ], - [ - 1436, - 445 - ], - [ - 1460, - 446 - ], - [ - 1468, - 446 - ], - [ - 1484, - 447 - ], - [ - 1508, - 448 - ], - [ - 1516, - 448 - ], - [ - 1532, - 449 - ], - [ - 1556, - 450 - ], - [ - 1564, - 450 - ], - [ - 1580, - 451 - ], - [ - 1604, - 452 - ], - [ - 1612, - 452 - ], - [ - 1660, - 452 - ], - [ - 1708, - 452 - ], - [ - 1756, - 452 - ], - [ - 1804, - 452 - ], - [ - 1852, - 452 - ], - [ - 1900, - 452 - ], - [ - 1948, - 452 - ], - [ - 1956, - 451 - ], - [ - 1964, - 450 - ], - [ - 1972, - 448 - ], - [ - 1980, - 447 - ], - [ - 1988, - 446 - ], - [ - 1996, - 445 - ], - [ - 2004, - 446 - ], - [ - 2020, - 447 - ], - [ - 2028, - 448 - ], - [ - 2044, - 449 - ], - [ - 2052, - 450 - ], - [ - 2068, - 451 - ], - [ - 2076, - 452 - ], - [ - 2092, - 453 - ], - [ - 2108, - 452 - ], - [ - 2132, - 451 - ], - [ - 2140, - 451 - ], - [ - 2156, 450 ], [ 2160, 450 ] - ], - [ - [ - 1652, - 90 - ], - [ - 1700, - 90 - ], - [ - 1748, - 90 - ], - [ - 1796, - 90 - ], - [ - 1844, - 90 - ], - [ - 1892, - 90 - ], - [ - 1940, - 90 - ], - [ - 1988, - 90 - ], - [ - 2036, - 90 - ], - [ - 2084, - 90 - ] ] ], "slide": [], @@ -632,11 +62,19 @@ "climb": [ { "x": 708, - "y": 65, + "y": 376, "w": 34, - "h": 655, + "h": 344, "kind": "ladder", "id": "rcz-2-0-ladder-1" + }, + { + "x": 2008, + "y": 450, + "w": 33, + "h": 270, + "kind": "ladder", + "id": "rcz-2-0-ladder-4" } ], "solid": [], diff --git a/art/zones/rusty-creek/collision/rcz-2-2.collision.json b/art/zones/rusty-creek/collision/rcz-2-2.collision.json index 2775c7e..f88b261 100644 --- a/art/zones/rusty-creek/collision/rcz-2-2.collision.json +++ b/art/zones/rusty-creek/collision/rcz-2-2.collision.json @@ -571,10 +571,6 @@ 2148, 235 ], - [ - 2156, - 234 - ], [ 2160, 233 diff --git a/art/zones/rusty-creek/masks/rcz-0-0.00-sky.png b/art/zones/rusty-creek/masks/rcz-0-0.00-sky.png deleted file mode 100644 index ac6a675..0000000 Binary files a/art/zones/rusty-creek/masks/rcz-0-0.00-sky.png and /dev/null differ diff --git a/art/zones/rusty-creek/masks/rcz-0-1.00-sky.png b/art/zones/rusty-creek/masks/rcz-0-1.00-sky.png deleted file mode 100644 index da877b8..0000000 Binary files a/art/zones/rusty-creek/masks/rcz-0-1.00-sky.png and /dev/null differ diff --git a/art/zones/rusty-creek/masks/rcz-1-0.00-sky.png b/art/zones/rusty-creek/masks/rcz-1-0.00-sky.png deleted file mode 100644 index e33a85e..0000000 Binary files a/art/zones/rusty-creek/masks/rcz-1-0.00-sky.png and /dev/null differ diff --git a/art/zones/rusty-creek/masks/rcz-1-1.00-sky.png b/art/zones/rusty-creek/masks/rcz-1-1.00-sky.png deleted file mode 100644 index d0f3c54..0000000 Binary files a/art/zones/rusty-creek/masks/rcz-1-1.00-sky.png and /dev/null differ diff --git a/art/zones/rusty-creek/masks/rcz-2-0.00-sky.png b/art/zones/rusty-creek/masks/rcz-2-0.00-sky.png deleted file mode 100644 index 2b1ec29..0000000 Binary files a/art/zones/rusty-creek/masks/rcz-2-0.00-sky.png and /dev/null differ diff --git a/art/zones/rusty-creek/masks/rcz-2-1.00-sky.png b/art/zones/rusty-creek/masks/rcz-2-1.00-sky.png deleted file mode 100644 index c0b0bf4..0000000 Binary files a/art/zones/rusty-creek/masks/rcz-2-1.00-sky.png and /dev/null differ diff --git a/docs/01-PROPOSAL.md b/docs/01-PROPOSAL.md index c5003ae..153e256 100644 --- a/docs/01-PROPOSAL.md +++ b/docs/01-PROPOSAL.md @@ -4,7 +4,7 @@ [← Design documents](README.md) · [Design docs](README.md) · **1 / 16** · [02 – Game design →](02-GAME-DESIGN.md) -![Rusty Creek – our first stage, current art](../art/stages/rusty-creek/images/after-center.png) +![Rusty Creek – our first stage, current art](../art/stages/rusty-creek/prototype/after-center.png) > **A familiar campus. A plush mascot that wants you to keep fighting. A quantum experiment that broke the pond.** diff --git a/docs/04-WORLD-AND-LEVELS.md b/docs/04-WORLD-AND-LEVELS.md index 680c9d4..512322d 100644 --- a/docs/04-WORLD-AND-LEVELS.md +++ b/docs/04-WORLD-AND-LEVELS.md @@ -27,7 +27,7 @@ The stepping-stone creek and the Playground slides are connectors between anomal | Clean Rusty Creek | Anomaly Rusty Creek | | --- | --- | -| ![Clean](../art/stages/rusty-creek/images/before-center.png) | ![Anomaly](../art/stages/rusty-creek/images/after-center.png) | +| ![Clean](../art/stages/rusty-creek/prototype/before-center.png) | ![Anomaly](../art/stages/rusty-creek/prototype/after-center.png) | All seven pairs as concepts: **[stage concepts](../art/locations/README.md)**. Both states share the camera, layout and landmarks, so the anomaly can swap layers (as in Rusty Creek, where only the structure layers change) instead of redrawing the world. @@ -127,21 +127,21 @@ Export: `art/stages//..collision.json` – polylines, poin ## Rusty Creek – the jam level -![Rusty Creek – full route, three chunks](../art/stages/rusty-creek/images/after-left.png) +![Rusty Creek – the zone, 3 × 3 chunks](../art/zones/rusty-creek/previews/grown.png) -The route already exists as a graph ([route.json](../art/stages/rusty-creek/route.json): 47 nodes, 47 edges, verified connected). The beats on it: +Since 26 Oct the level is a 3 × 3 zone grown from one cut of its stacked concept ([#157](https://github.com/THD-AI/WinCS/issues/157), [stage README](../art/stages/rusty-creek/README.md)): the rust maze above (`rc-x-0`), the creek path under the railway girder (`rc-x-1`), the drains below (`rc-x-2`). The rows are rooms joined by ladders (pier ladders up to the girder's deck, maze ladders on up) and by the culvert's door down into the drains. The beats, on the anomaly's floors (`rusty_creek_zone.py` `ANOMALY`): | Chunk | Beat | Content | | --- | --- | --- | -| Left – *entry, first climb* | Land from the pond crash. Quiet. | The **chair** lies on the first deck. One **rover** patrols the low deck (tutorial fight). Ladder up to the first branch. Optional lookout dead end: muffin + note #1 | -| Center – *branches, reconnection* | The maze opens up | Two routes: high (ladders, a **crab** on a deck) and low (along the creek, two rovers). A **drone** hovers over the low route: too hard to kill with the chair, so avoid it under girders. **Coffee machine** + **Dexter** (pocket computer) at the reconnection. Cache dead end: Leberkäse roll | -| Right – *boss clearing, exit* | Wide open girder floor | Boss gate closes behind you. **Jenny**. After the fight, Dexter absorbs the black fluid and the exit anomaly opens. Overlook dead end: note #2 (first hint about Dexter) | +| `rc-0-1` – *entry* | Land from the ram. Quiet. | The **chair** on the path, two **rovers** along it, a pier ladder up to the girder's deck: note #1. Up into the maze (`rc-0-0`): a rover on its girders, a muffin | +| `rc-1-1` – *the creek* | Along the water | Two rovers on the path, the **drone** over it. **Coffee machine** + **Dexter** (pocket computer). On the deck: Leberkäse roll. Above, in the maze (`rc-1-0`): the **crab** on a girder | +| `rc-2-1` – *the arena* | The path under the girder | The culvert's door down into the drains (`rc-2-2`: a rover, note #2). Boss gate closes behind you, **Jenny** on her floor with two chained platforms; past her the exit | Target play time for the slice: 8–12 minutes. -### Rebuild plan ([#157](https://github.com/THD-AI/WinCS/issues/157)) +### Rebuild plan ([#157](https://github.com/THD-AI/WinCS/issues/157)) – built 26 Oct as the 3 × 3 zone above -The three chunks above were the proof of concept for map generation, made before the location concepts, the direction pack and the Hidden Garden's pipeline. The rebuild re-derives Region 1 from the sources and grows it the way the garden was grown. It also fixes the slice's length: with three chunks, a player who runs straight through finishes the whole slice in about 5 minutes. The target is 8–12. +The one-row stage (`rc-0-0` … `rc-2-0`, before 26 Oct) was the proof of concept for map generation, made before the location concepts, the direction pack and the Hidden Garden's pipeline. The rebuild re-derives Region 1 from the sources and grows it the way the garden was grown. It also fixes the slice's length: with three chunks, a player who runs straight through finishes the whole slice in about 5 minutes. The target is 8–12. **Sources:** the style master ("Rusty Creek, first light": blue-green riveted rusty girders, ladders, autumn trees, the creek, a rusty railing in front), the location concept in `art/locations/`, the creek, rail and steel-bridge photos (`media-sources.json`), and the [anomaly language](../art/direction/anomaly-language.md) (cuts, stretched rows, 404 holes, crash dialogs). diff --git a/docs/09-ART-PIPELINE.md b/docs/09-ART-PIPELINE.md index 31dbba8..e839b12 100644 --- a/docs/09-ART-PIPELINE.md +++ b/docs/09-ART-PIPELINE.md @@ -4,7 +4,7 @@ [← 08 – Tech stack and where things live](08-TECH-STACK.md) · [Design docs](README.md) · **9 / 16** · [10 – Jam plan →](10-JAM-PLAN.md) -![Rusty Creek – seven registered layers composed](../art/stages/rusty-creek/images/after-center.png) +![Rusty Creek – seven registered layers composed](../art/stages/rusty-creek/prototype/after-center.png) One rule above everything: **every image comes from real references through a rerunnable script and a config.** No hand-saved images from a chat window, and no text-only prompts. The configs live next to their outputs (`art/**/*.json`), and every image has a Markdown page with its brief, inputs and review. @@ -106,6 +106,7 @@ What the proof taught (rules now): - **Up and down** with `world_paint.py grow`, then joins. An up/down join may move what it should keep: with 110 rows each side it shifted the railway girder to a different height in each chunk (the gate's seam check did not see it). `join … --only up-down --half 150,44` stops the window 44 rows into the lower chunk, above the girder. Where the model still left the maze's posts and the tree line hanging over a strip of sky, they were carried down to the flange column by column with their own pixels. - **Collision:** the level row is measured (path, girder deck, pier ladders, the culvert door over the drain door); the bands above and below are traced from their depth keys. A traced climb is a ladder only where both ends meet a floor (pillars and pipes key like rungs). Where pillars stand in front of a deck, the tracer breaks it: those floors are measured (`MEASURED`). A dead end got a painted steel stair, so the drains can be walked back. Underground, the flooded bottom is no-go. - **The kept maze:** the band above came out denser than its map's two beams; Alexander kept it, so its blockout is redrawn from its traced floors and ladders and the gate's route check measures against what is walked. Its repeat check fails on riveted girder flanges – real rivet pitch – and is waived in `zone.json` `"gate"` with that reason (`world_gate.py` prints WAIVED, keeps the value). + - **Into the game (26 Oct, Alexander: replace the creek stage now):** `rusty_creek_zone.py --stage` writes the zone as `art/stages/rusty-creek` (`rc-x-y` = the zone's grid; the stage holds the one committed copy of the paintings and masks, the zone's working copies come back from it). Both states share the art; the anomaly adds the 404 tears and the rust maze's fight, carried over from the one-row stage onto the zone's floors (`CLEAN`, `ANOMALY`), with Jenny's arena on the right-hand level chunk and its platforms on chains from the railway girder. A maze ladder that reaches its chunk's bottom goes on down to the girder's deck; `collision_check.py` takes a ladder off a chunk's top or bottom edge as a way in. Every layer scrolls with the path for now. The back layers are whole: the sky painted behind everything (`depth_layers.py fill --only sky`), the drains' walls down to the waterline (`whole`, then `--fills`). The old one-row stage's pipeline (`creek_layers.py`) is retired; its paintings that other boards still use are in `art/stages/rusty-creek/prototype/`. - **Played, the underground has to read (Alexander's playtest, 25 Oct):** the cellar's door was a purple box beside its painted door, a ladder ran up into the ceiling girder, the upper floor had a gap under a pillar, the hero walked in front of the steel pillars and off the row's open end, the prologue's guide followed him down and walked in the air, and nothing moved. The fixes are rules now: - **What the trace gets wrong is measured** (`hidden_garden_proof.py` `MEASURED`): a floor that runs behind pillars is one floor; a ladder runs between the floors it joins, never past them; a door's box is on its painted door (a door pair is joined by id, not by x). - **Columns the hero passes are in front of him:** `06-pillars` (z 6 like `06-near`, but still – the near strip sways), a measured mask per chunk (`PILLARS`), drawn over the actors. diff --git a/game/src/combat/coffee.test.ts b/game/src/combat/coffee.test.ts index 4bd0b5f..f73cab4 100644 --- a/game/src/combat/coffee.test.ts +++ b/game/src/combat/coffee.test.ts @@ -3,19 +3,19 @@ import { CoffeeUse, coffeeFrame } from './coffee'; import { Life } from './life'; import { parseCollision, placeCollision } from '../stage/collision'; import type { Body } from '../player/body'; -import raw from '../../../art/stages/rusty-creek/rc-1-0.anomaly.collision.json'; +import raw from '../../../art/stages/rusty-creek/rc-1-1.anomaly.collision.json'; import clips from '../../public/assets/sprites/hero-hurt.anims.json'; -const chunk = placeCollision(parseCollision(raw, 'rc-1-0', 'anomaly'), [2160, 0]); +const chunk = placeCollision(parseCollision(raw, 'rc-1-1', 'anomaly'), [2160, 720]); const machines = chunk.world.interact; -const body = (): Body => ({ x: 3950, y: 537, vx: 0, vy: 0, grounded: true }); +const body = (): Body => ({ x: 3950, y: 1242, vx: 0, vy: 0, grounded: true }); describe('coffee save interaction', () => { it('glows steadily, flickers one frame every two seconds, and every fourth flicker shows the pond', () => { expect(coffeeFrame(0, 12)).toBe(1); expect(coffeeFrame(84, 12)).toBe(0); expect(coffeeFrame(1999, 12)).toBe(0); expect(coffeeFrame(2000, 12)).toBe(1); expect(coffeeFrame(4000, 12)).toBe(1); expect(coffeeFrame(6000, 12)).toBe(2); }); it('uses the authored 40×80 machine at the translated walk surface and the approved drink timing', () => { - expect(machines.find(box => box.kind === 'coffee-machine')).toMatchObject({ id: 'coffee-1', x: 3930, y: 457, w: 40, h: 80 }); + expect(machines.find(box => box.kind === 'coffee-machine')).toMatchObject({ id: 'coffee-1', x: 3930, y: 1162, w: 40, h: 80 }); expect(clips.interact).toEqual({ frames: 3, fps: 12, loop: false }); expect(clips.interact.frames / clips.interact.fps).toBe(0.25); expect(new CoffeeUse().step(true, body(), true, machines)?.id).toBe('coffee-1'); @@ -47,6 +47,6 @@ describe('coffee save interaction', () => { expect(machine?.id).toBe('coffee-1'); expect(life.save(player)).toBe(true); expect(life.health).toBe(5); player.x += 200; expect(life.hit(5)).toBe(true); expect(life.tick(1).respawned).toBe(true); - expect(life.checkpoint).toEqual({ x: 3950, y: 537 }); expect(life.health).toBe(5); + expect(life.checkpoint).toEqual({ x: 3950, y: 1242 }); expect(life.health).toBe(5); }); }); diff --git a/game/src/combat/overhead.test.ts b/game/src/combat/overhead.test.ts index 3f03dad..3a4d3e0 100644 --- a/game/src/combat/overhead.test.ts +++ b/game/src/combat/overhead.test.ts @@ -4,7 +4,8 @@ import { Rover } from '../enemies/rover'; import { pogo, jump } from '../player/jump'; import { stepBody, type Body } from '../player/body'; import type { Damageable } from './sweeps'; -import raw from '../../../art/stages/rusty-creek/rc-1-0.anomaly.collision.json'; +import raw from '../../../art/stages/rusty-creek/rc-1-1.anomaly.collision.json'; +import maze from '../../../art/stages/rusty-creek/rc-1-0.anomaly.collision.json'; import clips from '../../public/assets/sprites/chair-overhead.anims.json'; describe('measured overhead chair attacks', () => { @@ -20,9 +21,9 @@ describe('measured overhead chair attacks', () => { attack.begin('up', -1); attack.step(2 / 12); expect(attack.box(feet, 500)).toEqual({ x: 36, y: 319, w: 68, h: 93 }); }); - it('reaches the Rusty Creek drone at its hover height from the ground and from the deck under it', () => { + it('reaches the Rusty Creek drone at its hover height from the creek path under it', () => { const drone = raw.spawn.find(spawn => spawn.kind === 'drone')!; - for (const floor of [536, 570]) { + for (const floor of raw.walk.filter(line => line[0][1] > drone.y).map(line => line[0][1])) { const attack = new Overhead(); let hits = 0; const target: Damageable = { id: drone.id, bounds: () => ({ x: drone.x - 22.5, y: drone.y - 45, w: 45, h: 45 }), hit: () => { hits++; return true; } }; @@ -30,9 +31,9 @@ describe('measured overhead chair attacks', () => { attack.contact({ x: drone.x - 20, y: floor }, floor, [target]); expect(hits).toBe(1); } }); - it('hits a 40px crab fixture at its authored one-way deck from below only once', () => { - const crab = raw.spawn.find(spawn => spawn.kind === 'crab')!; - expect(raw.oneWay.some(line => line.some(point => point[1] === crab.y))).toBe(true); + it('hits a 40px crab fixture on its rust-maze girder from below only once', () => { + const crab = maze.spawn.find(spawn => spawn.kind === 'crab')!; + expect(maze.walk.some(line => line.some(point => point[1] === crab.y))).toBe(true); let hits = 0; const target: Damageable = { id: crab.id, bounds: () => ({ x: crab.x - 20, y: crab.y - 40, w: 40, h: 40 }), hit: hit => { expect(hit.kind).toBe('up'); hits++; return true; } }; diff --git a/game/src/enemies/arena.test.ts b/game/src/enemies/arena.test.ts index 4b80e0b..27c8f4a 100644 --- a/game/src/enemies/arena.test.ts +++ b/game/src/enemies/arena.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; import { JENNY_BOX } from './jenny'; import { GRAVITY, JUMP_SPEED } from '../player/jump'; -import arena from '../../../art/stages/rusty-creek/rc-2-0.anomaly.collision.json'; +import arena from '../../../art/stages/rusty-creek/rc-2-1.anomaly.collision.json'; /** The platforms (arena-platform board, scripts/arena_platforms.py): girders this thick, hung on chains. */ const BEAM = 25; diff --git a/game/src/enemies/rover.test.ts b/game/src/enemies/rover.test.ts index f1ca939..1baeb1e 100644 --- a/game/src/enemies/rover.test.ts +++ b/game/src/enemies/rover.test.ts @@ -3,10 +3,12 @@ import { Rover, CHARGE_SPEED, PATROL_SPEED, ROVER_WIDTH, ROVER_HEIGHT } from './ import { parseCollision, placeCollision } from '../stage/collision'; import type { Damageable } from '../combat/sweeps'; import { Sweeps, intersects } from '../combat/sweeps'; -import raw from '../../../art/stages/rusty-creek/rc-0-0.anomaly.collision.json'; +import raw from '../../../art/stages/rusty-creek/rc-0-1.anomaly.collision.json'; +// The first rover on the creek path (rc-0-1, at x 900 on the path's y 522, patrolling 780-1020), placed 140 px left +// and 14 px up so it stands where the old stage's tutorial rover stood: (760, 508), patrolling 640-880. const tutorial = () => { - const spawn = placeCollision(parseCollision(raw, 'rc-0-0', 'anomaly'), [0, 0]).world.spawn.find(point => point.kind === 'rover')!; + const spawn = placeCollision(parseCollision(raw, 'rc-0-1', 'anomaly'), [-140, -14]).world.spawn.find(point => point.id === 'rover-1')!; return new Rover({ x: spawn.x, y: spawn.y }, spawn.patrol as [number, number]); }; describe('autonomous rover', () => { diff --git a/game/src/fx/AnomalyTest.ts b/game/src/fx/AnomalyTest.ts index d8fe645..5e83052 100644 --- a/game/src/fx/AnomalyTest.ts +++ b/game/src/fx/AnomalyTest.ts @@ -3,12 +3,12 @@ import { add404Void, addImageCut, addPixelStretch } from './anomaly'; const BASE = 'assets/stages/rusty-creek/'; const LAYERS = [ - { key: 'rc-test-distance', file: '01-distance-left.png', scroll: 0.2 }, - { key: 'rc-test-traversal', file: '05-traversal-left.png', scroll: 1 }, + { key: 'rc-test-distance', file: 'rc-0-1.01-far.png', scroll: 1 }, + { key: 'rc-test-traversal', file: 'rc-0-1.05-play.png', scroll: 1 }, ]; /** - * Dev only (#37 verification): the first Rusty Creek chunk with each anomaly effect on it. + * Dev only (#37 verification): the creek path's first chunk (rc-0-1) with each anomaly effect on it. * F9 opens it from the HUD; V shows and hides the effects; arrows pan; Esc closes. */ export class AnomalyTest extends Phaser.Scene { diff --git a/game/src/fx/AtmosphereTest.ts b/game/src/fx/AtmosphereTest.ts index 13cf4db..37b551e 100644 --- a/game/src/fx/AtmosphereTest.ts +++ b/game/src/fx/AtmosphereTest.ts @@ -3,19 +3,19 @@ import { addLeaves, addReflection, blurForeground } from './atmosphere'; import { StageState } from './atmosphereLayout'; const BASE = 'assets/stages/rusty-creek/'; -/** rc-0-0 in draw order (stage.json), with each layer's scroll factor. */ +/** rc-0-1 (the creek path's first chunk) in draw order (stage.json), with each layer's scroll factor. */ const LAYERS = [ - { id: '01-distance', scroll: 0.2 }, - { id: '03-bank', scroll: 1 }, - { id: '02-supports', scroll: 1 }, + { id: '00-sky', scroll: 1 }, + { id: '01-far', scroll: 1 }, + { id: '02-mid', scroll: 1 }, + { id: '03-rear', scroll: 1 }, { id: '04-water', scroll: 1 }, - { id: '05-traversal', scroll: 1 }, - { id: '06-near-rails', scroll: 1.1 }, - { id: '07-foliage', scroll: 1.15 }, + { id: '05-play', scroll: 1 }, + { id: '07-foreground', scroll: 1 }, ]; /** - * Dev only (#36 verification): the first Rusty Creek chunk with the blur, leaves and reflection. + * Dev only (#36 verification): the creek path's first chunk with the blur, leaves and reflection. * F10 opens it from the HUD; V shows and hides the atmosphere; A switches clean / anomaly leaves; arrows pan; Esc closes. */ export class AtmosphereTest extends Phaser.Scene { @@ -25,15 +25,15 @@ export class AtmosphereTest extends Phaser.Scene { constructor() { super('AtmosphereTest'); } preload(): void { - for (const layer of LAYERS) this.load.image(`rc-test-${layer.id}`, `${BASE}${layer.id}-left.png`); + for (const layer of LAYERS) this.load.image(`rc-test-${layer.id}`, `${BASE}rc-0-1.${layer.id}.png`); } create(): void { const images = LAYERS.map((l, i) => this.add.image(0, 0, `rc-test-${l.id}`).setOrigin(0).setScrollFactor(l.scroll, 1).setDepth(i)); const byId = (id: string) => images[LAYERS.findIndex((l) => l.id === id)]; - const mirrored = images.filter((_, i) => LAYERS[i].id !== '04-water' && LAYERS[i].id !== '07-foliage'); + const mirrored = images.filter((_, i) => LAYERS[i].id !== '04-water' && LAYERS[i].id !== '07-foreground'); const reflection = addReflection(byId('04-water'), mirrored); - const foliage = byId('07-foliage'); + const foliage = byId('07-foreground'); let on = true; blurForeground(foliage); this.leaves = addLeaves(this, this.state); diff --git a/game/src/player/feel.test.ts b/game/src/player/feel.test.ts index 4452333..c59fa4d 100644 --- a/game/src/player/feel.test.ts +++ b/game/src/player/feel.test.ts @@ -33,9 +33,10 @@ describe('surfaces', () => { expect(map.at(8640 + 1200, 441).name).toBe('wood'); // pier }); it('matches states, falls back to the default and without a file to the stone-like fallback', () => { - const rc = new SurfaceMap(creek, grid(['rc-0-0', 'rc-1-0', 'rc-2-0']), 'anomaly'); - expect(rc.at(600, 508).name).toBe('stone'); expect(rc.at(600, 461).name).toBe('steel'); - expect(new SurfaceMap(creek, grid(['rc-0-0']), 'clean').at(600, 508).name).toBe('steel'); + // Rusty Creek's level row: the creek path is stone, the railway girder's deck above it steel; the maze is steel. + const rc = new SurfaceMap(creek, grid(['rc-0-1', 'rc-1-1', 'rc-2-1']), 'anomaly'); + expect(rc.at(600, 522).name).toBe('stone'); expect(rc.at(600, 62).name).toBe('steel'); + expect(new SurfaceMap(creek, grid(['rc-0-0']), 'clean').at(600, 524).name).toBe('steel'); expect(new SurfaceMap(null, grid(['x']), 'clean').at(0, 0)).toBe(FALLBACK); }); it('rejects unknown materials and covers deeper than the sink', () => { diff --git a/game/src/player/slopes.test.ts b/game/src/player/slopes.test.ts index 0fae5fc..1564fd7 100644 --- a/game/src/player/slopes.test.ts +++ b/game/src/player/slopes.test.ts @@ -54,11 +54,14 @@ describe('continuous slope contacts', () => { }); it('crosses the real chunk seams in both states and directions without falling through', () => { const files = Object.values(import.meta.glob('../../../art/stages/rusty-creek/*.collision.json', { eager: true, import: 'default' })); + // Along the creek path (the level row, y 522), where the region is walked from chunk to chunk. + const path = (line: [number, number][]) => line[0][1] > 400; for (const state of ['clean', 'anomaly']) for (const column of [0, 1]) { - const left = files.find(f => f.chunk === `rc-${column}-0` && f.state === state)!; - const right = files.find(f => f.chunk === `rc-${column + 1}-0` && f.state === state)!; + const left = files.find(f => f.chunk === `rc-${column}-1` && f.state === state)!; + const right = files.find(f => f.chunk === `rc-${column + 1}-1` && f.state === state)!; const geometry = [placeCollision(left, [0, 0]).world, placeCollision(right, [2160, 0]).world]; - const leftY = left.walk.at(-1)!.at(-1)![1], rightY = right.walk[0][0][1]; + const leftY = left.walk.filter(path).find(l => l.at(-1)![0] === 2160)!.at(-1)![1]; + const rightY = right.walk.filter(path).find(l => l[0][0] === 0)![0][1]; for (const speed of [-258, -150.5, 150.5, 258]) { const b = body(speed > 0 ? 2155 : 2165, speed > 0 ? leftY : rightY, speed); for (let i = 0; i < 10; i++) { diff --git a/game/src/stage/collision.test.ts b/game/src/stage/collision.test.ts index 846821e..1ad4183 100644 --- a/game/src/stage/collision.test.ts +++ b/game/src/stage/collision.test.ts @@ -4,7 +4,7 @@ import type { StageManifest } from './manifest'; const fixtures = import.meta.glob('../../../art/stages/{rusty-creek,hidden-garden}/*.collision.json', { eager: true, import: 'default' }); -function fixture(chunk = 'rc-0-0', state: 'clean' | 'anomaly' = 'anomaly'): CollisionData { +function fixture(chunk = 'rc-0-1', state: 'clean' | 'anomaly' = 'anomaly'): CollisionData { const region = chunk.startsWith('hg-') ? 'hidden-garden' : 'rusty-creek'; const data = fixtures[`../../../art/stages/${region}/${chunk}.${state}.collision.json`]; if (!data) throw new Error(`Missing committed fixture ${chunk}.${state}`); @@ -12,47 +12,47 @@ function fixture(chunk = 'rc-0-0', state: 'clean' | 'anomaly' = 'anomaly'): Coll } it('reads every committed jam collision file without discarding encounter metadata', () => { - for (const state of ['clean', 'anomaly'] as const) for (let x = 0; x < 3; x++) { - const id = `rc-${x}-0`, raw = fixture(id, state); + for (const state of ['clean', 'anomaly'] as const) for (let x = 0; x < 3; x++) for (let y = 0; y < 3; y++) { + const id = `rc-${x}-${y}`, raw = fixture(id, state); expect(parseCollision(raw, id, state)).toEqual(raw); } const garden = fixture('hg-0-0', 'clean'); expect(parseCollision(garden, 'hg-0-0', 'clean')).toEqual(garden); - const creek = parseCollision(fixture(), 'rc-0-0', 'anomaly'); + const creek = parseCollision(fixture(), 'rc-0-1', 'anomaly'); expect(creek.interact.find(item => item.id === 'chair')?.item).toBe('chair'); }); it('places polylines, boxes, spawns and patrol bounds on a four-direction grid', () => { - const local = parseCollision(fixture(), 'rc-0-0', 'anomaly'), before = structuredClone(local); + const local = parseCollision(fixture(), 'rc-0-1', 'anomaly'), before = structuredClone(local); const { world } = placeCollision(local, [2160, -720]); - expect(world.walk[0][0]).toEqual([2160, -259]); - expect(world.spawn.find(p => p.id === 'rover-1')).toMatchObject({ x: 2920, y: -212, patrol: [2800, 3040] }); - expect(world.interact.find(p => p.id === 'chair')).toMatchObject({ x: 2476, y: -295, item: 'chair' }); + expect(world.walk[0][0]).toEqual([2160, -198]); + expect(world.spawn.find(p => p.id === 'rover-1')).toMatchObject({ x: 3060, y: -198, patrol: [2940, 3180] }); + expect(world.interact.find(p => p.id === 'chair')).toMatchObject({ x: 2680, y: -234, item: 'chair' }); expect(local).toEqual(before); }); it('rejects missing categories, wrong identities and non-integer/outside points', () => { - for (const change of [(d: CollisionData) => { delete (d as Partial).walk; }, (d: CollisionData) => { d.chunk = 'rc-2-0'; }, + for (const change of [(d: CollisionData) => { delete (d as Partial).walk; }, (d: CollisionData) => { d.chunk = 'rc-2-1'; }, (d: CollisionData) => { d.state = 'clean'; }, (d: CollisionData) => { d.spawn[0].x = 0.5; }, (d: CollisionData) => { d.walk[0][0][1] = 721; }]) { const raw = fixture(); change(raw); - expect(() => parseCollision(raw, 'rc-0-0', 'anomaly')).toThrow('Invalid collision'); + expect(() => parseCollision(raw, 'rc-0-1', 'anomaly')).toThrow('Invalid collision'); } }); it('rejects malformed lines, boxes, hazard damage and duplicate ids', () => { - for (const change of [(d: CollisionData) => { d.walk[0].reverse(); }, (d: CollisionData) => { d.solid[0].w = 0; }, + for (const change of [(d: CollisionData) => { d.walk[0].reverse(); }, (d: CollisionData) => { d.solid.push({ x: 0, y: 0, w: 0, h: 10 }); }, (d: CollisionData) => { d.climb[0].kind = ''; }, (d: CollisionData) => { d.spawn[0].id = d.climb[0].id; }, (d: CollisionData) => { d.hazard.push({ x: 1, y: 1, w: 10, h: 10, damage: 0 }); }]) { const raw = fixture(); change(raw); - expect(() => parseCollision(raw, 'rc-0-0', 'anomaly')).toThrow('Invalid collision'); + expect(() => parseCollision(raw, 'rc-0-1', 'anomaly')).toThrow('Invalid collision'); } }); it('retains reserved ledge and glide data without converting either to ground or walls', () => { const raw = fixture(); raw.ledge.push({ x: 200, y: 100 }); raw.glideLift.push({ x: 300, y: 200, w: 50, h: 100 }); - const { world } = placeCollision(parseCollision(raw, 'rc-0-0', 'anomaly'), [2160, 0]); + const { world } = placeCollision(parseCollision(raw, 'rc-0-1', 'anomaly'), [2160, 0]); expect(world.ledge).toEqual([{ x: 2360, y: 100 }]); expect(world.glideLift[0].x).toBe(2460); for (const key of LINES) expect(world[key]).toHaveLength(raw[key].length); diff --git a/game/src/ui/Hud.ts b/game/src/ui/Hud.ts index 624858b..c4bf7c5 100644 --- a/game/src/ui/Hud.ts +++ b/game/src/ui/Hud.ts @@ -52,8 +52,8 @@ export class Hud extends Phaser.Scene { if (event.shiftKey) return; pocketMap.unlock(); pocketMap.visit('hidden-garden', 'hg-0-0'); - pocketMap.visit('rusty-creek', 'rc-0-0'); - pocketMap.visit('rusty-creek', 'rc-1-0'); + pocketMap.visit('rusty-creek', 'rc-0-1'); + pocketMap.visit('rusty-creek', 'rc-1-1'); }); // Dev builds: F3 shows or hides Jenny's bar at 70 % (#54 will start it for real). if (import.meta.env.DEV) this.input.keyboard?.on('keydown-F3', () => { diff --git a/game/verification/creek/arena.png b/game/verification/creek/arena.png new file mode 100644 index 0000000..9649841 Binary files /dev/null and b/game/verification/creek/arena.png differ diff --git a/game/verification/creek/clean-path.png b/game/verification/creek/clean-path.png new file mode 100644 index 0000000..97e629e Binary files /dev/null and b/game/verification/creek/clean-path.png differ diff --git a/game/verification/creek/maze-tear.png b/game/verification/creek/maze-tear.png new file mode 100644 index 0000000..e77390a Binary files /dev/null and b/game/verification/creek/maze-tear.png differ diff --git a/references/campus/crossings.md b/references/campus/crossings.md index 26bb6a3..c6a0aee 100644 --- a/references/campus/crossings.md +++ b/references/campus/crossings.md @@ -6,7 +6,7 @@ **This board became [Rusty Creek](../../art/stages/rusty-creek/README.md)**, the first level: the creek, rails and riveted steel from these photos, rebuilt as a flat side view with a girder maze. -![Rusty Creek, the stage made from this board](../../art/stages/rusty-creek/images/before-center.png) +![Rusty Creek, the stage made from this board](../../art/stages/rusty-creek/prototype/before-center.png) **Latest direction, 23 October:** a recognizable creek/steel location redesigned as a **flat side-scroller**, not a perspective repaint. First a clean banner, then same-width extensions left/right and two staggered join views. Add the horizontal/vertical rusted-bar maze onto that accepted scene; derive five-plus depth/interaction roles afterwards. The algorithm/pathfinding villain seed guides the maze, while the collage's landmarks keep the place recognizable. **[See all banners and seven depth trials →](../../art/stages/rusty-creek/README.md)** @@ -25,7 +25,7 @@ The professor/degree connection is an owner-supplied **fictional villain premise Source photos C23–C27 show overhead riveted spans, mossy concrete, tubular rails, creek and ivy. Keep those identifying motifs in the newly designed side-on game layout. Do not copy the photographic vanishing point or substitute a generic fantasy maze. The approved board remains unchanged. The added traversal pass is visible below; routes, seams and mask cleanup still need review. -![The substantial riveted maze used for the girders](../../art/stages/rusty-creek/inputs/maze-center.png) +![The substantial riveted maze used for the girders](../../art/stages/rusty-creek/prototype/maze-center.png) The broad-platform, tall-shaft maze above is the traversal reference for the girders. How the stage is built: [09 – Art pipeline](../../docs/09-ART-PIPELINE.md). diff --git a/scripts/arena_platforms.py b/scripts/arena_platforms.py index 053494a..cc99dd4 100644 --- a/scripts/arena_platforms.py +++ b/scripts/arena_platforms.py @@ -1,15 +1,15 @@ -"""Jenny's arena platforms (playtest J6): two girder platforms hung on chains from the girder over her arena. +"""Jenny's arena platforms (playtest J6): two girder platforms hung on chains from the railway girder over her arena. - python scripts/arena_platforms.py # writes art/stages/rusty-creek/arena/right.png and the one-way lines + python scripts/arena_platforms.py # writes art/stages/rusty-creek/arena/rc-2-1.png The art is two sprite boards in the game's look (art/sprites boards.json): `arena-platform`, a short box girder in the maze's own material, and `arena-chain`, a rusted chain. Exported at game size (export_atlas.py, into tmp/), they -are composed into one overlay plate for the right chunk's anomaly state (export.json `05-arena`, "overlay"): -each platform at PLATFORMS, and a chain from each end of it straight up to the underside of the girder above, -measured from the traversal plate – so nothing floats. The same numbers write the platforms' one-way lines into -rc-2-0.anomaly.collision.json (any earlier lines over the arena floor are replaced). +are composed into one overlay plate for the right-hand level chunk's anomaly state (export.json `05-arena`, +"overlay"): each platform where the zone script puts it (rusty_creek_zone.PLATFORMS, which also writes their one-way +lines into rc-2-1.anomaly.collision.json), and a chain from each end of it straight up to the underside of the +railway girder above, measured from the chunk's play mask – so nothing floats. -Heights (arena.test.ts checks them): the tops 84–89 px over the walk line – a full jump is 96 px – and the bottoms +Heights (arena.test.ts checks them): the tops 87 px over the walk line – a full jump is 96 px – and the bottoms clear Jenny's 56 px body, so she drives under them. """ @@ -26,9 +26,10 @@ ROOT = Path(__file__).resolve().parents[1] REGION = ROOT / "art" / "stages" / "rusty-creek" ATLAS = ROOT / "tmp" / "arena-atlas" -PLATFORMS = [(1180, 476), (1430, 476)] # left edge, top (chunk px); 202 px wide +CHUNK = "rc-2-1" CHAIN_INSET = 18 # chain centre from each platform end (px) -ARENA = (1126, 1700) # the arena floor's x range: one-way lines in it are the platforms' +sys.path.insert(0, str(ROOT / "scripts" / "zones")) +from rusty_creek_zone import PLATFORMS # noqa: E402 left edge, top (chunk px); 202 px wide def frame(board: str, name: str) -> Image.Image: @@ -57,40 +58,43 @@ def chain_strip(chain: Image.Image, length: int) -> Image.Image: return strip -def underside(traversal: Image.Image, x: int, below: int) -> int: - """The lowest opaque row of the structure above `below` at column x: where the chain is fixed.""" - column = np.asarray(traversal.getchannel("A"))[:below, x] > 128 +def underside(play: np.ndarray, x: int, below: int) -> int: + """The underside of the railway girder at column x: the end of the first run of play rows from the top (the + girder), above `below` – where the chain is fixed.""" + column = play[:below, x] rows = np.nonzero(column)[0] if not len(rows): raise ValueError(f"nothing to hang a chain from above x {x}") - return int(rows[-1]) + 1 + y = int(rows[0]) + while y < below and column[y]: + y += 1 + return y -def build() -> tuple[Image.Image, list]: +def build() -> Image.Image: platform = frame("arena-platform", "platform-00") chain = frame("arena-chain", "chain-00") - traversal = Image.open(REGION / "images" / "05-traversal-right.png").convert("RGBA") - plate = Image.new("RGBA", traversal.size, (0, 0, 0, 0)) - lines = [] + play = np.asarray(Image.open(REGION / "masks" / f"{CHUNK}.05-play.png").getchannel("A")) > 128 + plate = Image.new("RGBA", (play.shape[1], play.shape[0]), (0, 0, 0, 0)) for x, top in PLATFORMS: for cx in (x + CHAIN_INSET, x + platform.width - CHAIN_INSET): - hook = underside(traversal, cx, top) + hook = underside(play, cx, top) plate.alpha_composite(chain_strip(chain, top - hook + 4), (cx - chain.width // 2, hook)) plate.alpha_composite(platform, (x, top)) - lines.append([[x, top], [x + platform.width, top]]) - return plate, lines + return plate def main() -> None: subprocess.run([sys.executable, str(ROOT / "scripts" / "export_atlas.py"), "arena-platform", "arena-chain", "--out", str(ATLAS)], check=True, capture_output=True) - plate, lines = build() - plate.save(REGION / "arena" / "right.png", optimize=True) - path = REGION / "rc-2-0.anomaly.collision.json" - data = json.loads(path.read_text(encoding="utf-8")) - data["oneWay"] = [l for l in data["oneWay"] if not (ARENA[0] <= l[0][0] <= ARENA[1] and l[0][1] > 400)] + lines - path.write_text(json.dumps(data, indent=1, ensure_ascii=False) + "\n", encoding="utf-8") - print(f"arena platforms: {len(lines)} on chains -> {plate.size}, one-way lines {lines}") + plate = build() + (REGION / "arena").mkdir(exist_ok=True) + plate.save(REGION / "arena" / f"{CHUNK}.png", optimize=True) + data = json.loads((REGION / f"{CHUNK}.anomaly.collision.json").read_text(encoding="utf-8")) + tops = {(x, top) for x, top in PLATFORMS} + if not tops <= {(line[0][0], line[0][1]) for line in data["oneWay"]}: + sys.exit(f"{CHUNK}.anomaly.collision.json lacks the platforms' one-way lines: run rusty_creek_zone.py --stage") + print(f"arena platforms: {len(PLATFORMS)} on chains -> arena/{CHUNK}.png") if __name__ == "__main__": diff --git a/scripts/collision_check.py b/scripts/collision_check.py index d7faff5..08db38b 100644 --- a/scripts/collision_check.py +++ b/scripts/collision_check.py @@ -193,6 +193,15 @@ def reach(data: dict, name: str) -> list[str]: player = [p for p in data["spawn"] if p["kind"] == "player"] start = standing(s, player[0]["x"], player[0]["y"]) if player else \ [i for i, a in enumerate(s) if a["x0"] <= SNAP] + # A ladder that runs off the chunk's top or bottom edge is a way in from the row next to it (a zone's rows are + # rooms joined by ladders): the floor at its other end is a start too. + h = data["size"][1] + for c in data["climb"]: + x = c["x"] + c["w"] / 2 + if c["y"] + c["h"] >= h - 2: + start += standing(s, x, c["y"]) + elif c["y"] <= 2: + start += standing(s, x, c["y"] + c["h"]) if not start: return [f"{name}: no floor at the player spawn or the chunk's left edge"] seen, todo = set(start), list(start) diff --git a/scripts/creek_layers.py b/scripts/creek_layers.py deleted file mode 100644 index f338a1a..0000000 --- a/scripts/creek_layers.py +++ /dev/null @@ -1,308 +0,0 @@ -"""Build registered creek layers from scene art; never regenerate a depth plate. - -Pillow performs the requested mask/canvas work. Image generation supplies the -scene-first sources and bounded repairs. No network, credentials or game runtime. -""" -from __future__ import annotations - -import argparse -import hashlib -import json -from pathlib import Path - -from PIL import Image, ImageChops, ImageDraw - -ROOT = Path(__file__).resolve().parents[1] -BASE = ROOT / 'art/stages/rusty-creek' -INPUTS = BASE / 'inputs' -WORK = ROOT / 'tmp/stages/rusty-creek' # derived seam-repair inputs, never committed -W, H = 2160, 720 -CHUNKS = ('left', 'center', 'right') -ROLES = ('01-distance', '02-supports', '03-bank', '04-water', - '05-traversal', '06-near-rails', '07-foliage') - - -def digest(path): - return hashlib.sha256(Path(path).read_bytes()).hexdigest() - - -def read(path): - return json.loads(Path(path).read_text(encoding='utf-8')) - - -def write(path, value): - Path(path).write_text(json.dumps(value, indent=2) + '\n', encoding='utf-8', newline='\n') - - -def blank(width=W): - return Image.new('RGBA', (width, H)) - - -def canonical(image): - image = image.convert('RGBA').resize((W, H), Image.Resampling.NEAREST) - image.putdata([(r, g, b, a) if a else (0, 0, 0, 0) - for r, g, b, a in image.getdata()]) - return image - - -def remove_matte(image): - """Remove saturated red debug matte, not orange/brown rust. Retain source.""" - result = image.copy() - result.putdata([(0, 0, 0, 0) if a and r > 160 and g < 85 and b < 75 - and r > 2 * g else (r, g, b, a) - for r, g, b, a in result.getdata()]) - return result - - -def changed(a, b): - return sum(pixel != (0, 0, 0, 0) - for pixel in ImageChops.difference(a, b).getdata()) - - -def mirrored(image, index): - return image.transpose(Image.Transpose.FLIP_LEFT_RIGHT) if index % 2 else image.copy() - - -def shifted(image, dy): - out = blank() - out.alpha_composite(image, (0, dy)) - return out - - -def split_structure(image, boxes): - """Disjoint masonry regions, not two independently redrawn paintings.""" - mask = Image.new('L', image.size) - draw = ImageDraw.Draw(mask) - for box in boxes: - draw.rectangle(box, fill=255) - rear = blank() - front = blank() - rear.paste(image, (0, 0), mask) - front.paste(image, (0, 0), ImageChops.invert(mask)) - proof = Image.alpha_composite(rear, front) - if changed(proof, image): - raise ValueError('Structure partition loses or duplicates source pixels') - return rear, front - - -def save_once(image, path, aliases): - """Shared scenery repeats on the right chunk: keep one file, record an alias.""" - twin = path.with_name(path.name.replace('-right.png', '-left.png')) - if path != twin and twin.exists() and not changed(Image.open(twin).convert('RGBA'), image.convert('RGBA')): - aliases[path.name] = twin.name - return - image.save(path) - - -def plate_path(name, data=None): - """An export's file, following the alias for a right chunk stored as its left twin.""" - data = data or read(BASE / 'media-sources.json') - return BASE / 'images' / data.get('aliases', {}).get(name, name) - - -def compose(plates, architecture=None): - # The game's draw order and offsets (export.json states, as export_stage.py --verify draws them): the masters - # are what the game shows. Anomaly without architecture, clean with it. - config = read(BASE / 'export.json') - out = blank() - for role in config['states']['clean' if architecture is not None else 'anomaly']: - if config['layers'][role].get('overlay'): - continue # drawn over the art in the game (Jenny's arena platforms), not part of the masters - layer = architecture if role == 'clean-architecture' else plates[role] - dy = config['layers'][role].get('dy', 0) - if dy: # a plate painted off its ground, moved down onto it - moved = blank() - moved.paste(layer, (0, dy)) - layer = moved - out = Image.alpha_composite(out, layer) - return out - - -def route_errors(route): - errors = [] - nodes = {n['id']: n for n in route['nodes']} - if len(nodes) != len(route['nodes']): - errors.append('duplicate route node') - adjacency = {key: set() for key in nodes} - for node in nodes.values(): - x, y = node['at'] - if not (0 <= x <= 3 * W and 32 <= y <= 650): - errors.append('route node outside review world: ' + node['id']) - for edge in route['edges']: - a, b = edge['from'], edge['to'] - if a not in nodes or b not in nodes: - errors.append('unknown edge endpoint') - continue - adjacency[a].add(b) - if edge.get('bidirectional', True): - adjacency[b].add(a) - dx = abs(nodes[a]['at'][0] - nodes[b]['at'][0]) - dy = abs(nodes[a]['at'][1] - nodes[b]['at'][1]) - if edge['kind'] == 'ladder' and dx > 8: - errors.append('ladder is not vertical: ' + a) - if edge['kind'] == 'jump' and (dx > 180 or dy > 120): - errors.append('jump exceeds proposed movement envelope: ' + a) - reached = {route['entry']} - pending = list(reached) - while pending: - for node in adjacency[pending.pop()] - reached: - reached.add(node) - pending.append(node) - if set(nodes) - reached: - errors.append('unreachable route nodes: ' + ', '.join(sorted(set(nodes) - reached))) - if route['exit'] not in reached or route['boss'] not in reached: - errors.append('entry cannot reach boss and exit') - dead_ends = [n['id'] for n in route['nodes'] if n.get('purpose') == 'optional dead end'] - if not dead_ends or any(len(adjacency[n]) != 1 for n in dead_ends): - errors.append('optional dead ends must have one return connection') - return errors - - -def build(): - config = read(BASE / 'assembly.json') - old = INPUTS - WORK.mkdir(parents=True, exist_ok=True) - original = {} - removals = {} - for chunk in CHUNKS: - source = canonical(Image.open(BASE / 'sources' / f'{chunk}.png')) - clean = remove_matte(source) - removals[chunk] = changed(source, clean) - # Preserve the exact input bytes used to prepare the recorded packet. - normalized = remove_matte(Image.open(BASE / 'sources' / f'{chunk}.png').convert('RGBA').resize((W, H), Image.Resampling.NEAREST)) - normalized.save(WORK / f'{chunk}-normalized.png') - original[chunk] = clean - world = blank(3 * W) - for i, chunk in enumerate(CHUNKS): - world.alpha_composite(original[chunk], (i * W, 0)) - unpatched = world.copy() - for index, join in enumerate(('left--center', 'center--right')): - candidate = canonical(Image.open(BASE / 'sources' / f'structure--{join}-candidate.png')) - x = (index + 1) * W - 256 - world.paste(candidate.crop((824, 0, 1336, H)), (x, 0)) - protected = Image.new('L', world.size, 255) - pen = ImageDraw.Draw(protected) - for seam in (W, 2 * W): - pen.rectangle((seam - 256, 0, seam + 255, H - 1), fill=0) - before = blank(3 * W) - after = blank(3 * W) - before.paste(unpatched, (0, 0), protected) - after.paste(world, (0, 0), protected) - if changed(before, after): - raise ValueError('Repair changed protected pixels') - # Matte cleanup is a separate explicit post-repair step, never hidden in the - # bounded-copy invariant. Raw repaired source and hashes remain auditable. - cleaned_world = remove_matte(world) - removals['post_repair'] = changed(world, cleaned_world) - far = canonical(Image.open(old / 'depth-01-far.png')) - bank = shifted(remove_matte(canonical(Image.open(old / 'depth-03-bank.png'))), 90) - water = canonical(Image.open(old / 'depth-04-water.png')) - rails = shifted(remove_matte(canonical(Image.open(old / 'depth-06-rails.png'))), 90) - clean_arch = remove_matte(canonical(Image.open(old / 'depth-02-structure.png'))) - plants_source = remove_matte(canonical(Image.open(BASE / 'sources/plants.png'))) - plants = blank() - plants.alpha_composite(plants_source.resize((W, 504), Image.Resampling.NEAREST), (0, 263)) - outputs = BASE / 'images' - outputs.mkdir(exist_ok=True) - for stale in outputs.glob('*.png'): - stale.unlink() - aliases = {} - for i, chunk in enumerate(CHUNKS): - structure = canonical(cleaned_world.crop((i * W, 0, (i + 1) * W, H))) - rear, traversal = split_structure(structure, config['masonry_regions'][chunk]) - foliage = mirrored(plants, i) - # The boss floor must stay readable; this is an explicit authored alpha - # mask, not automatic semantic segmentation or a claim of a clean rig. - if chunk == 'right': - transparent = blank() - foliage.paste(transparent.crop((1050, 0, 1800, 590)), (1050, 0)) - plates = dict(zip(ROLES, (mirrored(far, i), rear, mirrored(bank, i), - mirrored(water, i), traversal, mirrored(rails, i), foliage))) - for role, plate in plates.items(): - save_once(plate, outputs / f'{role}-{chunk}.png', aliases) - architecture = mirrored(clean_arch, i) - save_once(architecture, outputs / f'clean-architecture-{chunk}.png', aliases) - compose(plates).convert('RGB').save(outputs / f'after-{chunk}.png') # previews: rebuilt, never edited - compose(plates, architecture).convert('RGB').save(outputs / f'before-{chunk}.png') - errors = route_errors(read(BASE / 'route.json')) - if errors: - raise ValueError('; '.join(errors)) - # Snapshot reviewed exports; verify mode checks actual files against it. - records = [] - for path in sorted([*outputs.glob('*.png'), *(BASE / 'sources').glob('*.png')]): - im = Image.open(path) - records.append({'file': path.relative_to(BASE).as_posix(), 'sha256': digest(path), - 'dimensions': list(im.size), 'mode': im.mode, - 'alpha_extrema': list(im.getchannel('A').getextrema()) if im.mode == 'RGBA' else None}) - inputs = [old / f'depth-{name}.png' for name in ('01-far', '02-structure', '03-bank', '04-water', '06-rails')] - inputs += [ROOT / 'references/campus/images/crossings.png'] - inputs += [INPUTS / f'maze-{chunk}.png' for chunk in CHUNKS] - write(BASE / 'media-sources.json', {'date': '2026-10-23', - 'method': 'Built-in image generation; exact prompts in prompts.json. Deterministic masks and assembly in scripts/creek_layers.py.', - 'images': records, 'source_inputs': [{'project_file': p.relative_to(ROOT).as_posix(), 'sha256': digest(p)} for p in inputs], - 'aliases': aliases, - 'layer_order': list(ROLES), 'shared_roles': [ROLES[i] for i in (0, 2, 3, 5, 6)], - 'packet': read(BASE / 'packet.json'), - 'configuration_hashes': {name: digest(BASE / name) for name in ('assembly.json', 'route.json', 'stage.json', 'prompts.json')}, - 'source_graph': {'architecture': 'sources/{chunk}.png -> explicit normalization/matte cleanup -> bounded repairs -> disjoint masks -> role/chunk exports', - 'shared_nature': 'earlier fixed source -> explicit offset/mirroring -> same role export in both states', - 'foliage': 'sources/plants.png -> explicit vertical scale/offset and boss alpha window -> shared role7', - 'masters': 'registered exports in assembly draw order; clean swaps role2 and omits role5'}, - 'acceptance': {'team_art_approval': False, 'physics_verified': False, 'per_object_rigs': False}}) - write(BASE / 'verification.json', {'world_size': [3 * W, H], 'layer_chunks': 21, - 'structure_partition_changed_pixels': 0, 'outside_repair_changed_pixels': 0, - 'shared_role_source_differences': 0, 'red_matte_pixels_removed': removals, - 'route_graph_errors': [], 'graph_is_not_physics': True, - 'repair_report': read(BASE / 'repair-report.json')}) - verify() - - -def verify(): - data = read(BASE / 'media-sources.json') - for name, expected in data['configuration_hashes'].items(): - if digest(BASE / name) != expected: - raise ValueError('Changed assembly contract: ' + name) - actual = {p.relative_to(BASE).as_posix() for folder in ('images', 'sources') - for p in (BASE / folder).glob('*.png')} - if actual != {item['file'] for item in data['images']}: - raise ValueError('Image inventory differs') - for item in data['images']: - path = BASE / item['file'] - im = Image.open(path) - if digest(path) != item['sha256'] or list(im.size) != item['dimensions'] or im.mode != item['mode']: - raise ValueError('Changed asset: ' + item['file']) - if im.mode == 'RGBA' and list(im.getchannel('A').getextrema()) != item['alpha_extrema']: - raise ValueError('Alpha differs: ' + item['file']) - for item in data['source_inputs']: - if digest(ROOT / item['project_file']) != item['sha256']: - raise ValueError('Changed fixed input: ' + item['project_file']) - for chunk in CHUNKS: - plates = {role: Image.open(plate_path(f'{role}-{chunk}.png', data)).convert('RGBA') for role in ROLES} - for role, im in plates.items(): - low, high = im.getchannel('A').getextrema() - if im.size != (W, H) or (role != ROLES[0] and (low != 0 or high == 0)): - raise ValueError('Noncanonical or missing alpha: ' + role) - for name, architecture in (('after', None), ('before', Image.open(plate_path(f'clean-architecture-{chunk}.png', data)))): - expected = compose(plates, architecture).convert('RGB') - master = Image.open(BASE / 'images' / f'{name}-{chunk}.png').convert('RGB') - if ImageChops.difference(master, expected).getbbox(): - raise ValueError('Master recomposition differs: ' + name + '-' + chunk) - # Shared nature uses exact matching edge columns, not an opacity blend. - for role in data['shared_roles']: - for left, right in zip(CHUNKS, CHUNKS[1:]): - a = Image.open(plate_path(f'{role}-{left}.png', data)).convert('RGBA') - b = Image.open(plate_path(f'{role}-{right}.png', data)).convert('RGBA') - # The authored boss window only touches the interior of the right chunk. - if a.crop((W-1, 0, W, H)).tobytes() != b.crop((0, 0, 1, H)).tobytes(): - raise ValueError('Shared scenery boundary differs: ' + role) - errors = route_errors(read(BASE / 'route.json')) - if errors: - raise ValueError('; '.join(errors)) - print('Verified 21 registered plates, six masters, exact recomposition, alpha, sources and route graph. Physics/art approval remain separate.') - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('--build', action='store_true', help='Rebuild explicitly approved derived mask exports in place') - args = parser.parse_args() - build() if args.build else verify() diff --git a/scripts/export_ui.py b/scripts/export_ui.py index dc538c7..b6e263f 100644 --- a/scripts/export_ui.py +++ b/scripts/export_ui.py @@ -161,7 +161,7 @@ def nine_slice(piece: Image.Image, w: int, h: int, inset: int) -> Image.Image: def contact(pieces: dict[str, Image.Image], lay: dict) -> Image.Image: """The HUD and the open map over a Rusty Creek frame, at game size and the measured placements.""" - plate = ROOT / "art" / "stages" / "rusty-creek" / "images" / "after-center.png" + plate = ROOT / "art" / "stages" / "rusty-creek" / "images" / "rc-1-1.png" frame = Image.open(plate).convert("RGBA").crop((0, 0, 1280, 720)) if plate.exists() \ else Image.new("RGBA", (1280, 720), (23, 36, 45, 255)) put = lambda name, xy: name in pieces and frame.alpha_composite(pieces[name], xy) diff --git a/scripts/readability.py b/scripts/readability.py index d2344df..ccafab9 100644 --- a/scripts/readability.py +++ b/scripts/readability.py @@ -36,9 +36,10 @@ "path": ("hg-0-0.png", (300, 300, 1380, 480), 137), "air": ("hg-0-0.png", (1000, 160, 2080, 340), 120), "pond": ("hg-4-0.png", (300, 500, 1380, 680), 70), - # The rust maze: the first rover's deck (y 508) in rc-0-0 and the creek floor (y 569) in rc-1-0. - "deck": (("rusty-creek", "rc-0-0", "anomaly"), (300, 330, 1380, 510), 178), - "maze": (("rusty-creek", "rc-1-0", "anomaly"), (300, 390, 1380, 570), 179), + # Rusty Creek's anomaly: the creek path under the railway girder (y 522) in rc-0-1, and a rust-maze girder (y 331) + # in rc-1-0 – where the rovers and the crab drive. + "deck": (("rusty-creek", "rc-0-1", "anomaly"), (300, 344, 1380, 524), 178), + "maze": (("rusty-creek", "rc-1-0", "anomaly"), (300, 152, 1380, 332), 179), } # --all: the band where each atlas appears (default: the maze deck). HOME = {"dexter": "path", "dexter-acts": "path", "dexter-prologue": "path", "fx-ground": "path", "hero-move": "path", diff --git a/scripts/test_creek_layers.py b/scripts/test_creek_layers.py deleted file mode 100644 index 06ce374..0000000 --- a/scripts/test_creek_layers.py +++ /dev/null @@ -1,47 +0,0 @@ -"""Failures that would invalidate the route contract or registered decomposition.""" -import unittest - -from PIL import Image - -import creek_layers as creek - - -class CreekContractTests(unittest.TestCase): - def setUp(self): - self.route = creek.read(creek.BASE / 'route.json') - - def test_disconnected_exit_is_rejected(self): - self.route['edges'] = [e for e in self.route['edges'] - if 'exit' not in (e['from'], e['to'])] - self.assertTrue(any('unreachable' in e for e in creek.route_errors(self.route))) - - def test_spur_needs_a_return(self): - self.route['edges'].append({'from': 'l-lookout', 'to': 'entry', 'kind': 'walk'}) - self.assertTrue(any('dead ends' in e for e in creek.route_errors(self.route))) - - def test_ladder_must_be_vertical(self): - self.route['edges'][0]['kind'] = 'ladder' - self.assertTrue(any('vertical' in e for e in creek.route_errors(self.route))) - - def test_jump_must_fit_proposed_envelope(self): - self.route['edges'].append({'from': 'entry', 'to': 'exit', 'kind': 'jump'}) - self.assertTrue(any('jump exceeds' in e for e in creek.route_errors(self.route))) - - def test_partition_preserves_semitransparent_pixels(self): - source = Image.new('RGBA', (creek.W, creek.H), (40, 100, 140, 127)) - rear, front = creek.split_structure(source, [[0, 0, 800, creek.H-1]]) - self.assertEqual(creek.changed(Image.alpha_composite(rear, front), source), 0) - self.assertEqual(rear.getpixel((801, 10)), (0, 0, 0, 0)) - self.assertEqual(front.getpixel((800, 10)), (0, 0, 0, 0)) - - def test_matte_cleanup_preserves_rust_and_transparency(self): - source = Image.new('RGBA', (3, 1)) - source.putdata([(255, 0, 0, 255), (174, 95, 42, 255), (200, 80, 30, 0)]) - cleaned = creek.remove_matte(source) - self.assertEqual(cleaned.getpixel((0, 0)), (0, 0, 0, 0)) - self.assertEqual(cleaned.getpixel((1, 0)), source.getpixel((1, 0))) - self.assertEqual(cleaned.getpixel((2, 0)), source.getpixel((2, 0))) - - -if __name__ == '__main__': - unittest.main() diff --git a/scripts/test_split_layers.py b/scripts/test_split_layers.py index 600e4e6..2acbfae 100644 --- a/scripts/test_split_layers.py +++ b/scripts/test_split_layers.py @@ -9,7 +9,6 @@ import split_layers as sl ROOT = Path(__file__).resolve().parents[1] -CREEK = ROOT / 'art' / 'stages' / 'rusty-creek' def scene(anomaly=False): @@ -81,28 +80,6 @@ def test_bad_config_is_named(self): with self.assertRaisesRegex(sl.SplitError, "unknown layer '09-fx'"): sl.run(self.region, check=False) - def test_rusty_creek_matches_creek_layers(self): - """Split the composed left anomaly chunk with the creek's own layer alphas, in its draw order. - Every pixel lands in the layer creek_layers.py drew on top there, and the stack rebuilds the art. - (Colours can't match the plates: they are semi-transparent, so the composed art is a blend.)""" - assembly = json.loads((CREEK / 'assembly.json').read_text(encoding='utf-8')) - role_to_layer = {'01-distance': '01-far', '03-bank': '02-mid', '02-supports': '03-rear', - '04-water': '04-water', '05-traversal': '05-play', '06-near-rails': '06-near', - '07-foliage': '07-foreground'} - order = assembly['draw_order'] - plates = {r: Image.open(CREEK / 'images' / f'{r}-left.png').convert('RGBA') for r in order} - rules = [{'layer': role_to_layer[r], 'alpha': f'images/{r}-left.png'} for r in order] - source = Image.open(CREEK / 'images' / 'after-left.png').convert('RGBA') - layers = sl.split(source, sl.assign({'default': '01-far', 'rules': rules}, 'anomaly', source, CREEK)) - self.assertTrue(sl.same(sl.stack(layers, source.size), source)) - covered = Image.new('L', source.size, 0) # pixels a later-drawn plate already claims - for role in reversed(order): - drawn = plates[role].getchannel('A').point(lambda a: 255 if a else 0) - on_top = ImageChops.subtract(drawn, covered) - ours = layers.get(role_to_layer[role]) - ours = ours.getchannel('A').point(lambda a: 255 if a else 0) if ours else Image.new('L', source.size, 0) - self.assertIsNone(ImageChops.difference(ours, on_top).getbbox(), role) - covered = ImageChops.lighter(covered, drawn) def test_a_fill_goes_only_under_nearer_layers(self): source = scene() owner = sl.assign(self.config['chunks']['t-0-0'], 'clean', source, self.region) diff --git a/scripts/zones/creek_guide.py b/scripts/zones/creek_guide.py index 917dbee..12781da 100644 --- a/scripts/zones/creek_guide.py +++ b/scripts/zones/creek_guide.py @@ -125,7 +125,7 @@ def build(name, real_top): img = Image.new("RGB", (W, H)) sky(img); trees(img); top(img); water(img) if real_top: - ref = Image.open(ROOT / "art/stages/rusty-creek/images/before-center.png").convert("RGB") + ref = Image.open(ROOT / "art/stages/rusty-creek/prototype/before-center.png").convert("RGB") # bridge photo-painting: scale to full width, its water line (y~595 of 720) to WATER_Y+? ref = ref.resize((W, int(720 * W / 2160))) img.paste(ref.crop((0, 0, W, 640)), (0, 0)) diff --git a/scripts/zones/creek_paint_creek.py b/scripts/zones/creek_paint_creek.py index e2ff013..a75c6fb 100644 --- a/scripts/zones/creek_paint_creek.py +++ b/scripts/zones/creek_paint_creek.py @@ -41,8 +41,8 @@ S = "repo:art/direction/images/style-master-preview.png" ZA = "repo:tmp/zones/concepts/zone-a.png" -BC = "repo:art/stages/rusty-creek/images/before-center.png" -AC = "repo:art/stages/rusty-creek/images/after-center.png" +BC = "repo:art/stages/rusty-creek/prototype/before-center.png" +AC = "repo:art/stages/rusty-creek/prototype/after-center.png" TAKES = { # clean: layout from my painted guide (edited image), look from refs "clean-1": ("guide-a.png", [S, ZA], "The first image is a rough flat LAYOUT GUIDE: keep every shape where it is " diff --git a/scripts/zones/rusty_creek_zone.py b/scripts/zones/rusty_creek_zone.py index 2069fe7..9e108f0 100644 --- a/scripts/zones/rusty_creek_zone.py +++ b/scripts/zones/rusty_creek_zone.py @@ -2,7 +2,9 @@ #227 concept's level band – the rust maze above, the creek path, the drains below. Writes every chunk's collision, re-traces the band above's blockout from its painting, and checks that the whole grid can be walked both ways. - python scripts/zones/rusty_creek_zone.py + python scripts/zones/rusty_creek_zone.py # collision, blockout, reachability + python scripts/zones/rusty_creek_zone.py --stage # the zone becomes the game's Rusty Creek (art/stages/rusty-creek) + python scripts/zones/rusty_creek_zone.py --fills # after depth_layers fill/whole: the back layers whole The level row's collision is measured from the art (the concept's path and the railway girder are straight); the band above and the band below are traced from their depth keys (depth_layers.py key / masks --all), with the same @@ -67,6 +69,19 @@ def level(col: int) -> dict: return data +def simplify(line: list[list[int]], tolerance: float) -> list[list[int]]: + """Ramer-Douglas-Peucker: the fewest points whose straight runs stay within `tolerance` px of the line.""" + if len(line) <= 2: + return line + (x0, y0), (x1, y1) = line[0], line[-1] + def off(p): + return abs((y1 - y0) * p[0] - (x1 - x0) * p[1] + x1 * y0 - y1 * x0) / max(1e-9, ((y1 - y0) ** 2 + (x1 - x0) ** 2) ** 0.5) + i, worst = max(((i, off(p)) for i, p in enumerate(line[1:-1], 1)), key=lambda t: t[1]) + if worst <= tolerance: + return [line[0], line[-1]] + return simplify(line[:i + 1], tolerance)[:-1] + simplify(line[i:], tolerance) + + def traced(cid: str, row: int) -> dict: """A grown band's floors and ladders from its depth key (stage 7).""" data, bands = empty(cid), hg.key_bands(cid, ZONE) @@ -90,14 +105,28 @@ def traced(cid: str, row: int) -> dict: data["walk"] = [l for l in data["walk"] if l[0][0] < x] + [line] data["walk"] = [[p for p in l if p[0] <= x] if l is not data["walk"][-1] else l for l in data["walk"]] data["walk"] = [l for l in data["walk"] if len(l) > 1] - # The key marks pillars and pipes with brick rows or brackets like rungs: a climb is a ladder only where both its - # ends meet a floor, or the chunk edge that leads on to the next row. - def meets(x0: int, x1: int, y: int) -> bool: - return any(abs(hg_y - y) <= 32 for line in data["walk"] for a, b in zip(line, line[1:]) - if a[0] <= x1 and b[0] >= x0 for hg_y in (a[1], b[1])) - data["climb"] = [c for c in data["climb"] - if (meets(c["x"], c["x"] + c["w"], c["y"]) or c["y"] == 0) - and (meets(c["x"], c["x"] + c["w"], c["y"] + c["h"]) or c["y"] + c["h"] == H)] + # A floor run on to the chunk's edge (walkable) can end in a 4 px piece the body steps over in one frame: a point + # that close to an end goes, the end stays. + data["walk"] = [[p for i, p in enumerate(line) if i in (0, len(line) - 1) + or (p[0] - line[0][0] >= 8 and line[-1][0] - p[0] >= 8)] for line in data["walk"]] + if row == 0: # a floor at the frame's top has no room over it for the body (the row above is not there) + data["walk"] = [l for l in data["walk"] if min(y for _, y in l) >= BODY + 14] + # A girder is straight: each traced beam is one flat tread at its median height (collision_check: planks + # are flat; the trace wobbles 1-3 px along the rivets). + data["walk"] = [[[line[0][0], med], [line[-1][0], med]] for line in data["walk"] + for med in [sorted(p[1] for p in line)[len(line) // 2]]] + # The key marks pillars and pipes with brick rows or brackets like rungs: a climb is a ladder between the floors + # it crosses, trimmed to them; only a maze ladder runs on down past its chunk's bottom (onto the girder deck). + climbs = [] + for c in data["climb"]: + mid = c["x"] + c["w"] / 2 + ys = sorted({round(a[1] + (b[1] - a[1]) * (mid - a[0]) / max(1, b[0] - a[0])) + for line in data["walk"] for a, b in zip(line, line[1:]) if a[0] <= mid <= b[0]}) + ys = [y for y in ys if c["y"] - 32 <= y <= c["y"] + c["h"] + 32] + bottom = H if row == 0 and c["y"] + c["h"] > H - 40 else (ys[-1] if ys else None) + if ys and bottom is not None and bottom - ys[0] >= 48: + climbs.append({**c, "y": ys[0], "h": bottom - ys[0]}) + data["climb"] = climbs return data @@ -168,9 +197,264 @@ def blockout(data: dict) -> Image.Image: return wm.guide(ch) +STAGE = ROOT / "art" / "stages" / "rusty-creek" +# Zone band -> stage layer. Every layer scrolls with the path (1.0): per-chunk plates at a slower scroll would slide +# against their neighbours (docs/09); parallax comes back with region plates quilted per row, a later step. +MASKS = (("00-sky", "00-sky"), ("01-far", "01-far"), ("02-mid", "02-mid"), ("04-water", "04-water"), + ("05-play", "05-play"), ("07-foreground", "07-foreground")) +LAYERS = {"00-sky": 0, "01-far": 1, "02-mid": 2, "03-rear": 3, "04-water": 4, "05-play": 5, "07-foreground": 7} +MATERIAL = {0: "steel", 1: "stone", 2: "stone"} # the maze's girders, the creek path, the drains' concrete + +# The region's two states on the same art (Alexander, 26 Oct: the zone replaces the creek stage; the anomaly is the +# same picture with the 404 tears). Clean: you land on the path, Jenny comes down it and rams you (the jenny-ram box; +# Dexter watches from beyond it). Anomaly: the rust maze's fight, carried over from the old stage onto the zone's +# floors - the chair first, rovers on the path, the maze and the drains, the drone over the path, the crab on a maze +# beam, the coffee machine with Dexter, snacks and notes off the path, and Jenny's arena on the right-hand chunk, +# its platforms hung on chains from the railway girder. +CLEAN = { + "rc-0-1": {"spawn": [{"id": "player", "kind": "player", "x": 300, "y": PATH, + "note": "The 404 lands the hero on the creek path under the rail bridge (P5)"}]}, + "rc-1-1": {"interact": [{"id": "jenny-ram", "kind": "jenny-ram", "x": 1080, "y": PATH - 92, "w": 40, "h": 92, + "note": "Jenny comes down the creek path and rams the hero; the region turns (M4-S1 #54, P5)"}]}, +} +ARENA_GATE = 1096 # rc-2-1: the boss gate's x; her floor ends at ARENA_END, behind it the pier ladder and the exit +ARENA_END = 1690 +PLATFORM_W = 202 +PLATFORMS = [(1180, PATH - 87), (1430, PATH - 87)] # left edge, top: 87 px over her floor (a full jump is 96) +ANOMALY = { + "rc-0-1": {"spawn": [{"id": "player", "kind": "player", "x": 200, "y": PATH}, + {"id": "rover-1", "kind": "rover", "x": 900, "y": PATH, "patrol": [780, 1020]}, + {"id": "rover-4", "kind": "rover", "x": 1500, "y": PATH, "patrol": [1380, 1620]}], + "interact": [{"id": "chair", "kind": "pickup", "item": "chair", "x": 520, "y": PATH - 36, "w": 40, "h": 36}, + {"id": "note-1", "kind": "pickup", "item": "note-1", "x": 1200, "y": 62 - 24, "w": 24, "h": 24}]}, + "rc-0-0": {"spawn": [{"id": "rover-5", "kind": "rover", "x": 1800, "y": 287, "patrol": [1560, 2040]}, + {"id": "rover-6", "kind": "rover", "x": 450, "y": 524, "patrol": [220, 700]}], + "interact": [{"id": "muffin-1", "kind": "pickup", "item": "muffin", "x": 1500, "y": 287 - 28, "w": 24, "h": 28}]}, + "rc-1-1": {"spawn": [{"id": "rover-2", "kind": "rover", "x": 500, "y": PATH, "patrol": [360, 640]}, + {"id": "rover-3", "kind": "rover", "x": 1350, "y": PATH, "patrol": [1220, 1480]}, + {"id": "drone-1", "kind": "drone", "x": 1150, "y": PATH - 95, "patrol": [900, 1500]}, + {"id": "dexter-1", "kind": "dexter", "x": 1820, "y": PATH}], + "interact": [{"id": "coffee-1", "kind": "coffee-machine", "x": 1770, "y": PATH - 80, "w": 40, "h": 80}, + {"id": "leberkaese-1", "kind": "pickup", "item": "leberkaese", "x": 1400, "y": 63 - 28, "w": 24, "h": 28}]}, + "rc-1-0": {"spawn": [{"id": "crab-1", "kind": "crab", "x": 1200, "y": 536, "patrol": [950, 1530]}]}, + "rc-2-2": {"spawn": [{"id": "rover-7", "kind": "rover", "x": 1300, "y": 221, "patrol": [1000, 1700]}], + "interact": [{"id": "note-2", "kind": "pickup", "item": "note-2", "x": 1900, "y": 221 - 24, "w": 24, "h": 24}]}, + "rc-2-1": {"spawn": [{"id": "jenny", "kind": "jenny", "x": 1440, "y": PATH}, + {"id": "dexter-2", "kind": "dexter", "x": 1640, "y": PATH}], + "interact": [{"id": "boss-gate", "kind": "boss-gate", "x": ARENA_GATE, "y": PATH - 100, "w": 30, "h": 100}, + {"id": "exit-anomaly", "kind": "chunk-exit", "x": 2060, "y": PATH - 80, "w": 60, "h": 80}]}, +} + + +def looks_like_sky(rgb): + """Blue sky or a white cloud (the creek's morning sky): what the sky layer may own.""" + import numpy as np + r, g, b = (np.asarray(rgb)[..., i].astype(int) for i in range(3)) + return ((b > r + 15) & (b > 120)) | (np.minimum(np.minimum(r, g), b) > 170) + + +def sky_mask(mask: Path, image: Path) -> Image.Image: + """The depth key's sky without the girder edges, ladders and leaves it let through (they go to the back wall).""" + import numpy as np + alpha = np.asarray(Image.open(mask).getchannel("A")) > 128 + keep = alpha & looks_like_sky(Image.open(image).convert("RGB")) + out = np.zeros((*keep.shape, 4), np.uint8) + out[keep] = 255 + return Image.fromarray(out) + + +def stage_id(zid: str) -> str: + return "rc-" + zid.split("-", 1)[1] + + +def copy(value): + return json.loads(json.dumps(value)) + + +def stage_collision(data: dict, sid: str, state: str, row: int) -> dict: + """A zone chunk's collision as the stage's: typed terrain, the state's spawns and finds.""" + out = copy(data) + out.update({"chunk": sid, "state": state, "ledge": [], "glideLift": [], "spawn": [], + "interact": [i for i in data["interact"] if i.get("kind") == "door"]}) + extra = (CLEAN if state == "clean" else ANOMALY).get(sid, {}) + out["spawn"] += copy(extra.get("spawn", [])) + out["interact"] += copy(extra.get("interact", [])) + if state == "anomaly" and sid == "rc-2-1": + # Jenny's floor is the path from the gate to ARENA_END (arenaFrom reads its end); past it the path goes on. + out["walk"] = [[[0, PATH], [ARENA_END, PATH]], [[ARENA_END, PATH], [W, PATH]]] + \ + [line for line in out["walk"] if line[0][1] != PATH] + out["oneWay"] += [[[x, top], [x + PLATFORM_W, top]] for x, top in PLATFORMS] + out["terrain"] = [] + for line in out["oneWay"]: + out["terrain"].append({"x": [line[0][0], line[-1][0]], "y": [line[0][1] - 12, line[0][1] + 12], + "kind": "plank", "material": "steel", "note": "an arena platform on its chains"}) + for line in out["walk"]: + ys = [y for _, y in line] + deck = row == 1 and max(ys) < 100 + steel = row == 0 or deck + note = "a girder of the rust maze" if row == 0 else "the railway girder's deck" if deck \ + else "the creek path" if row == 1 else "the drains' floor" + out["terrain"].append({"x": [line[0][0], line[-1][0]], "y": [min(ys) - 12, max(ys) + 12], + "kind": "plank" if steel else "ground", "material": "steel" if steel else MATERIAL[row], + "note": note}) + return out + + +def stage_ladders(collisions: dict[str, dict], grid: dict[str, tuple[int, int]]) -> None: + """A maze ladder reaching its chunk's bottom goes on down to the girder deck in the chunk below.""" + for cid, (col, row) in grid.items(): + if row != 0: + continue + below = collisions[f"rcz-{col}-1"] + top = girder_top(f"rcz-{col}-1") + for n, c in enumerate(collisions[cid]["climb"]): + if c["y"] + c["h"] >= H and not any(b["x"] == c["x"] and b["y"] == 0 for b in below["climb"]): + below["climb"].append(hg.box(c["x"], 0, c["x"] + c["w"], top, kind="ladder", id=f"{cid}-ladder-{n}-on")) + + +def tears_plate(image: Path, tears: list[dict]): + """The chunk's 404 tears as one RGBA plate over its clean picture (world_preview.tear_overlay), or None.""" + import numpy as np + import world_preview as wp + if not tears: + return None + clean = np.asarray(Image.open(image).convert("RGB")) + plate = Image.new("RGBA", (W, H), (0, 0, 0, 0)) + for tear in tears: + x0, y0, x1, y1 = wp.tear_region(tear) + layer = Image.new("RGBA", (W, H), (0, 0, 0, 0)) + layer.paste(Image.fromarray(wp.tear_overlay(clean[y0:y1, x0:x1], tear, x0, y0)), (x0, y0)) + plate = Image.alpha_composite(plate, layer) + return plate + + +def export_stage(collisions: dict[str, dict], grid: dict[str, tuple[int, int]], world: dict) -> None: + """The zone into art/stages/rusty-creek: paintings, masks (layers.json rules), export.json, both states' + collision and the tears. Then: arena_platforms.py, split_layers.py, export_stage.py, collision_check.py.""" + import shutil + for folder in ("images", "masks", "layers", "tears", "arena"): + (STAGE / folder).mkdir(parents=True, exist_ok=True) + stage_ladders(collisions, grid) + layers = {"note": "Rusty Creek from its zone (art/zones/rusty-creek, scripts/zones/rusty_creek_zone.py --stage).", + "chunks": {}} + export = {"note": ("Rusty Creek as a 3 x 3 zone (#157): the rust maze, the creek path, the drains. Every layer " + "scrolls with the path; the anomaly is the same picture with the 404 tears (05-tears) and " + "Jenny's arena platforms (05-arena, an overlay on rc-2-1)."), + "chunks": {}, "layers": {}, "states": {}, "composed": {"clean": "images/{name}.png"}} + for lid, z in LAYERS.items(): + export["layers"][lid] = {"file": f"layers/{{name}}.{lid}.png", "z": z, "scroll": 1.0, "optional": lid != "03-rear"} + export["layers"]["05-tears"] = {"file": "tears/{name}.png", "z": 5, "scroll": 1.0, "optional": True} + export["layers"]["05-arena"] = {"file": "arena/{name}.png", "z": 5, "scroll": 1.0, "optional": True, "overlay": True, + "why": "Jenny's arena platforms (playtest J6), on chains from the railway girder"} + order = list(LAYERS) + play = order.index("05-play") + 1 + export["states"] = {"clean": order, "anomaly": order[:play] + ["05-tears", "05-arena"] + order[play:]} + tears = world["anomaly"]["tears"] + for zid, (col, row) in grid.items(): + sid = stage_id(zid) + shutil.copy(ZONE / "images" / f"{zid}.png", STAGE / "images" / f"{sid}.png") + rules = [] + for band, layer in MASKS: + mask = ZONE / "masks" / f"{zid}.{band}.png" + if mask.exists() and band == "00-sky": + sky_mask(mask, ZONE / "images" / f"{zid}.png").save(STAGE / "masks" / f"{sid}.{layer}.png", optimize=True) + rules.append({"layer": layer, "alpha": f"masks/{sid}.{layer}.png"}) + elif mask.exists(): + shutil.copy(mask, STAGE / "masks" / f"{sid}.{layer}.png") + rules.append({"layer": layer, "alpha": f"masks/{sid}.{layer}.png"}) + layers["chunks"][sid] = {"states": {"clean": f"images/{sid}.png"}, "default": "03-rear", "rules": rules} + export["chunks"][sid] = {"x": col, "y": row} + for state in ("clean", "anomaly"): + data = stage_collision(collisions[zid], sid, state, row) + (STAGE / f"{sid}.{state}.collision.json").write_text( + json.dumps(data, indent=1, ensure_ascii=False) + "\n", encoding="utf-8") + plate = tears_plate(STAGE / "images" / f"{sid}.png", [t for t in tears if t["chunk"] == zid]) + if plate is not None: + plate.save(STAGE / "tears" / f"{sid}.png", optimize=True) + for path, data in ((STAGE / "layers.json", layers), (STAGE / "export.json", export)): + path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8") + print(f"rusty-creek stage: {len(grid)} chunks from the zone, both states, {len(tears)} tears") + + +def stage_fills(grid: dict[str, tuple[int, int]]) -> None: + """Every chunk's back layer whole (docs/09, checked on purple): the sky of the two rows that have one, painted + behind everything in front of it (depth_layers.py fill --only sky, its plate in tmp/), as fills/.00-sky.png; + the drains' back wall (depth_layers.py whole) down to the waterline only - below it the water layer covers the + room, and the model painted the wall there as flat black (the made-up void docs/09 rejects).""" + import numpy as np + filled = ROOT / "tmp" / "boards" / "rusty-creek" / "filled" + # The sky's colour per row, from the sky the maze's three chunks show (its mask): behind the maze the model's fill + # came back as black girder silhouettes twice (60 % of each chunk masked), so there the sky is this gradient. + skies = {} + for zid, (_, row) in grid.items(): + sid = stage_id(zid) + mask = STAGE / "masks" / f"{sid}.00-sky.png" + if row < 2 and mask.exists(): + rgb = np.asarray(Image.open(STAGE / "images" / f"{sid}.png").convert("RGB")) + r, g, b = (rgb[..., i].astype(int) for i in range(3)) + # the mask lets girder edges, ladders and tree tops through: only what looks like sky (blue, or a white + # cloud) is kept as the sky's own; the rest is filled like the hidden sky + looks = ((b > r + 15) & (b > 120)) | (np.minimum(np.minimum(r, g), b) > 170) + skies[sid] = (rgb, (np.asarray(Image.open(mask).getchannel("A")) > 128) & looks) + gradient = {} + for row in (0, 1): + rows = [v for s, v in skies.items() if s.endswith(f"-{row}")] + rgb = np.concatenate([r for r, _ in rows], 1).astype(float) + own = np.concatenate([o for _, o in rows], 1) + line = np.array([np.median(rgb[y][own[y]], 0) if own[y].sum() > 20 else [np.nan] * 3 for y in range(H)]) + for ch in range(3): # rows with too little sky take the nearest rows' colour + good = ~np.isnan(line[:, ch]) + line[:, ch] = np.interp(np.arange(H), np.flatnonzero(good), line[good, ch]) + gradient[row] = line + for zid, (_, row) in grid.items(): + sid = stage_id(zid) + if row < 2 and sid in skies: + rgb, own = skies[sid] + base = np.repeat(gradient[row][:, None, :], W, 1) + painted = filled / f"{sid}.00-sky.filled.png" + if row == 1 and painted.exists(): # the path's sky came back whole: keep it, but not its dark specks + base_img = np.asarray(Image.open(painted).convert("RGB")).astype(float) + dark = base_img.max(2) < 110 + base = np.where(dark[..., None], base, base_img) + # the fill is only what the sky does not own (split_layers puts it under the nearer layers) + plate = np.dstack([np.where(own[..., None], rgb, base).clip(0, 255).astype(np.uint8), + np.where(own, 0, 255).astype(np.uint8)]) + Image.fromarray(plate).save(STAGE / "fills" / f"{sid}.00-sky.png", optimize=True) + continue + rear = STAGE / "fills" / f"{sid}.03-rear.png" + water = json.loads((STAGE / f"{sid}.clean.collision.json").read_text(encoding="utf-8"))["noGo"] + if rear.exists() and water: + pixels = np.array(Image.open(rear).convert("RGBA")) + pixels[min(b["y"] for b in water):, :, 3] = 0 + Image.fromarray(pixels).save(rear, optimize=True) + print("rusty-creek fills: sky behind the maze and the path, the drains' walls down to the water") + + +def from_stage(grid: dict[str, tuple[int, int]], drop: bool = False) -> None: + """Once exported, the stage holds the one committed copy of the zone's paintings and masks (check_docs: no + duplicates); on a fresh checkout the zone's working copies come back from it. `drop`: after the export, remove the + zone's copies.""" + import shutil + for zid in grid: + sid = stage_id(zid) + pairs = [(STAGE / "images" / f"{sid}.png", ZONE / "images" / f"{zid}.png")] + pairs += [(STAGE / "masks" / f"{sid}.{layer}.png", ZONE / "masks" / f"{zid}.{band}.png") for band, layer in MASKS] + for stage, zone in pairs: + if drop and stage.exists() and zone.exists(): + zone.unlink() + elif not drop and stage.exists() and not zone.exists(): + zone.parent.mkdir(parents=True, exist_ok=True) + shutil.copy(stage, zone) + + def main() -> None: + if "--fills" in sys.argv: + world = json.loads((ZONE / "world.json").read_text(encoding="utf-8")) + stage_fills({cid: (c["col"], c["row"]) for cid, c in world["chunks"].items()}) + return world = json.loads((ZONE / "world.json").read_text(encoding="utf-8")) grid = {cid: (c["col"], c["row"]) for cid, c in world["chunks"].items()} + from_stage(grid) collisions = {cid: level(col) if row == 1 else traced(cid, row) for cid, (col, row) in grid.items()} drain_door(collisions["rcz-2-2"]) gone = reachable_only(collisions, grid) @@ -189,6 +473,9 @@ def main() -> None: "from their depth keys; the band above's blockout redrawn from it (the kept rust maze).") (ZONE / "world.json").write_text(json.dumps(world, indent=1, ensure_ascii=False) + "\n", encoding="utf-8") problems = wm.check(graph(collisions, grid)) + if "--stage" in sys.argv: + export_stage(collisions, grid, world) + from_stage(grid, drop=True) print(f"rusty-creek: collision for {len(collisions)} chunks ({gone} unreachable floor segments dropped); " + ("every surface reachable and leavable" if not problems else f"{len(problems)} problems, e.g. {problems[:4]}"))