SMOOSH level editor

Paint a chamber, watch the validator, then copy the rows array into shared/levels.ts. Legend: # wall  . floor  S spawn  D door  * shard  K socket  B battery  Y power-swap shrine  1–5 alcove mouths with pads a–e (the tool stamps mouth + corridor + pad together so the pair is always axis-aligned and exactly 2 tiles apart — press R to rotate the stamp).

Build a set of chambers with the tabs above the canvas — up to seven, played in order. Play live sends the whole set to the server, which re-validates every chamber and creates a fresh room — share the link and play immediately, no deploy. From the second chamber on, sets get power-swap shrines just like the authored run — paint a Y to place that chamber's shrine yourself instead (one per chamber; in authored mode it must leave every pad, mouth, item and the door reachable, since a shrine is solid). Custom rooms wind down ~10 minutes after everyone leaves; to make chambers permanent, export the rows into shared/levels.ts.

SET

Palette

Grid × (16×12 to 28×18 — click paints, drag paints walls/floor)

Validation

    Same checks as scripts/check-levels.mjs: single S/D, five complete alcove pairs on the 2-tile axis rule, and flood-fill reachability (walls and shrines block) of the door, every mouth, every shard, socket and battery from S.

    Preview

    Play live

    Name and timing are per chamber — switch tabs to set each. The room plays the set in tab order. Drafts autosave in this browser.

    Share & publish

    Share puts the whole draft in the link itself — opening it imports the set into that browser's editor. Publish puts the set on the public shelf (“Community levels” on the landing page), where anyone can mint a room from it. Both use the set exactly as the tabs show it now.

    Export

    Paste as a rows array in shared/levels.ts (the same shape as the TOP/INTERIORS/BOTTOM blocks), then run npm run check:levels and redeploy.

    Import