Collapse the spiky/sticky/skewer box-variant assets into a single per-
instance `adhesion` property on any moveable block, chosen in the editor
via a dropdown next to the colour picker and stored in the .sav alongside
the class.
- spiky -> sticky: soft grab on every true edge (goopy shader)
- skewer -> gluey: rigid weld on every true edge (spiked outline)
- old trailing-face sticky is removed; its saves fold into new sticky
Move the spike geometry + drawGlueySprite into shaders.lua, fold drawing
and the adhesion flag into GenericMoveable, and delete the three
Generic{Sticky,Spiky,Skewer} classes and box_variants.lua. Room:createEntity
normalises legacy spiky_/skewer_/sticky_ class prefixes so old saves load,
and serialization emits `adhesion`. World/map previews and the movement
proxy follow the rename.
Backfill rooms/*.sav to the new format via tools/backfill_adhesion.lua
(41 objects across 8 files). Update tests to the two-mode model; the two
tests asserting the removed lateral-shear limitation are dropped and a
legacy-load migration test added. 27/27 pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Mark: a debug non-collidable named destination (pixel-art target icon),
editor tool + name modal, globally-unique names, programmatic Room:addMark
- NPCs walk to Marks: each RGB copy is a per-room resident (like the player),
running its own A* on its own colour layer, transferring rooms as it crosses
seams; rendered and collided by the room it currently stands in
- Player copies are obstacles in NPC pathfinding
- A* is footprint-aware for multi-cell NPCs
- Editor: click an NPC to open a filterable destination picker
- Ink: Dialogue.open binds walk_to; Jorge can be sent to "end"/"begin"
- Fix: a blocked NPC now replans each tick and resumes instead of freezing
- [npc] move diagnostics under DEBUG (start/goal/route or block reason)
- Docs (adding-npcs) + CLAUDE.md LÖVE 11.x/float-colour corrections
- Fix test harness loadSprite stub; movement tests green (28)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generate 1x2/2x1 dominoes, 2x2 (square + 4 L-trominoes) and all
connected 3x2/2x3 polyominoes as R/G/B channel masks, reusing the
distance-based concentric-ring format that reproduces box_r/g/b
exactly. Outer silhouette keeps a 1px margin; connected cells stay
seamless. Each shape ships a {class="moveable"} .meta so getAllAssets
auto-registers it as a GenericMoveable.
Wire the occupied-cell shape (precomputed once by getAllAssets via
getCellsFromSprite) through to entities: createEntity now passes the
cached cells as cellShape, so an L/U/notched block collides on its real
cells and its gaps read as empty space. Fix the per-colour cache that
was reset every channel so only one colour survived.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>