diff --git a/art/sprites/README.md b/art/sprites/README.md index 895376a..03f1765 100644 --- a/art/sprites/README.md +++ b/art/sprites/README.md @@ -19,4 +19,4 @@ Sprite reference boards: the hero sheet (approved) and the animation, enemy, ite | [![FX · pond ripples and lily pad](images/fx-water-preview.png)](fx-water.md)
**[FX · pond ripples and lily pad](fx-water.md)** | [![Dexter · prologue additions](images/dexter-prologue-preview.png)](dexter-prologue.md)
**[Dexter · prologue additions](dexter-prologue.md)** | | [![Menu · the Hidden Garden at first light](images/menu-key-preview.png)](menu-key.md)
**[Menu · the Hidden Garden at first light](menu-key.md)** | [![Props · the storm drain's IT details](images/it-props-preview.png)](it-props.md)
**[Props · the storm drain's IT details](it-props.md)** | | [![Secret · the rubber chicken](images/rubber-chicken-preview.png)](rubber-chicken.md)
**[Secret · the rubber chicken](rubber-chicken.md)** | [![Prop · Jenny's arena platforms](images/arena-platform-preview.png)](arena-platform.md)
**[Prop · Jenny's arena platforms](arena-platform.md)** | -| [![Prop · the platforms' chains](images/arena-chain-preview.png)](arena-chain.md)
**[Prop · the platforms' chains](arena-chain.md)** | | +| [![Prop · the platforms' chains](images/arena-chain-preview.png)](arena-chain.md)
**[Prop · the platforms' chains](arena-chain.md)** | [![Prop · Jenny's arena wall](images/arena-wall-preview.png)](arena-wall.md)
**[Prop · Jenny's arena wall](arena-wall.md)** | diff --git a/art/sprites/arena-chain.md b/art/sprites/arena-chain.md index cc7b401..55f8af9 100644 --- a/art/sprites/arena-chain.md +++ b/art/sprites/arena-chain.md @@ -1,7 +1,7 @@ # Prop · the platforms' chains -[← Prop · Jenny's arena platforms](arena-platform.md) · [Sprite boards](README.md) · **31 / 31** · [Sprite boards →](README.md) +[← Prop · Jenny's arena platforms](arena-platform.md) · [Sprite boards](README.md) · **31 / 32** · [Prop · Jenny's arena wall →](arena-wall.md) ![Prop · the platforms' chains](images/arena-chain-preview.png) @@ -21,5 +21,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/arena-chain.png` · rebuild: `python scripts/make_boards.py draw arena-chain --redo --config art/sprites/boards.json` -[← Prop · Jenny's arena platforms](arena-platform.md) · [Sprite boards](README.md) · **31 / 31** · [Sprite boards →](README.md) +[← Prop · Jenny's arena platforms](arena-platform.md) · [Sprite boards](README.md) · **31 / 32** · [Prop · Jenny's arena wall →](arena-wall.md) diff --git a/art/sprites/arena-platform.md b/art/sprites/arena-platform.md index 4fd3f85..87e693b 100644 --- a/art/sprites/arena-platform.md +++ b/art/sprites/arena-platform.md @@ -1,7 +1,7 @@ # Prop · Jenny's arena platforms -[← Secret · the rubber chicken](rubber-chicken.md) · [Sprite boards](README.md) · **30 / 31** · [Prop · the platforms' chains →](arena-chain.md) +[← Secret · the rubber chicken](rubber-chicken.md) · [Sprite boards](README.md) · **30 / 32** · [Prop · the platforms' chains →](arena-chain.md) ![Prop · Jenny's arena platforms](images/arena-platform-preview.png) @@ -21,5 +21,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh 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` -[← Secret · the rubber chicken](rubber-chicken.md) · [Sprite boards](README.md) · **30 / 31** · [Prop · the platforms' chains →](arena-chain.md) +[← Secret · the rubber chicken](rubber-chicken.md) · [Sprite boards](README.md) · **30 / 32** · [Prop · the platforms' chains →](arena-chain.md) diff --git a/art/sprites/arena-wall.md b/art/sprites/arena-wall.md new file mode 100644 index 0000000..debb38a --- /dev/null +++ b/art/sprites/arena-wall.md @@ -0,0 +1,25 @@ +# Prop · Jenny's arena wall + + +[← Prop · the platforms' chains](arena-chain.md) · [Sprite boards](README.md) · **32 / 32** · [Sprite boards →](README.md) + + +![Prop · Jenny's arena wall](images/arena-wall-preview.png) + +**Review:** 🟨 Awaiting Alexander's review (25 Oct). Playtest J7: the arena's walls were code-drawn rectangles with hazard stripes. First draw: a barrier column of red-and-white crowd-control panels strapped to a rusted pole, with a caged warning lamp (lit, dark). 300 px tall in the game, as tall as the walls. The lamp's halo specks are dropped by "despeckle". + +## Brief + +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 this sheet in exactly that pixel-art look - the same pixel grain, palette and warm rim light. Prop sprite sheet of ONE tall narrow BARRIER COLUMN that closes a race-track arena on a rusty steel girder maze: a stack of old red-and-white striped plastic and steel crowd-control barrier panels and a rusted scaffold pole, lashed together with orange ratchet straps, standing straight up, about TEN times as tall as it is wide, its top crowned by a small amber rotating warning lamp in a cage (like the race car from image 2 might have hit it before: a few dents, black tyre marks). Strict front view, the same in every frame. 1 row, exactly 2 frames: frame 1 the warning lamp lit bright amber with a glow, frame 2 the same column with the lamp dark. Both frames identical apart from the lamp, same scale, standing on the SAME invisible ground line, with a wide clear magenta gap between them. Count the frames: the row has EXACTLY 2. No people, no car, no scenery, no ground. + +## Inputs + +- [coffee-machine-preview.png](images/coffee-machine-preview.png) +- [boss-jenny-preview.png](images/boss-jenny-preview.png) +- [style-master-preview.png](../direction/images/style-master-preview.png) + +Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/arena-wall.png` · rebuild: `python scripts/make_boards.py draw arena-wall --redo --config art/sprites/boards.json` + + +[← Prop · the platforms' chains](arena-chain.md) · [Sprite boards](README.md) · **32 / 32** · [Sprite boards →](README.md) + diff --git a/art/sprites/boards.json b/art/sprites/boards.json index 714e018..09bc037 100644 --- a/art/sprites/boards.json +++ b/art/sprites/boards.json @@ -1244,6 +1244,31 @@ ] }, "review": "🟨 Awaiting Alexander's review (25 Oct). The platforms hang from the girder over the arena: scripts/arena_platforms.py tiles this chain's link period from each platform end up to the girder's underside. The second frame came out as a second chain instead of an eye-bolt, so it is unused." + }, + { + "id": "arena-wall", + "title": "Prop · Jenny's arena wall", + "factor": 2, + "inputs": [ + "repo:art/sprites/images/coffee-machine-preview.png", + "repo:art/sprites/images/boss-jenny-preview.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 this sheet in exactly that pixel-art look - the same pixel grain, palette and warm rim light. Prop sprite sheet of ONE tall narrow BARRIER COLUMN that closes a race-track arena on a rusty steel girder maze: a stack of old red-and-white striped plastic and steel crowd-control barrier panels and a rusted scaffold pole, lashed together with orange ratchet straps, standing straight up, about TEN times as tall as it is wide, its top crowned by a small amber rotating warning lamp in a cage (like the race car from image 2 might have hit it before: a few dents, black tyre marks). Strict front view, the same in every frame. 1 row, exactly 2 frames: frame 1 the warning lamp lit bright amber with a glow, frame 2 the same column with the lamp dark. Both frames identical apart from the lamp, same scale, standing on the SAME invisible ground line, with a wide clear magenta gap between them. Count the frames: the row has EXACTLY 2. No people, no car, no scenery, no ground.", + "atlas": { + "height": 300, + "rows": [ + [ + { + "anim": "lamp", + "frames": 2, + "fps": 3 + } + ] + ] + }, + "despeckle": 12, + "review": "🟨 Awaiting Alexander's review (25 Oct). Playtest J7: the arena's walls were code-drawn rectangles with hazard stripes. First draw: a barrier column of red-and-white crowd-control panels strapped to a rusted pole, with a caged warning lamp (lit, dark). 300 px tall in the game, as tall as the walls. The lamp's halo specks are dropped by \"despeckle\"." } ] } diff --git a/art/sprites/boss-jenny-2.md b/art/sprites/boss-jenny-2.md index a8320af..97ccba8 100644 --- a/art/sprites/boss-jenny-2.md +++ b/art/sprites/boss-jenny-2.md @@ -1,7 +1,7 @@ # Boss · Jenny, stunned and debris -[← Boss · Jenny, attacks](boss-jenny.md) · [Sprite boards](README.md) · **17 / 31** · [Item · pocket computer →](pocket-computer.md) +[← Boss · Jenny, attacks](boss-jenny.md) · [Sprite boards](README.md) · **17 / 32** · [Item · pocket computer →](pocket-computer.md) ![Boss · Jenny, stunned and debris](images/boss-jenny-2-preview.png) @@ -29,5 +29,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/boss-jenny-2.png` · rebuild: `python scripts/make_boards.py draw boss-jenny-2 --redo --config art/sprites/boards.json` -[← Boss · Jenny, attacks](boss-jenny.md) · [Sprite boards](README.md) · **17 / 31** · [Item · pocket computer →](pocket-computer.md) +[← Boss · Jenny, attacks](boss-jenny.md) · [Sprite boards](README.md) · **17 / 32** · [Item · pocket computer →](pocket-computer.md) diff --git a/art/sprites/boss-jenny.md b/art/sprites/boss-jenny.md index 84e15dc..d131268 100644 --- a/art/sprites/boss-jenny.md +++ b/art/sprites/boss-jenny.md @@ -1,7 +1,7 @@ # Boss · Jenny, attacks -[← FX · black fluid](fx.md) · [Sprite boards](README.md) · **16 / 31** · [Boss · Jenny, stunned and debris →](boss-jenny-2.md) +[← FX · black fluid](fx.md) · [Sprite boards](README.md) · **16 / 32** · [Boss · Jenny, stunned and debris →](boss-jenny-2.md) ![Boss · Jenny, attacks](images/boss-jenny-preview.png) @@ -29,5 +29,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/boss-jenny.png` · rebuild: `python scripts/make_boards.py draw boss-jenny --redo --config art/sprites/boards.json` -[← FX · black fluid](fx.md) · [Sprite boards](README.md) · **16 / 31** · [Boss · Jenny, stunned and debris →](boss-jenny-2.md) +[← FX · black fluid](fx.md) · [Sprite boards](README.md) · **16 / 32** · [Boss · Jenny, stunned and debris →](boss-jenny-2.md) diff --git a/art/sprites/chair-block.md b/art/sprites/chair-block.md index 523a2ab..85ced64 100644 --- a/art/sprites/chair-block.md +++ b/art/sprites/chair-block.md @@ -1,7 +1,7 @@ # Chair · block -[← Chair · overhead slam](chair-overhead.md) · [Sprite boards](README.md) · **11 / 31** · [Enemy · drone →](enemy-drone.md) +[← Chair · overhead slam](chair-overhead.md) · [Sprite boards](README.md) · **11 / 32** · [Enemy · drone →](enemy-drone.md) ![Chair · block](images/chair-block-preview.png) @@ -30,5 +30,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/chair-block.png` · rebuild: `python scripts/make_boards.py draw chair-block --redo --config art/sprites/boards.json` -[← Chair · overhead slam](chair-overhead.md) · [Sprite boards](README.md) · **11 / 31** · [Enemy · drone →](enemy-drone.md) +[← Chair · overhead slam](chair-overhead.md) · [Sprite boards](README.md) · **11 / 32** · [Enemy · drone →](enemy-drone.md) diff --git a/art/sprites/chair-overhead.md b/art/sprites/chair-overhead.md index b26b124..93298e4 100644 --- a/art/sprites/chair-overhead.md +++ b/art/sprites/chair-overhead.md @@ -1,7 +1,7 @@ # Chair · overhead slam -[← Chair · side sweep](chair-side.md) · [Sprite boards](README.md) · **10 / 31** · [Chair · block →](chair-block.md) +[← Chair · side sweep](chair-side.md) · [Sprite boards](README.md) · **10 / 32** · [Chair · block →](chair-block.md) ![Chair · overhead slam](images/chair-overhead-preview.png) @@ -31,5 +31,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/chair-overhead.png` · rebuild: `python scripts/make_boards.py draw chair-overhead --redo --config art/sprites/boards.json` -[← Chair · side sweep](chair-side.md) · [Sprite boards](README.md) · **10 / 31** · [Chair · block →](chair-block.md) +[← Chair · side sweep](chair-side.md) · [Sprite boards](README.md) · **10 / 32** · [Chair · block →](chair-block.md) diff --git a/art/sprites/chair-side.md b/art/sprites/chair-side.md index 22e0bd8..ef7fdc8 100644 --- a/art/sprites/chair-side.md +++ b/art/sprites/chair-side.md @@ -1,7 +1,7 @@ # Chair · side sweep -[← The student · ladder top and bottom](hero-ladder.md) · [Sprite boards](README.md) · **9 / 31** · [Chair · overhead slam →](chair-overhead.md) +[← The student · ladder top and bottom](hero-ladder.md) · [Sprite boards](README.md) · **9 / 32** · [Chair · overhead slam →](chair-overhead.md) ![Chair · side sweep](images/chair-side-preview.png) @@ -30,5 +30,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/chair-side.png` · rebuild: `python scripts/make_boards.py draw chair-side --redo --config art/sprites/boards.json` -[← The student · ladder top and bottom](hero-ladder.md) · [Sprite boards](README.md) · **9 / 31** · [Chair · overhead slam →](chair-overhead.md) +[← The student · ladder top and bottom](hero-ladder.md) · [Sprite boards](README.md) · **9 / 32** · [Chair · overhead slam →](chair-overhead.md) diff --git a/art/sprites/coffee-machine.md b/art/sprites/coffee-machine.md index ce15838..514b0cd 100644 --- a/art/sprites/coffee-machine.md +++ b/art/sprites/coffee-machine.md @@ -1,7 +1,7 @@ # Prop · coffee machine (save point) -[← Mensa · food pickups](mensa-food.md) · [Sprite boards](README.md) · **20 / 31** · [Dexter · moves →](dexter.md) +[← Mensa · food pickups](mensa-food.md) · [Sprite boards](README.md) · **20 / 32** · [Dexter · moves →](dexter.md) ![Prop · coffee machine (save point)](images/coffee-machine-preview.png) @@ -27,5 +27,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/coffee-machine.png` · rebuild: `python scripts/make_boards.py draw coffee-machine --redo --config art/sprites/boards.json` -[← Mensa · food pickups](mensa-food.md) · [Sprite boards](README.md) · **20 / 31** · [Dexter · moves →](dexter.md) +[← Mensa · food pickups](mensa-food.md) · [Sprite boards](README.md) · **20 / 32** · [Dexter · moves →](dexter.md) diff --git a/art/sprites/dexter-acts.md b/art/sprites/dexter-acts.md index 4434bb1..f37f285 100644 --- a/art/sprites/dexter-acts.md +++ b/art/sprites/dexter-acts.md @@ -1,7 +1,7 @@ # Dexter · gestures -[← Dexter · moves](dexter.md) · [Sprite boards](README.md) · **22 / 31** · [FX · falling leaves →](fx-leaves.md) +[← Dexter · moves](dexter.md) · [Sprite boards](README.md) · **22 / 32** · [FX · falling leaves →](fx-leaves.md) ![Dexter · gestures](images/dexter-acts-preview.png) @@ -30,5 +30,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/dexter-acts.png` · rebuild: `python scripts/make_boards.py draw dexter-acts --redo --config art/sprites/boards.json` -[← Dexter · moves](dexter.md) · [Sprite boards](README.md) · **22 / 31** · [FX · falling leaves →](fx-leaves.md) +[← Dexter · moves](dexter.md) · [Sprite boards](README.md) · **22 / 32** · [FX · falling leaves →](fx-leaves.md) diff --git a/art/sprites/dexter-prologue.md b/art/sprites/dexter-prologue.md index 2505f77..c1ecee2 100644 --- a/art/sprites/dexter-prologue.md +++ b/art/sprites/dexter-prologue.md @@ -1,7 +1,7 @@ # Dexter · prologue additions -[← FX · pond ripples and lily pad](fx-water.md) · [Sprite boards](README.md) · **26 / 31** · [Menu · the Hidden Garden at first light →](menu-key.md) +[← FX · pond ripples and lily pad](fx-water.md) · [Sprite boards](README.md) · **26 / 32** · [Menu · the Hidden Garden at first light →](menu-key.md) ![Dexter · prologue additions](images/dexter-prologue-preview.png) @@ -29,5 +29,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/dexter-prologue.png` · rebuild: `python scripts/make_boards.py draw dexter-prologue --redo --config art/sprites/boards.json` -[← FX · pond ripples and lily pad](fx-water.md) · [Sprite boards](README.md) · **26 / 31** · [Menu · the Hidden Garden at first light →](menu-key.md) +[← FX · pond ripples and lily pad](fx-water.md) · [Sprite boards](README.md) · **26 / 32** · [Menu · the Hidden Garden at first light →](menu-key.md) diff --git a/art/sprites/dexter.md b/art/sprites/dexter.md index dd76632..97ab03c 100644 --- a/art/sprites/dexter.md +++ b/art/sprites/dexter.md @@ -1,7 +1,7 @@ # Dexter · moves -[← Prop · coffee machine (save point)](coffee-machine.md) · [Sprite boards](README.md) · **21 / 31** · [Dexter · gestures →](dexter-acts.md) +[← Prop · coffee machine (save point)](coffee-machine.md) · [Sprite boards](README.md) · **21 / 32** · [Dexter · gestures →](dexter-acts.md) ![Dexter · moves](images/dexter-preview.png) @@ -30,5 +30,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/dexter.png` · rebuild: `python scripts/make_boards.py draw dexter --redo --config art/sprites/boards.json` -[← Prop · coffee machine (save point)](coffee-machine.md) · [Sprite boards](README.md) · **21 / 31** · [Dexter · gestures →](dexter-acts.md) +[← Prop · coffee machine (save point)](coffee-machine.md) · [Sprite boards](README.md) · **21 / 32** · [Dexter · gestures →](dexter-acts.md) diff --git a/art/sprites/enemy-crab.md b/art/sprites/enemy-crab.md index fdd1ee2..b88eeab 100644 --- a/art/sprites/enemy-crab.md +++ b/art/sprites/enemy-crab.md @@ -1,7 +1,7 @@ # Enemy · crab -[← Enemy · rover](enemy-rover.md) · [Sprite boards](README.md) · **14 / 31** · [FX · black fluid →](fx.md) +[← Enemy · rover](enemy-rover.md) · [Sprite boards](README.md) · **14 / 32** · [FX · black fluid →](fx.md) ![Enemy · crab](images/enemy-crab-preview.png) @@ -29,5 +29,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/enemy-crab.png` · rebuild: `python scripts/make_boards.py draw enemy-crab --redo --config art/sprites/boards.json` -[← Enemy · rover](enemy-rover.md) · [Sprite boards](README.md) · **14 / 31** · [FX · black fluid →](fx.md) +[← Enemy · rover](enemy-rover.md) · [Sprite boards](README.md) · **14 / 32** · [FX · black fluid →](fx.md) diff --git a/art/sprites/enemy-drone.md b/art/sprites/enemy-drone.md index 6f94a3f..d4902d6 100644 --- a/art/sprites/enemy-drone.md +++ b/art/sprites/enemy-drone.md @@ -1,7 +1,7 @@ # Enemy · drone -[← Chair · block](chair-block.md) · [Sprite boards](README.md) · **12 / 31** · [Enemy · rover →](enemy-rover.md) +[← Chair · block](chair-block.md) · [Sprite boards](README.md) · **12 / 32** · [Enemy · rover →](enemy-rover.md) ![Enemy · drone](images/enemy-drone-preview.png) @@ -30,5 +30,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/enemy-drone.png` · rebuild: `python scripts/make_boards.py draw enemy-drone --redo --config art/sprites/boards.json` -[← Chair · block](chair-block.md) · [Sprite boards](README.md) · **12 / 31** · [Enemy · rover →](enemy-rover.md) +[← Chair · block](chair-block.md) · [Sprite boards](README.md) · **12 / 32** · [Enemy · rover →](enemy-rover.md) diff --git a/art/sprites/enemy-rover.md b/art/sprites/enemy-rover.md index ce72f0f..01159b2 100644 --- a/art/sprites/enemy-rover.md +++ b/art/sprites/enemy-rover.md @@ -1,7 +1,7 @@ # Enemy · rover -[← Enemy · drone](enemy-drone.md) · [Sprite boards](README.md) · **13 / 31** · [Enemy · crab →](enemy-crab.md) +[← Enemy · drone](enemy-drone.md) · [Sprite boards](README.md) · **13 / 32** · [Enemy · crab →](enemy-crab.md) ![Enemy · rover](images/enemy-rover-preview.png) @@ -29,5 +29,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/enemy-rover.png` · rebuild: `python scripts/make_boards.py draw enemy-rover --redo --config art/sprites/boards.json` -[← Enemy · drone](enemy-drone.md) · [Sprite boards](README.md) · **13 / 31** · [Enemy · crab →](enemy-crab.md) +[← Enemy · drone](enemy-drone.md) · [Sprite boards](README.md) · **13 / 32** · [Enemy · crab →](enemy-crab.md) diff --git a/art/sprites/fx-ground.md b/art/sprites/fx-ground.md index 6f1fbc8..0acea41 100644 --- a/art/sprites/fx-ground.md +++ b/art/sprites/fx-ground.md @@ -1,7 +1,7 @@ # FX · footstep puffs -[← FX · falling leaves](fx-leaves.md) · [Sprite boards](README.md) · **24 / 31** · [FX · pond ripples and lily pad →](fx-water.md) +[← FX · falling leaves](fx-leaves.md) · [Sprite boards](README.md) · **24 / 32** · [FX · pond ripples and lily pad →](fx-water.md) ![FX · footstep puffs](images/fx-ground-preview.png) @@ -29,5 +29,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/fx-ground.png` · rebuild: `python scripts/make_boards.py draw fx-ground --redo --config art/sprites/boards.json` -[← FX · falling leaves](fx-leaves.md) · [Sprite boards](README.md) · **24 / 31** · [FX · pond ripples and lily pad →](fx-water.md) +[← FX · falling leaves](fx-leaves.md) · [Sprite boards](README.md) · **24 / 32** · [FX · pond ripples and lily pad →](fx-water.md) diff --git a/art/sprites/fx-leaves.md b/art/sprites/fx-leaves.md index a09a308..1c796b8 100644 --- a/art/sprites/fx-leaves.md +++ b/art/sprites/fx-leaves.md @@ -1,7 +1,7 @@ # FX · falling leaves -[← Dexter · gestures](dexter-acts.md) · [Sprite boards](README.md) · **23 / 31** · [FX · footstep puffs →](fx-ground.md) +[← Dexter · gestures](dexter-acts.md) · [Sprite boards](README.md) · **23 / 32** · [FX · footstep puffs →](fx-ground.md) ![FX · falling leaves](images/fx-leaves-preview.png) @@ -29,5 +29,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/fx-leaves.png` · rebuild: `python scripts/make_boards.py draw fx-leaves --redo --config art/sprites/boards.json` -[← Dexter · gestures](dexter-acts.md) · [Sprite boards](README.md) · **23 / 31** · [FX · footstep puffs →](fx-ground.md) +[← Dexter · gestures](dexter-acts.md) · [Sprite boards](README.md) · **23 / 32** · [FX · footstep puffs →](fx-ground.md) diff --git a/art/sprites/fx-water.md b/art/sprites/fx-water.md index 718436e..da78d76 100644 --- a/art/sprites/fx-water.md +++ b/art/sprites/fx-water.md @@ -1,7 +1,7 @@ # FX · pond ripples and lily pad -[← FX · footstep puffs](fx-ground.md) · [Sprite boards](README.md) · **25 / 31** · [Dexter · prologue additions →](dexter-prologue.md) +[← FX · footstep puffs](fx-ground.md) · [Sprite boards](README.md) · **25 / 32** · [Dexter · prologue additions →](dexter-prologue.md) ![FX · pond ripples and lily pad](images/fx-water-preview.png) @@ -28,5 +28,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/fx-water.png` · rebuild: `python scripts/make_boards.py draw fx-water --redo --config art/sprites/boards.json` -[← FX · footstep puffs](fx-ground.md) · [Sprite boards](README.md) · **25 / 31** · [Dexter · prologue additions →](dexter-prologue.md) +[← FX · footstep puffs](fx-ground.md) · [Sprite boards](README.md) · **25 / 32** · [Dexter · prologue additions →](dexter-prologue.md) diff --git a/art/sprites/fx.md b/art/sprites/fx.md index d129282..112bac9 100644 --- a/art/sprites/fx.md +++ b/art/sprites/fx.md @@ -1,7 +1,7 @@ # FX · black fluid -[← Enemy · crab](enemy-crab.md) · [Sprite boards](README.md) · **15 / 31** · [Boss · Jenny, attacks →](boss-jenny.md) +[← Enemy · crab](enemy-crab.md) · [Sprite boards](README.md) · **15 / 32** · [Boss · Jenny, attacks →](boss-jenny.md) ![FX · black fluid](images/fx-preview.png) @@ -26,5 +26,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/fx.png` · rebuild: `python scripts/make_boards.py draw fx --redo --config art/sprites/boards.json` -[← Enemy · crab](enemy-crab.md) · [Sprite boards](README.md) · **15 / 31** · [Boss · Jenny, attacks →](boss-jenny.md) +[← Enemy · crab](enemy-crab.md) · [Sprite boards](README.md) · **15 / 32** · [Boss · Jenny, attacks →](boss-jenny.md) diff --git a/art/sprites/hero-air.md b/art/sprites/hero-air.md index a79eca9..ba55d04 100644 --- a/art/sprites/hero-air.md +++ b/art/sprites/hero-air.md @@ -1,7 +1,7 @@ # The student · jump, fall, climb -[← The student · death](hero-death.md) · [Sprite boards](README.md) · **7 / 31** · [The student · ladder top and bottom →](hero-ladder.md) +[← The student · death](hero-death.md) · [Sprite boards](README.md) · **7 / 32** · [The student · ladder top and bottom →](hero-ladder.md) ![The student · jump, fall, climb](images/hero-air-preview.png) @@ -26,5 +26,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hero-air.png` · rebuild: `python scripts/make_boards.py draw hero-air --redo --config art/sprites/boards.json` -[← The student · death](hero-death.md) · [Sprite boards](README.md) · **7 / 31** · [The student · ladder top and bottom →](hero-ladder.md) +[← The student · death](hero-death.md) · [Sprite boards](README.md) · **7 / 32** · [The student · ladder top and bottom →](hero-ladder.md) diff --git a/art/sprites/hero-death.md b/art/sprites/hero-death.md index b9bcb3f..18a506a 100644 --- a/art/sprites/hero-death.md +++ b/art/sprites/hero-death.md @@ -1,7 +1,7 @@ # The student · death -[← The student · hurt and interact](hero-hurt.md) · [Sprite boards](README.md) · **6 / 31** · [The student · jump, fall, climb →](hero-air.md) +[← The student · hurt and interact](hero-hurt.md) · [Sprite boards](README.md) · **6 / 32** · [The student · jump, fall, climb →](hero-air.md) ![The student · death](images/hero-death-preview.png) @@ -26,5 +26,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hero-death.png` · rebuild: `python scripts/make_boards.py draw hero-death --redo --config art/sprites/boards.json` -[← The student · hurt and interact](hero-hurt.md) · [Sprite boards](README.md) · **6 / 31** · [The student · jump, fall, climb →](hero-air.md) +[← The student · hurt and interact](hero-hurt.md) · [Sprite boards](README.md) · **6 / 32** · [The student · jump, fall, climb →](hero-air.md) diff --git a/art/sprites/hero-hurt.md b/art/sprites/hero-hurt.md index 9199c1b..a976659 100644 --- a/art/sprites/hero-hurt.md +++ b/art/sprites/hero-hurt.md @@ -1,7 +1,7 @@ # The student · hurt and interact -[← The student · run](hero-run.md) · [Sprite boards](README.md) · **5 / 31** · [The student · death →](hero-death.md) +[← The student · run](hero-run.md) · [Sprite boards](README.md) · **5 / 32** · [The student · death →](hero-death.md) ![The student · hurt and interact](images/hero-hurt-preview.png) @@ -26,5 +26,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hero-hurt.png` · rebuild: `python scripts/make_boards.py draw hero-hurt --redo --config art/sprites/boards.json` -[← The student · run](hero-run.md) · [Sprite boards](README.md) · **5 / 31** · [The student · death →](hero-death.md) +[← The student · run](hero-run.md) · [Sprite boards](README.md) · **5 / 32** · [The student · death →](hero-death.md) diff --git a/art/sprites/hero-idle.md b/art/sprites/hero-idle.md index b58e4f7..7f2d217 100644 --- a/art/sprites/hero-idle.md +++ b/art/sprites/hero-idle.md @@ -1,7 +1,7 @@ # The student · idle variants -[← The student · walk](hero-move.md) · [Sprite boards](README.md) · **3 / 31** · [The student · run →](hero-run.md) +[← The student · walk](hero-move.md) · [Sprite boards](README.md) · **3 / 32** · [The student · run →](hero-run.md) ![The student · idle variants](images/hero-idle-preview.png) @@ -26,5 +26,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hero-idle.png` · rebuild: `python scripts/make_boards.py draw hero-idle --redo --config art/sprites/boards.json` -[← The student · walk](hero-move.md) · [Sprite boards](README.md) · **3 / 31** · [The student · run →](hero-run.md) +[← The student · walk](hero-move.md) · [Sprite boards](README.md) · **3 / 32** · [The student · run →](hero-run.md) diff --git a/art/sprites/hero-ladder.md b/art/sprites/hero-ladder.md index 2616b9c..46de9a6 100644 --- a/art/sprites/hero-ladder.md +++ b/art/sprites/hero-ladder.md @@ -1,7 +1,7 @@ # The student · ladder top and bottom -[← The student · jump, fall, climb](hero-air.md) · [Sprite boards](README.md) · **8 / 31** · [Chair · side sweep →](chair-side.md) +[← The student · jump, fall, climb](hero-air.md) · [Sprite boards](README.md) · **8 / 32** · [Chair · side sweep →](chair-side.md) ![The student · ladder top and bottom](images/hero-ladder-preview.png) @@ -26,5 +26,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hero-ladder.png` · rebuild: `python scripts/make_boards.py draw hero-ladder --redo --config art/sprites/boards.json` -[← The student · jump, fall, climb](hero-air.md) · [Sprite boards](README.md) · **8 / 31** · [Chair · side sweep →](chair-side.md) +[← The student · jump, fall, climb](hero-air.md) · [Sprite boards](README.md) · **8 / 32** · [Chair · side sweep →](chair-side.md) diff --git a/art/sprites/hero-move.md b/art/sprites/hero-move.md index fd96aa5..0189ebe 100644 --- a/art/sprites/hero-move.md +++ b/art/sprites/hero-move.md @@ -1,7 +1,7 @@ # The student · walk -[← The student · hero design](hero.md) · [Sprite boards](README.md) · **2 / 31** · [The student · idle variants →](hero-idle.md) +[← The student · hero design](hero.md) · [Sprite boards](README.md) · **2 / 32** · [The student · idle variants →](hero-idle.md) ![The student · walk](images/hero-move-preview.png) @@ -26,5 +26,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hero-move.png` · rebuild: `python scripts/make_boards.py draw hero-move --redo --config art/sprites/boards.json` -[← The student · hero design](hero.md) · [Sprite boards](README.md) · **2 / 31** · [The student · idle variants →](hero-idle.md) +[← The student · hero design](hero.md) · [Sprite boards](README.md) · **2 / 32** · [The student · idle variants →](hero-idle.md) diff --git a/art/sprites/hero-run.md b/art/sprites/hero-run.md index 6c8a070..cd8da67 100644 --- a/art/sprites/hero-run.md +++ b/art/sprites/hero-run.md @@ -1,7 +1,7 @@ # The student · run -[← The student · idle variants](hero-idle.md) · [Sprite boards](README.md) · **4 / 31** · [The student · hurt and interact →](hero-hurt.md) +[← The student · idle variants](hero-idle.md) · [Sprite boards](README.md) · **4 / 32** · [The student · hurt and interact →](hero-hurt.md) ![The student · run](images/hero-run-preview.png) @@ -26,5 +26,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hero-run.png` · rebuild: `python scripts/make_boards.py draw hero-run --redo --config art/sprites/boards.json` -[← The student · idle variants](hero-idle.md) · [Sprite boards](README.md) · **4 / 31** · [The student · hurt and interact →](hero-hurt.md) +[← The student · idle variants](hero-idle.md) · [Sprite boards](README.md) · **4 / 32** · [The student · hurt and interact →](hero-hurt.md) diff --git a/art/sprites/hero.md b/art/sprites/hero.md index 687c795..6d24bb6 100644 --- a/art/sprites/hero.md +++ b/art/sprites/hero.md @@ -1,7 +1,7 @@ # The student · hero design -[← Sprite boards](README.md) · [Sprite boards](README.md) · **1 / 31** · [The student · walk →](hero-move.md) +[← Sprite boards](README.md) · [Sprite boards](README.md) · **1 / 32** · [The student · walk →](hero-move.md) ![The student · hero design](images/hero-preview.png) @@ -21,5 +21,5 @@ Keep the body, height (6 ft adult), proportions, pose, backpack, grey slim jeans Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/hero.png` · rebuild: `python scripts/make_boards.py draw hero --redo --config art/sprites/boards.json` -[← Sprite boards](README.md) · [Sprite boards](README.md) · **1 / 31** · [The student · walk →](hero-move.md) +[← Sprite boards](README.md) · [Sprite boards](README.md) · **1 / 32** · [The student · walk →](hero-move.md) diff --git a/art/sprites/images/arena-wall-preview.png b/art/sprites/images/arena-wall-preview.png new file mode 100644 index 0000000..5e2e523 Binary files /dev/null and b/art/sprites/images/arena-wall-preview.png differ diff --git a/art/sprites/images/arena-wall.png b/art/sprites/images/arena-wall.png new file mode 100644 index 0000000..c5d2825 Binary files /dev/null and b/art/sprites/images/arena-wall.png differ diff --git a/art/sprites/it-props.md b/art/sprites/it-props.md index 858c6c3..9c27acf 100644 --- a/art/sprites/it-props.md +++ b/art/sprites/it-props.md @@ -1,7 +1,7 @@ # Props · the storm drain's IT details -[← Menu · the Hidden Garden at first light](menu-key.md) · [Sprite boards](README.md) · **28 / 31** · [Secret · the rubber chicken →](rubber-chicken.md) +[← Menu · the Hidden Garden at first light](menu-key.md) · [Sprite boards](README.md) · **28 / 32** · [Secret · the rubber chicken →](rubber-chicken.md) ![Props · the storm drain's IT details](images/it-props-preview.png) @@ -27,5 +27,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/it-props.png` · rebuild: `python scripts/make_boards.py draw it-props --redo --config art/sprites/boards.json` -[← Menu · the Hidden Garden at first light](menu-key.md) · [Sprite boards](README.md) · **28 / 31** · [Secret · the rubber chicken →](rubber-chicken.md) +[← Menu · the Hidden Garden at first light](menu-key.md) · [Sprite boards](README.md) · **28 / 32** · [Secret · the rubber chicken →](rubber-chicken.md) diff --git a/art/sprites/mensa-food.md b/art/sprites/mensa-food.md index 9be2e1e..ae744d6 100644 --- a/art/sprites/mensa-food.md +++ b/art/sprites/mensa-food.md @@ -1,7 +1,7 @@ # Mensa · food pickups -[← Item · pocket computer](pocket-computer.md) · [Sprite boards](README.md) · **19 / 31** · [Prop · coffee machine (save point) →](coffee-machine.md) +[← Item · pocket computer](pocket-computer.md) · [Sprite boards](README.md) · **19 / 32** · [Prop · coffee machine (save point) →](coffee-machine.md) ![Mensa · food pickups](images/mensa-food-preview.png) @@ -30,5 +30,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/mensa-food.png` · rebuild: `python scripts/make_boards.py draw mensa-food --redo --config art/sprites/boards.json` -[← Item · pocket computer](pocket-computer.md) · [Sprite boards](README.md) · **19 / 31** · [Prop · coffee machine (save point) →](coffee-machine.md) +[← Item · pocket computer](pocket-computer.md) · [Sprite boards](README.md) · **19 / 32** · [Prop · coffee machine (save point) →](coffee-machine.md) diff --git a/art/sprites/menu-key.md b/art/sprites/menu-key.md index 31c7b9a..b5f0dd1 100644 --- a/art/sprites/menu-key.md +++ b/art/sprites/menu-key.md @@ -1,7 +1,7 @@ # Menu · the Hidden Garden at first light -[← Dexter · prologue additions](dexter-prologue.md) · [Sprite boards](README.md) · **27 / 31** · [Props · the storm drain's IT details →](it-props.md) +[← Dexter · prologue additions](dexter-prologue.md) · [Sprite boards](README.md) · **27 / 32** · [Props · the storm drain's IT details →](it-props.md) ![Menu · the Hidden Garden at first light](images/menu-key-preview.png) @@ -22,5 +22,5 @@ Key art for the game's title menu, a full 16:9 picture in exactly the hi-bit pix Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/menu-key.png` · rebuild: `python scripts/make_boards.py draw menu-key --redo --config art/sprites/boards.json` -[← Dexter · prologue additions](dexter-prologue.md) · [Sprite boards](README.md) · **27 / 31** · [Props · the storm drain's IT details →](it-props.md) +[← Dexter · prologue additions](dexter-prologue.md) · [Sprite boards](README.md) · **27 / 32** · [Props · the storm drain's IT details →](it-props.md) diff --git a/art/sprites/pocket-computer.md b/art/sprites/pocket-computer.md index 2395a6f..b8e4d78 100644 --- a/art/sprites/pocket-computer.md +++ b/art/sprites/pocket-computer.md @@ -1,7 +1,7 @@ # Item · pocket computer -[← Boss · Jenny, stunned and debris](boss-jenny-2.md) · [Sprite boards](README.md) · **18 / 31** · [Mensa · food pickups →](mensa-food.md) +[← Boss · Jenny, stunned and debris](boss-jenny-2.md) · [Sprite boards](README.md) · **18 / 32** · [Mensa · food pickups →](mensa-food.md) ![Item · pocket computer](images/pocket-computer-preview.png) @@ -28,5 +28,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/pocket-computer.png` · rebuild: `python scripts/make_boards.py draw pocket-computer --redo --config art/sprites/boards.json` -[← Boss · Jenny, stunned and debris](boss-jenny-2.md) · [Sprite boards](README.md) · **18 / 31** · [Mensa · food pickups →](mensa-food.md) +[← Boss · Jenny, stunned and debris](boss-jenny-2.md) · [Sprite boards](README.md) · **18 / 32** · [Mensa · food pickups →](mensa-food.md) diff --git a/art/sprites/rubber-chicken.md b/art/sprites/rubber-chicken.md index cc998a9..eb4216d 100644 --- a/art/sprites/rubber-chicken.md +++ b/art/sprites/rubber-chicken.md @@ -1,7 +1,7 @@ # Secret · the rubber chicken -[← Props · the storm drain's IT details](it-props.md) · [Sprite boards](README.md) · **29 / 31** · [Prop · Jenny's arena platforms →](arena-platform.md) +[← Props · the storm drain's IT details](it-props.md) · [Sprite boards](README.md) · **29 / 32** · [Prop · Jenny's arena platforms →](arena-platform.md) ![Secret · the rubber chicken](images/rubber-chicken-preview.png) @@ -20,5 +20,5 @@ On a flat, solid, pure magenta #FF00FF background (no paper colour, no ground sh Model `gpt-image-2.5-sunburst` · pixel factor 2 · source image `images/rubber-chicken.png` · rebuild: `python scripts/make_boards.py draw rubber-chicken --redo --config art/sprites/boards.json` -[← Props · the storm drain's IT details](it-props.md) · [Sprite boards](README.md) · **29 / 31** · [Prop · Jenny's arena platforms →](arena-platform.md) +[← Props · the storm drain's IT details](it-props.md) · [Sprite boards](README.md) · **29 / 32** · [Prop · Jenny's arena platforms →](arena-platform.md) diff --git a/art/stages/rusty-creek/previews/arena-platforms.png b/art/stages/rusty-creek/previews/arena-platforms.png index 2223980..e62807c 100644 Binary files a/art/stages/rusty-creek/previews/arena-platforms.png and b/art/stages/rusty-creek/previews/arena-platforms.png differ diff --git a/game/public/assets/sprites/arena-wall.anims.json b/game/public/assets/sprites/arena-wall.anims.json new file mode 100644 index 0000000..f5b34bc --- /dev/null +++ b/game/public/assets/sprites/arena-wall.anims.json @@ -0,0 +1,7 @@ +{ + "lamp": { + "frames": 2, + "fps": 3, + "loop": true + } +} diff --git a/game/public/assets/sprites/arena-wall.json b/game/public/assets/sprites/arena-wall.json new file mode 100644 index 0000000..8fa8aed --- /dev/null +++ b/game/public/assets/sprites/arena-wall.json @@ -0,0 +1,62 @@ +{ + "frames": { + "lamp-00": { + "frame": { + "x": 0, + "y": 0, + "w": 56, + "h": 304 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 304 + }, + "sourceSize": { + "w": 56, + "h": 304 + }, + "pivot": { + "x": 0.5, + "y": 1 + } + }, + "lamp-01": { + "frame": { + "x": 58, + "y": 0, + "w": 56, + "h": 304 + }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 56, + "h": 304 + }, + "sourceSize": { + "w": 56, + "h": 304 + }, + "pivot": { + "x": 0.5, + "y": 1 + } + } + }, + "meta": { + "app": "scripts/export_atlas.py", + "image": "arena-wall.png", + "format": "RGBA8888", + "size": { + "w": 114, + "h": 304 + }, + "scale": "1" + } +} diff --git a/game/public/assets/sprites/arena-wall.png b/game/public/assets/sprites/arena-wall.png new file mode 100644 index 0000000..1d7f1b5 Binary files /dev/null and b/game/public/assets/sprites/arena-wall.png differ diff --git a/game/src/enemies/jennyBoss.ts b/game/src/enemies/jennyBoss.ts index 6ce953a..8898549 100644 --- a/game/src/enemies/jennyBoss.ts +++ b/game/src/enemies/jennyBoss.ts @@ -59,7 +59,7 @@ export class JennyBoss { private parts = new Map(); private shadows = new Map(); /** The arena's two walls, drawn while they are closed so they are never invisible. */ - private barriers: Phaser.GameObjects.Graphics[] = []; + private barriers: (Phaser.GameObjects.Graphics | Phaser.GameObjects.Sprite)[] = []; /** Her path in the rev: a strip on the floor from her nose to the wall she will hit. */ private path?: Phaser.GameObjects.Rectangle; /** Stars circling over her while she is stunned: she is dazed, hit her now. */ @@ -124,8 +124,17 @@ export class JennyBoss { this.hud?.model?.showBoss(NAME, JENNY_HEALTH); } - /** A closed wall: a rusted barrier with hazard stripes, so it reads as "not until she is beaten". */ - private drawBarrier(box: Box): Phaser.GameObjects.Graphics { + /** + * A closed wall reads as "not until she is beaten": the barrier column (`arena-wall` board, its warning lamp + * blinking), standing on the wall's foot; without the board, a rusted barrier with hazard stripes. + */ + private drawBarrier(box: Box): Phaser.GameObjects.Graphics | Phaser.GameObjects.Sprite { + if (this.scene.textures.exists('arena-wall')) { + if (!this.scene.anims.exists('arena-wall:lamp')) this.scene.anims.create({ key: 'arena-wall:lamp', frameRate: 3, repeat: -1, + frames: this.scene.anims.generateFrameNames('arena-wall', { prefix: 'lamp-', start: 0, end: 1, zeroPad: 2 }) }); + return this.scene.add.sprite(box.x + box.w / 2, box.y + box.h, 'arena-wall', 'lamp-00').setOrigin(0.5, 1) + .setDepth(DEPTH + 3).setAlpha(0).play('arena-wall:lamp'); + } const g = this.scene.add.graphics({ x: box.x, y: box.y }).setDepth(DEPTH + 3).setAlpha(0); g.fillStyle(0x3a2418, 0.85).fillRect(0, 0, box.w, box.h); g.lineStyle(2, 0xc8642a, 1).strokeRect(1, 1, box.w - 2, box.h - 2); diff --git a/game/src/stage/boards.json b/game/src/stage/boards.json index f7125f3..1e018b8 100644 --- a/game/src/stage/boards.json +++ b/game/src/stage/boards.json @@ -8,5 +8,5 @@ "boss-jenny", "boss-jenny-2", "coffee-machine", "dexter", "dexter-acts", "dexter-prologue", "pocket-computer", "mensa-food" ], - "optional": ["it-props", "rubber-chicken"] + "optional": ["it-props", "rubber-chicken", "arena-wall"] } diff --git a/references/reading-order.json b/references/reading-order.json index 0303ff2..eae67b1 100644 --- a/references/reading-order.json +++ b/references/reading-order.json @@ -49,11 +49,11 @@ }, { "path": "references/games/drova-forsaken-kin/README.md", - "label": "Drova – Forsaken Kin" + "label": "Drova – Forsaken Kin" }, { "path": "references/games/drova-forsaken-kin/visual-reference.md", - "label": "Drova – Forsaken Kin · gallery" + "label": "Drova – Forsaken Kin · gallery" }, { "path": "references/games/kingdom-two-crowns/README.md", diff --git a/scripts/check_docs.py b/scripts/check_docs.py index 6e8de02..6aa1a6b 100644 --- a/scripts/check_docs.py +++ b/scripts/check_docs.py @@ -6,6 +6,8 @@ - no byte-identical tracked files, no tracked file over 6 MB - every committed board image belongs to a board in its config - no photos, audio or keys tracked anywhere +- no double-encoded text (UTF-8 read as Windows-1252 and saved again, so an en dash or a check mark turns into + two or three Latin-1 letters) """ from __future__ import annotations @@ -29,6 +31,16 @@ capture_output=True, check=True).stdout.decode().split('\0') if p] tracked = [p for p in tracked if p.exists()] +# UTF-8 bytes read as Windows-1252 and written back as UTF-8: the lead bytes of "–", "“", "✅", "🟨", "ä" turn +# into these pairs. A script that reads git's output in the console's code page does it to a whole file. +_PAIRS = ((0xE2, 0x20AC), (0xE2, 0x153), (0xF0, 0x178)) # the pairs, by code point, so this file stays clean +_AFTER_C3 = (0xA4, 0xB6, 0xBC, 0x178, 0x2013, 0x153, 0xA9) +MOJIBAKE = re.compile('|'.join(''.join(map(chr, pair)) for pair in _PAIRS) + '|' + chr(0xC3) + '[' + ''.join(map(chr, _AFTER_C3)) + ']') +for path in (p for p in tracked if p.suffix in ('.md', '.json', '.ts', '.py', '.csv')): + found = MOJIBAKE.search(path.read_text(encoding='utf-8-sig', errors='replace')) + if found: + errors.append(f'{path.relative_to(ROOT)}: double-encoded text ({found.group(0)!r}), re-save it from the UTF-8 source') + for path in (p for p in tracked if p.suffix == '.md'): text = path.read_text(encoding='utf-8-sig') for target in re.findall(r'\]\(([^)\s]+)', text): diff --git a/scripts/make_boards.py b/scripts/make_boards.py index bbdbac6..474658a 100644 --- a/scripts/make_boards.py +++ b/scripts/make_boards.py @@ -275,6 +275,8 @@ def crush(board: dict) -> None: else: small = image.resize(size, Image.Resampling.BOX).convert("RGBA") alpha = small.getchannel("A").point(lambda a: 255 if a >= 128 else 0) + if board.get("despeckle"): + alpha = despeckle(alpha, board["despeckle"]) colours = small.convert("RGB").quantize(board.get("colours", COLOURS), method=Image.Quantize.MEDIANCUT, dither=Image.Dither.NONE) sprite = colours.convert("RGBA") @@ -289,6 +291,36 @@ def crush(board: dict) -> None: print(f"{board['id']}: {small.width}x{small.height} sprite + preview") +def despeckle(alpha: Image.Image, smaller_than: int) -> Image.Image: + """Drop the islands of opaque pixels smaller than `smaller_than` (8-connected): a glow the model drew as a soft + halo crushes into scattered specks, which read as noise over any backdrop (backdrop_check.py). The game draws + glows itself.""" + w, h = alpha.size + solid = [v > 0 for v in alpha.getdata()] + seen = [False] * (w * h) + out = alpha.copy() + for start in range(w * h): + if not solid[start] or seen[start]: + continue + island, todo = [start], [start] + seen[start] = True + while todo: + i = todo.pop() + x, y = i % w, i // w + for dx in (-1, 0, 1): + for dy in (-1, 0, 1): + nx, ny = x + dx, y + dy + j = ny * w + nx + if 0 <= nx < w and 0 <= ny < h and solid[j] and not seen[j]: + seen[j] = True + island.append(j) + todo.append(j) + if len(island) < smaller_than: + for i in island: + out.putpixel((i % w, i // w), 0) + return out + + def describe(ref: str) -> str: ref, _, box = ref.partition("@") if box: diff --git a/scripts/test_make_boards.py b/scripts/test_make_boards.py index ae30821..9a39d1d 100644 --- a/scripts/test_make_boards.py +++ b/scripts/test_make_boards.py @@ -38,6 +38,20 @@ def test_no_hole_without_enclosed_magenta(self): self.assertIsNone(mb.hole_mask(image).getbbox()) +class DespeckleTests(unittest.TestCase): + def test_small_islands_go_and_the_sprite_and_its_attached_glow_stay(self): + alpha = Image.new('L', (20, 20), 0) + alpha.paste(255, (5, 5, 15, 15)) # the sprite + alpha.putpixel((15, 4), 255) # glow touching it diagonally: part of it + alpha.putpixel((1, 1), 255) # a lone speck + alpha.paste(255, (18, 18, 20, 20)) # a 4-pixel island + out = mb.despeckle(alpha, 5) + self.assertEqual(out.getpixel((1, 1)), 0) + self.assertEqual(out.getpixel((19, 19)), 0) + self.assertEqual(out.getpixel((15, 4)), 255) + self.assertEqual(out.getpixel((10, 10)), 255) + + class BoardPipelineTests(unittest.TestCase): def setUp(self): self.tmp = tempfile.TemporaryDirectory()