Engine: pit-rim exits live in one helper (pitRimExits) shared by the
resolver and the automaton; chargeReach names the six-stride cap; dust
sight is inDust + dustAtEnd; PushPending is exported once; the force-field
counter builds its events in one list; drawUnderSlowDeath says what it
draws under. Test groups are named for the rule they pin, not the
revision that introduced it.
Client: one smoothstep; one edgeScar per battle-scarred edge; one
board-zone rule (which also seats the caption strip on phones); the
compass names live in SIDE_NAMES; net.flash() is the one toast; MediaQuery
replaces two hand-rolled matchMedia listeners; sprites carry their sizes
as plain numbers and their CSS in one rule each; canvas helpers are
formatted like the rest of the tree. Comments that told how a cel or a
fallback used to look now say what it draws. The actions-over notice no
longer blames a pickup when slime ended the turn.
Server and ops: dataRoot() is the one data directory; headlineOf builds
its deeds without a cast; the rollup and skills read the same way the
code behaves.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
One shared motion policy: the OS's reduce-motion setting, read live
through Svelte's own media query, folds into the flourishes switch.
Under it the board plays no flourishes, the reel skips its die
interlude and slate wipes, bodies jump between squares instead of
gliding, the canvas holds its ambient shimmers still, and the camera
cuts wherever the director would have panned — in the cockpit as in
the reel, so the eye still lands on what the director chose to watch.
Timers and animation frames are cleared when the policy flips or the
pane closes. A first turn and two reels stepped clean under the
setting with no errors.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
The last of the inked look. Walls carry stone joints and highlights,
doors their grain, hinges, and a brass lock plate whose keyhole turns
to a cross when jammed; battle scars fracture and branch with the
damage; illusion walls drift as tapered wisps with breathing glints;
the wall of fire burns in flat three-tone flames on a stepped flicker;
warp mouths and destinations are painted curls. Through a wizard's
eyes the punch is a three-tone hand with an ink contour and a
hand-cut POW, the same on every platform where the emoji glyph was
not, and the incoming fist no longer reverses late in its travel. The
inked stand-ins for missing conjuration files match. Goldens
re-blessed: every board frame, and the web's third ring.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
The eleventh scene, written for the new conjurations. Wanderer fills
the corridor between them with a dust cloud — no sight, no spells —
so Rival lays a dimensional warp with one mouth under his own feet
and the other at her back, steps through the light, and lands on her
square fists first. She bolts into her own cloud, and the die picks
where she goes: into a wall. Three beats through the eyes — the cloud
billowing, the arrival, the blind stagger with the far pillar of light
at the corridor's end — and the board at the arrival.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
Kestrel stood beside a pit dug against the board's west edge, walls
north and south of it, and was told there was nothing to land on — the
rim check counted only neighbouring squares, and the warp mouth beyond
the pit is not one. From rev 17 a mouth on the rim is an exit like any
square, named at a fork like any other; every older game takes the
mouth when no square offers, so the refused crossing goes through as
it stands. The jump through a mouth carries `via: "warp"`: the board
shimmers both mouths instead of streaking across the maze, and the
reel cuts rather than gliding. The automaton leaves a pit only by its
exits. Three tests walk the rim under both readings.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
Two blind reviews of everything since the last pass (afa0e17), every
finding checked against the code, no behavior changed: all thirty
scene goldens match without a re-bless and the engine suite is
untouched.
Reel and renderer: the camera's look-down rule is stated once, beside
LOOK_DOWN, instead of twice in the effect; the empty aim branch that
stood where a cutaway used to be is gone (the guard it implied is now
explicit); the pit events and the punch are handled by their own
types, not through "in" casts; smoothstep is one export used by every
tween instead of eleven inline copies; the two floor rings share one
painter; project() takes a Billboard instead of a third hand-typed
copy of its fields; the strides-left figure and the web rim no longer
shadow the reel's steps and the pane's fx; the die card's verdict is
built from events, not by matching an emoji; the workshop asks for the
hover cue by name instead of passing an empty click handler.
Server and engine: one requestBase() for the origin, one slug pattern
in store.ts gating both the clip page and its files, one 404 for both;
LOOPBACK sits above its only caller; doCounteract names what a counter
is played against once; fearCells sits beside its own docblock rather
than between sightedCellsFor and its.
Deploy: chromiumExe, the private server, ffmpeg, and the reel rewind
live in deploy/lib/harness.mjs, shared by the gate, the recorder, and
the card cutter instead of pasted three times; the recorder drops its
duplicate frame counters and names its poster settle; the card uses the
gallery's exact gold; the one-time Sentry URL bootstrap leaves
deploy.sh; the backup comment states the rule rather than the incident.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
Springing the Trap never showed its fireball: Rival stepped into the
watched corridor facing the way he walked, and the ambush's fireball
flew in from the mouth behind him while only the caption told of it.
The director now aims at incoming magic and punches — the caster's or
attacker's square, straight or through a mouth — and a stride that
ends with something to watch turns once more after the walk, the
slate holding the outcome until the eyes face it. The fireball comes
through the wormhole at the camera, then the blow lands.
The trap's first beat re-blessed for it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
The Warp Sniper cut to another angle the moment the fireball landed,
though the caster could see the whole thing: the director counted a
warp mouth before the target as blocked sight. Sight threads warps as
the rules say, and now the camera does too. director.sightline finds
the heading that actually sees a point — straight, or through a mouth
by aiming at the target's position in the far room and asking whether
the bent ray reaches it — and both the aim and the turn-toward-the-
actor rules use it. Only a point no ray reaches earns the cutaway.
Warp Sniper's second beat re-blessed: Wanderer's eyes now find Rival
through the mouth as the turn passes to him.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
A day of Eric watching the clips as a newcomer would.
The camera can pitch: FirstPerson takes a `pitch` that shears the
horizon up the pane (walls center on it, the eye stays half a wall
high), so the ground at the pane's foot comes within half a cell. The
director uses it for deeds at your own feet — a conjuration on your
square, a treasure taken up, the pit you fell down — instead of the
cutaway that stepped outside your body.
Everything shows through a warp. The floor pass now runs between the
cast and the wall draw, so a column that bent through a mouth maps its
ground through the warp's rigid motion and wears the far room's decals
— the pit past the wormhole included — under the same violet haze as
its walls.
A wizard down a pit is public (inPit on the player view), drawn sunk to
the floor line in first person and dimmed on the board. A body sharing
your square, which had no depth to draw at, stands right in front of
you. A pit leap glides like a shove instead of cutting. And the
director's blocked-sight test no longer counts a warp BEYOND the
target as a block, nor stands a cutaway camera inside another wizard's
square — the pair that put Wanderer's face across the whole pane.
The reel stops for a die: a card over the held world names who rolls
and for what, tumbles the faces on the reel's own clock, lands the
roll, and only then plays the outcome; the beat, the fx, the glides
and the camera all wait it out. A punch by you drives a fist into the
scene; one at you comes at the camera; both land with a comic POW.
film-clips rolls until the reel's last move rather than a fixed count,
and the gate settles longer on a step whose caption rolls a die. All
thirty goldens re-blessed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
Two things for a viewer who has never seen the game. When the reel's
pov passes to another wizard, the cut used to be instant — one wizard
apparently teleporting. Now a slate wipes across the pane: a dark band
sweeps in over the old sight, holds with the new wizard's standee and
THROUGH THE EYES OF <name>, and sweeps off to reveal theirs. It is an
FpFx ("slate") drawn by the renderer on the reel's own clock, so the
harness and the film see the same frames.
The caption grows a right-hand column: strides left to spend this turn
as a countdown, ♥ life, and chips for what the wizard carries,
displays, or suffers — a treasure, displayed cards, spells on them
with turns remaining, lost turns, banked Pass Wall, attack spent. The
save-video composite carries the same column.
All thirty scene goldens re-blessed: the caption is inside every
frame. The 3D panes are pixel-identical to the previous goldens.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
Eric's direction: passing through an ordinary warp mouth is a normal
stride. The veil already marks the doorway, and the wizard walks through
it as through any door — no shimmer, no surge, and the eyes carry on
the way they were going instead of turning back to show the mouth. The
surge stays for the moment a wormhole is cast, staged straight from the
warpOpened event through both its new mouths.
The heist's pinned frames re-blessed for it: at the crossing the reel
now looks down the corridor at the enemy's home rather than back
through the mouth.
deploy/film-clips.mjs films the catalog for the gallery — every scene
in both takes, the reel playing under the paused clock at one frame per
40ms, muxed to 25fps mp4s with the first pinned beat as the poster. The
recorder used for the first clip set lived in a session scratchpad and
was lost; this one lives here.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
Every board effect the cockpit had no art for landed as the same purple
lightning-ring sprite, so a body stepping through a warp mouth wore the
ring over its own portrait. Eric wanted the purple wall to do the
animating. The portal effect now becomes a "surge" keyed by the mouth's
index in board.warps: the veil hung in that opening floods with its
texture, the swirl quickens and pales, and a ripple runs out to the
jambs before it settles back — nothing drawn over whoever stands in it.
The director used to steer the eyes toward that ring's cell on the pov
wizard's own crossing; it now aims at a surging mouth the same way, so
the heist's pinned frames render as before. Illusion and Pass Wall
crossings keep the shimmer sprite — stone has no veil to surge.
Scene gate: 29 of 30 frames unchanged. stone-gaze-s10-board drifts
0.21% with or without this change (the dashed sight line's phase), a
pre-existing flake left unblessed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
deploy/verify-scenes.sh replays each screenplay to its authored beats
under a paused Playwright clock — pulses, tweens, and fx advance only
on the harness's schedule, so the same beat renders the same bytes
every run — screenshots the reel, and diffs pixels against the goldens
in deploy/scene-goldens (30 frames: warp transits, impacts, curses
landing, in both views). A channel may drift 6 before a pixel counts,
0.2% of pixels before a beat fails; --update blesses intended changes.
Proven both ways before landing: a clean double-run reproduces all 30
goldens exactly, and resurrecting the warp-smear cutaway bug fails the
warp-transit beat at 61% pixel drift.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
?fpv&script=<name> plays a screenplay — a seeded deal, cards slipped
into hands as props, then a command list run through applyCommand, so
every event on screen is a legal move under the real rules. Ten scenes
ship in the catalog: wormhole heists, a fireball threaded through a
warp, an ambush that watches its corridor through a mouth, the leap
over a conjured pit, and the wall between two homes coming down.
The server grows a public gallery to hang them in: /clips lists the
catalog, /clips/<name> pages each scene in two takes — through the
wizard's eyes and from the board — with og:video unfurls and
Range-served mp4s (Safari refuses video without it). Files live in
the clip vault beside the rooms, shipped by deploy/clips-publish.sh;
the name gate is the security.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
A ray threads a warp and keeps counting; a body cannot. Both cutaway
cameras (reel and live pane) backed down deepestFacing's corridor,
which meant a mouth-adjacent shot could measure its backing room
THROUGH the warp and park the eye off the board — a second of smeared
nothing whenever someone stepped a rim warp. cutawayStand now measures
standable ground, clamping warped rays at the mouth, so the shot stands
on real floor watching the veil instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
Sticky-web silk becomes a real web — hub, spokes, two sagging rings —
each strand shadowed so it reads against busy token art. The dread
ring moves behind the body onto the floor plane, sharing the ember
ring's flattened perspective instead of smouldering over the sprite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
The aura's warp-walking diamond — dreadDistance ≤ 3, extracted to one
shared fearCells so the board's dashed ring, the cockpit's floor stain,
and the engine's refusal can never disagree — now tints the flagstones
violet in first person, breathing like the board's aura, beneath the
dread ring already at the bearer's feet.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
Sticky webs strand across a caught body, MEDUSA drains it to gray
stone, the invisible and the misted go translucent, BIG MAN towers and
SHRINK dwindles the billboard, and FEAR smoulders a dark-red dread
ring at its bearer's feet — the six condition looks the 2D board wore
alone. Marks flow billboard → projection → draw, painted only when
the walls show the sprite. The workshop poses them: ?wear=card;card
dresses the Rival.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
While a targeted card is armed, wizards and creatures standing on
castable ground wear a pulsing ember ring at their feet — drawn behind
the body, only when the walls actually show it, and only when the card
could land on a being (creations still light floor alone). The hover
cue now carries a verdict: gold outline and bright name for what the
cast can reach, cold slate for what stands beyond it. The workshop
poses it all: ?aim=1 arms a pretend cast and ?rival=x,y stands the
Rival wherever the shot needs them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
Raising an edge-target card now makes every wall and door face
breathe faint gold in the pane — the cockpit's answer to the board's
edge handles — with hover still brightening the chosen face. And the
director's own-magic aim gains a quarter-turn cap: a deed you aimed
behind you via the keymap stays behind you, while deeds done TO you
may still spin the world.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
Third pass, scoped from 7a32370. Three blind reviewers (engine, web,
server/tools) each concluded the work is coherent engineering with
seam-level tells; every finding was verified before touching a line.
Session biography left the comments: the bot brain's heuristics no
longer cite the opponent who taught them, the RNRX coma parenthetical
and the thief-chase citation are gone, the seat-wallet comments state
their invariants without the war stories, and process-named test
groups now name the behaviors they pin. The incident record lives
where history belongs — commit messages and the ledgers.
Structural dedup: one VISIONSTONE one-edge-sight loop serves both
LOS paths; one creature-arrival touch handler serves walking and
warp-stepping (error text aligned); one facingWedge helper draws both
keymap ribbons; one spriteVisibleInCol rule serves the draw pass and
the hover test (which also stops re-sorting per pointermove); and
deepestFacing joins the director, replacing four copied scans.
Test hardening exposed real rot the tells were hiding: the tight
CreatureState cast caught two literals with a bogus field masking
three missing ones; the number-hoarding rig had NEVER run (its
column didn't exist on seed 42 — it now carves its own geometry);
the bank-guard rig now drives the whole table to an arrival
assertion; the bent-trace test walls off straight sight so the bend
must answer. Silent `return`-on-rig-failure became loud throws, and
can-never-fail assertions were removed.
Sweep-up: the eyeTurn ghost comment, the stacked leave() doc
comments (leave now delegates to leaveLocal), the dead ternary in
the seat client, the kick handler's name-coercion drift, kick ledger
lines gain timestamps, archiveRoomFile reuses fileFor, the RULES_REV
alias retires in favor of the engine constant, hitTest un-exports,
the NUL-sentinel hover shape becomes an honest "none" variant, and
the steering holds get named constants. The bezel's stride cluster
also centers per the table's note.
288 tests, 24 ledgers verified, all workspaces typecheck.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
The pane learns the menagerie. On your turn, a "ride" button appears
for each creature you command with moves or claws unspent; mounting
seats the camera in its skull facing its longest corridor, hides its
own hide from its eyes, and hands it the helm — chevrons and arrows
stride IT, an adjacent floor click steps it, and clicking an enemy
sharing its square lands its blow. A banner shows the mount's
remaining legs; one tap (or the turn passing, or the mount dying)
returns you to your own eyes, where the director reseats you fresh.
Two cockpit-dignity fixes from live play ride along: a cutaway to
your own body now plays only for things done TO you — dropping a
dagger no longer flings your eyes out of your skull — and a standing
camera is never "rescued" off a wall you deliberately faced; the
deepest-corridor default applies only to fresh cuts.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
Hovering the pane now shows what a click would do: a wizard or
creature outlines in gold with its name at the crosshair, a wall or
door face lights across every column it owns, and a floor square
draws its perspective-true quad on the ground. Warp-bent ground still
targets truly but labels itself "through the warp" rather than
drawing a quad in the wrong geometry. And when a cell-target card is
selected, the ineligible ground dims in the 3D view itself — the same
litCells the board's shadow uses, rasterized into the floor pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
Clicks in the first-person view now act. The renderer keeps what the
last frame knew — per-column depth, warp bends, every wall hit's edge,
every sprite's screen rect with its identity — and hitTest inverts the
projection: the nearest visible sprite answers as its wizard or
creature, a struck wall or door answers as its edge, and the ground
answers as the square under the pixel, warp-bent columns mapping their
virtual floor back to real cells through the warp's own rigid motion.
The pane hands each target to the very functions the top-down board's
clicks use, so pane and map can never disagree: click the floor ahead
and you walk there; click a door with a key selected and the lock
turns; click a wizard with an attack and the spell flies.
The keymap token now wears a golden wedge showing the camera's compass
quadrant — the cockpit and the chart always agree on which way you
face. Verified live: a floor click became a real move command in the
room ledger, edge clicks resolve and defer correctly, and the wedge
tracks quarter-turns.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
A pane above the board plays the game through your own eyes while you
play it — the board below stays the tactical truth. One new module,
fpv/director.ts, extracts the reel's directorial instincts (the aim
ladder, the hurl test, the glide gatherer) so the replay and the live
pane share one eye and can never drift; Replay is refactored onto it
unchanged. LiveFirstPerson.svelte feeds the shared FirstPerson
renderer from the live event stream: every batch plays through the
same fx pipeline as the instant replay — projectiles, door swings,
conjurations growing — while the camera walks your strides, turns to
your aims and to actors in your sight, cuts away (with your own body
in frame) to deeds beyond it, and never idles nose-to-brick. Bodies
glide between server views. A ✕ hides the pane; the liveFp preference
(on by default) brings it back.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The per-column sprite gate blanked an overlay's WHOLE column wherever a
nearer body touched it — a treasure chest masked the warp veil all the
way to the ceiling. Each column now remembers its nearest sprite's
vertical span as well as its depth, and every overlay family (veils,
ghost walls, lintels, rising conjurations) draws in segments above and
below the covered band, sampling the matching slice of its texture — so
the shimmer wraps the chest instead of vanishing over it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The warp veil painted over a wizard standing before the mouth — the
overlay passes ran after the sprites with no knowledge of their depth.
Each column now remembers its nearest sprite, and every overlay family
(veils, ghost walls, doorway lintels, rising conjurations) skips the
columns where a body stands closer, while still washing translucently
over anything beyond.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three blind reviews over the first-person arc, every finding verified
against the source. History-narrating comments made timeless or cut;
the stacked BUDDY comment collapsed to one voice. Dead code out: the
orphaned FACE copy, the DIR_ANGLE duplicate, the dead loop-counter
poke, the impossible-state sentinel. The never-produced "warp" hit
kind resolved the right way — warp mouths now hang a translucent veil
of the painted warp texture, so art that never rendered finally does.
Types tightened (SlabStrike named once, ShareData rides CatchUpStep,
botTier loses its casts), the gallery reads MATERIALS instead of a
hand-copied list, the chronicle resets through one helper, a
superseded share mint rejects instead of stranding, and the conjured
safe gains the growth key its siblings had. Tests lose a triple
assignment, a tautology, and two self-swallowing regex alternatives.
The sprite spec — which still told the artist to paint for additive
compositing the renderer no longer uses — now describes the renderer
that exists.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
treasureDropped and objectDropped played as nothing — the gold simply
teleported from chest to floor between frames. A drop now glints (the
spark blooming where it lands, a beat after the blow when combat
knocked it loose), and a wizard dropping at their own feet takes the
cutaway: a third-person shot of them setting the prize down — or
spilling it. When the reel's wizard strikes the spill loose from
someone else, the attack-facing already has the victim in frame, so
the treasure falls on camera.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A carried treasure rendered nowhere in first person — the thief hauling
your gold looked exactly like an innocent. The treasure now rides its
carrier at chest height, drawn just in front of their card (a sort bias
wins the tie), gliding along with their tweened strides and showing
through warp mouths like everything else. The workshop rehearses it
with ?carry=Rival.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Eric's rosebush-through-a-wall, hunted to two roots. A camera-facing
billboard viewed obliquely rotates out of its square, so cell-bound
volumes are now windowed to the exact segment where their plane
crosses their own cell — no end may paint beyond it. And the real
smoking gun: the near-bias that lets a hedge win the tie against the
wizard standing in it was applied to the OCCLUSION depth too, letting
the hedge cheat a fifth of a cell through any neighboring wall. The
bias now orders sprites among themselves only; walls always judge the
true depth.
Also answered: edge-deeds turn the head. Picking or jamming a lock,
unlocking with the Master Key, raising or razing or drowning a wall —
any edge-bearing deed by the reel's own wizard now aims the camera at
that edge's midpoint before the outcome shows, same as any other
target.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Nothing appears fully-formed anymore. Summoned creatures and conjured
terrain volumes scale up from a sliver, bottom-anchored, as if growing
out of the floor. Conjured SOLIDS — walls, firewalls, stone, and yes,
illusion walls for whoever they fool — RISE: while growing, the rays
pass over them so the room behind stays visible, and the renderer
draws the young face climbing bottom-up with violet swirls running
across it, solidifying as it tops out. Every creation also blooms the
shimmer at its cell. The growth is driven through the fx channel, so
the director's slate applies: things grow only once the camera faces
them.
Two camera notes squared away en route: the slate-setter read back the
state it had just written, registering itself as its own dependency
(an update-depth ping-pong under fast stepping) — locals now; and a
reel whose FINAL step strides into a corner gets one more turn after
the walk lands, to a view worth ending on.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DUKK's floor-to-ceiling white sliver, decoded: the sprite gate only
asked "did this column's ray warp?" — so a REAL body standing in front
of a warp mouth was clipped out of the mouth's columns (leaving a
baffling sliver of a huge close sprite), and a body virtualized
through warp A could paint columns bent by warp B. Every column now
remembers WHICH warp bent its ray and how far away that mouth stood;
a real body paints a column only nearer than its mouth (in front of
the window), and a virtual one only through its own warp's columns,
beyond the mouth. Projectile legs carry the same identity.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Eric walked a five-player board's corner warp and the world stretched.
The lane rule — carry the along-the-edge offset through unchanged —
is only correct for half the side pairings: for the rest (N to N,
E to N, and their kin, the ones five-player boards deal), the proper
rotation lands the entry axis head-to-head against the exit axis, and
preserving the raw lane smuggled a REFLECTION into the traversal —
rays crossing over at the mouth, parallax inverted, the far room
swimming. warpLaneMirrored computes the pairing's sign from the
rotation itself; castRay mirrors the lane where required, and
warpMotion anchors the far mouth at its opposite corner to stay the
same pure rotation — so sprites and projectile legs agree with the
rays again. The workshop grows ?players=2..6 to stand on any table
size (the mirror-class mouths live on the five-player boards).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rubble drawn to span its gap stopped short of the posts, and the
ledger of blame is arithmetic: billboard widths scaled by the vertical
pixel ratio (H/depth) when horizontal pixels-per-world-unit is the
focal length over depth — about 1.4x larger. Every "one cell wide"
volume rendered at seventy percent. Sprites that declare an aspect now
mean WORLD width and use the horizontal scale, so rubble reaches post
to post and hedges brush both walls; plain square token sprites keep
their familiar pixel shape.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The audit Eric called for, delivered whole. Open doors are DOORWAYS
now: stone jamb posts at both ends and a lintel hung across the top
(paintable as textures/doorframe.png), the way through open to the eye.
Battle damage shows — the engine's per-edge wallDamage wears painted
cracks into any wall, heavier as harm mounts. The wall safe stands as
a strongbox volume instead of a flat token. Hedges take root: an
underbrush floor decal covers the whole square beneath them (Eric's
report — a billboard at center depth can't reach the floor trapezoid's
near edge), and the hedge itself widens past the cell. Rubble
stretches across the fallen wall's full gap, corner piles landing at
the posts, exactly as its art was painted.
The first-person effect gaps close: victory now throws SIX fireworks
climbing over the winner's home with gold washing the screen; sector
rotations flash violet and heave the whole world; the Thumb of God
lands with a burst and a shudder; walls conjured from nothing rise in
stone dust; and every hazard pratfall plays — pit falls (with a dark
drop and jolt for the faller's own eyes), ooze slips, tack yelps,
thorn snaps, slime, dust. Dying in first person fades long and dark.
And the whole tale travels: a finished game's full replay carries the
share button too — turn -1 mints a link to every turn of the game,
each through its wizard's own eyes, titled for the winner's triumph.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The flat token billboards give way to terrain that inhabits the room.
Pits, slime, tacks, and the dimensional warp's rings are painted INTO
the flagstones — the home-tile decal pass grows into a general per-cell
overlay grid, one texture per cell, alpha-blended texel by texel. Thorn
and rose hedges fill their square wall to wall at half height, drawn
with a near-bias so the wizard standing among the thorns peeks over the
top. The killer ooze rises as a full translucent cube of jello, bricks
and bodies visible through it; dust billows; and each dimensional warp
mouth throws an additive pillar of violet light up from its floor ring.
Billboards learn aspect, translucency, glow, and draw-order bias to
carry it all.
Nine paintable starters ship — four floor decals under textures/, five
standing volumes under terrain3d/ (spec updated for the artist, hedges
wide, jello solid, warpglow as light) — shown in the token workshop,
rehearsable in place with /?fpv&terrain=thornbush@3,7;jello@4,7.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The share button lands on the instant replay. One click mints a slug —
persistent, unguessable, one per (room, turn) — and copies a /watch
link anyone can open: the server rebuilds exactly that turn for the
nameless SPECTATOR, public knowledge only, none of the rest of the
game visible. The page arrives with its OpenGraph card pre-baked into
the head (crawlers never run the app): the turn's title and round in
the text, and an og.png of the maze itself — cells, walls, doors, warp
mouths, homes, standees — painted server-side and PNG-encoded with
nothing but node's own zlib. The viewer page wears its chrome: the
WIZ-WAR masthead linking home, the turn's title, the reel opening
straight into the turn-owner's eyes with a "watch it again" loop, and
a footer that says what this table is and deals the visitor in.
The share page loads as its own entry so a shared link never drags the
full app's socket appetite along; the reel's modal scrim learns to
stand in a page instead of over one.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A wizard who has seen through an illusion no longer walks toward empty
air where the board shows a dashed ghost: the ray records the first
known-illusion edge it crosses without stopping, and the renderer
stands a wall there at one-fifth opacity, violet ripple running through
it, drawn over the sprites so bodies show through its breath. Untested
illusions get the same tell the board gives — a faint shimmer on their
solid face, maybe stone, maybe not — while a believed illusion stays
honest brick. The workshop rehearses it with ?illusion=H:2,8.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A9WK's mystery, solved by Eric: the wizard walked through an illusion
wall it disbelieves, and the viewer — still deceived — watched the
camera slide through solid stone. The deception stays intact, but the
crossing now performs: any body stepping through an edge the VIEWER
holds as wall (which can only be an illusion the mover saw through)
shimmers on both faces, with the stone-gray wash when the eyes
themselves cross. Same dressing Pass Wall wears.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entertainment polish for the instant replay, all through one wizard's
eyes. Doors now slide open along their own edge — Wolf3D style — when
anyone steps through in a reel, hold for the crossing, and swing shut;
the raycaster takes a per-edge openness map and doors carry their
texture with them, leaving a sliver of jamb at the far post. A wall
that dies bursts into stone and shakes the camera, then leaves a mound
of rubble at the fallen edge for the rest of the reel (a tenth
paintable sprite, drawn opaque — debris, not light). Jammed locks
seethe: a rusty pulse across the wood, keyed off the view's own door
states. Walking THROUGH a wall shimmers on both faces and washes the
walker's own screen stone-gray. And every home base wears its owner's
emblem on the flagstones — a near-white paintable overlay tinted by
wizard color per cell in the floor cast.
Testing surfaced a real ghost: a body standing near a far warp mouth
also rendered at its virtual position, which can overlap real
corridors — the depth buffer alone cannot clip it. Every column now
remembers whether its ray bent, and a sprite draws only where its warp
side matches the column's; projectile legs carry the same flag.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A stride into a warp mouth now carries the walker out of the paired
mouth mid-glide, body turned exactly as the rays turn — canWalk admits
a rim edge only where a mouth waits, and the crawler splits the stride
at the crossing. And with painted conjuration sprites arriving, the fx
pass composites them normally instead of additively: painted art is
ink, not light, and additive blending would bloom its outlines white.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three polishes aimed at the instant-replay dream. Other wizards and
creatures now GLIDE between steps in first person instead of blinking
cell to cell — a stride tweens, a teleport still simply arrives. A
projectile whose sight line runs through a warp now flies as two
simultaneous legs under the mouths' rigid motion, so the fireball
plunges into the opening on one side and bursts from the pair on the
other, whichever room the camera stands in. And the saved video is no
longer a bare canvas grab: it composites into a shareable 1280x720
frame with the step's caption burned in — gold actor name, the reel's
own words — and the game's name in the corner, so a clip passed along
explains itself.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reel's first-person mode now shows the fight, not just the rooms.
The board flourishes' event map is recast into world space (fx3d):
fireballs, bolts, and thrown things streak caster to target as glowing
billboards; landings swell and fade; blows that land on YOU wash the
screen red and jolt the camera; warp-steps and teleports flash violet;
a hurled body glides fast and straight with its eyes held steady. Nine
paintable conjuration sprites ship at public/fx3d (spec for the artist
in research/), shown in the token workshop beside the masonry.
Three rough edges sharpened along the way: sprites now project through
warp mouths under the same rigid motion the rays use, clipped by the
depth buffer to the opening; fire and warp surfaces pull a different
texture slice per world cell so a long blaze reads as one; and the
replay camera only turns toward an actor its eyes could actually see.
Two more gifts: the reel can record its first-person canvas straight
to a downloadable WebM (⏺ save video), and the About tab now shows
visitors the way into the three workshops.
One buried mine defused: rAF hands frame-start times that can precede
the tween's own clock, and a zero-length turn divided by it — one NaN
facing poisoned every ray black and re-triggered the camera effect
forever. The tween clamps and guards its phases now.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The loader walks MATERIALS to swap painted files over the procedural
bakes, and the two ground planes were never added to it — so floor.png
and ceiling.png sat served-but-unread while the renderer kept its own
flagstones. Eight materials in the list now, all eight paintable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Zero-width planes vanish when seen end-on. Each wall edge now rises as
a thin box — masonry thickest, door joinery slimmer, fire a mere sheet
— so the ray march tests the slabs of every cell it passes through and
wall ENDS present a cap face. Corners, jambs, and junctions read as
stone with depth instead of paper. Warp traversal, stone cells, and
the rim keep their crossings; the frame budget doesn't notice.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
True floor-casting replaces the gradients and the projected seam lines:
every screen row lies at one depth, walked with a constant world-space
step and sampled from floor.png underfoot and ceiling.png overhead —
each maze cell wearing exactly one tile, so the artist's border IS the
cell seam. Distance shade and fog fold into the same per-pixel pass,
pixel buffers cache per texture (re-read when a painted file lands),
and the whole frame still clears 60fps with room to spare. Flagstones
and dark slabs ship as the starter files beside the other masonry.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The six materials move out of the renderer into public/textures/*.png —
repaint any of them (any size; the sampler reads each file's own scale)
and refresh, exactly as the token SVGs work. fpv/textures.ts keeps the
procedural bake as the shipped default and the stand-in while files
load, and the /?tokens gallery grows a masonry section showing the set
beside the tokens they will someday match.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Walls wear baked 64-texel textures sampled per column — running-bond
brick for the maze, darker courses for the rim, rough blocks for filled
stone, planked doors with an iron band and handle, flame-streaked fire,
swirling violet for the warps — drawn crisp with smoothing off, shaded
by distance and animated by overlay. The floor shows its tile seams:
grid lines projected onto the ground plane, occluded by the walls that
stand on them. And the workshop walks like the game plays: a tap glides
exactly one square with an eased stride, a turn swings a clean quarter,
held keys queueing the next move as each settles.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sight now runs THROUGH the warps as the rules say: a ray reaching a
mouth re-enters at its pair and marches on, the far side swimming in
violet haze. The floor's furniture joins the scene — bushes stand tall,
safes squat, slime and tacks and pits lie low, dropped daggers glint.
And the replay reel gains a 👁 toggle: relive the catch-up or the whole
tale through your wizard's eyes, the camera turning before it strides,
easing between cells, cutting on teleports, and turning toward whoever
acted while you stood still. The /?fpv workshop grows &demo=1 — two
automatons play a stretch and the real Replay component reruns it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>