Commit History
-
feat(hint): make the betrayed hint more obvious (#77)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureReformat the "betrayed" riddle so the tile-path is quoted and the target is labelled, letting players read off exactly which words to hop: I feel "little hurt again ? angry sad" (betrayed). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>c7be0b3 -
feat(game): escalating, per-target hint ladder (#73)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureReplace the single cryptic nudge with stored per-target solutions and a multi-step hint modal: - levels: `solutions` on the Level dataclass (shipped via client_value). - critters: confirm -> "really stuck on {X}?" -> partial reveal (thanks/"No. I'm a loser") -> full solution. - feelings: betrayed-only riddle, else a shrug. - opener escalates by hints revealed: lame / "Really? Again?" / "getting silly". The same reveal count feeds the win-screen "hints used" tally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>66ebc4d -
feat(audio): per-board music with loudness-matched crossfade (#72)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureGive the bonus and critters boards their own background loops and crossfade between tracks on every level transition. - bonus → corporate-glitch, critters → farm; home keeps Cipher2. - Each Level carries a music basename + a loudness trim (music_gain). The trims (0.349, 0.365) match each track to Cipher2's -19.74 LUFS (measured via EBU R128) so nothing jumps in volume across a transition. - Music is now a per-track voice pool (one <audio> + gain node each) feeding the shared music bus; loadLevel crossfades by ramping the outgoing track to 0 and the incoming up to its trim. Mixer slider, mute, and the glitch-board low-pass still level every track together. Verified with Playwright against the live Web Audio graph: home→bonus→critters each select the right track, crossfade (both tracks overlap mid-fade), settle on the exact trim, and park the outgoing voice; farm decodes and plays (HAVE_ENOUGH_DATA); no console errors. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@an…30816a1 -
feat(levels): glitch bonus board — context bombs, shrink/hug, portal round-trip (#54)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureA secret glitch bonus board (feelings → bonus → critters), inverted to a dark negative with glitching word tiles and muffled music. - file context bombs (dog.png/diary.txt/receipt.pdf) flood the prompt → "context window exceeded" death - the only submit is the prompt injection; build/small/hackathon rise in a sequential lane and ship to the judge endpoint; shipped keys break, locked keys bonk - shrink tile unlocks "small"; the 🤗 earned by clearing critters (via the cross-level portal) replaces the face and unlocks "hackathon" - smooth light→dark transition, you-win modal once all three are collected Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>a341239 -
feat(levels): make critters the home board, drop the last two levels (#53)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureRemove the subjects and countries boards; lead with critters (now first/home) and feelings (second). Rework critters into a 4x4 with a blank central start, one top-left wings exit, two submit keys, no portals, a refreshed word set, and 8 animal targets (dropped lion). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>62fa109
-
feat(levels): drop dolphin target, rename acrobatic tile to smart (#50)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureRemove "dolphin" from the animal board's targets/labels (now 8) and rename the "acrobatic" tile back to "smart". Sync the CLAUDE.md count. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>8d5d8d2 -
feat(levels): rename the "smart" animal tile to "acrobatic" (#48)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>84cceb3 -
feat(levels): rename a tile and drop the lion target on the animal board (#47)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureSwap the "flying" tile for "smart" and remove "lion" from the animal board's targets/labels (now 9). Sync the CLAUDE.md target count. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>0f9f5dc -
feat(levels): add the countries board with the column-shuffle mechanic (#44)
Ben BlakerUnverified signature## What & why Board four — **`countries`** (`order=3`, reached after the subjects board). The judge reads which country a sentence sounds like: USA, Russia, Italy, France, India, China, Korea, England. ### New mechanic — the `shift` / column-shuffle tile The user's `[swap]` tile, named **`shift`** in code so it doesn't collide with the existing off-edge board-navigation *swap tiles*. - Shift tiles render as hand-drawn keycaps stamped with **two stacked accent ⇨ arrows** (wordless, dashed "press me" rim). - The top row is all structural: a blank `start` in the middle flanked by four shift tiles. Hopping onto one **rotates every row UNDER the top row one column to the right**; the rightmost cap of each row **wraps around to become the leftmost**, arcing up-and-over the caps that slide in beneath it. The top row never moves. - Landing on a shift tile costs one budget hop and appends no word (consistent with `wings` / every land, and routed through #42's new `settleIdle()` …3663d53 -
feat(portal): spinning-spiral teleport tiles on the animal board (#42)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureThree spinning ink-spiral portals on the animal board (board 2), each linking to the next clockwise (top→right→bottom→top). Hopping onto one shrinks the doodle into the source spiral and expands it out of the destination. "portal" is a new reserved tile word (wordless, never reaches the judge); the landing hop costs budget. Spirals spin in the render loop (mesh spin, no texture redraw). Rebased onto #41 (the wings board): #41 reserved the word "wings", which collided with the literal "wings" the layout placed at animal (3,2) — renamed that cell to "winged" so the animal board stays portal-only. Verified in-browser (Playwright): all three clockwise links walked live, spirals spinning, shrink-in/expand-out teleport, "winged" renders as a normal word, 0 console errors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>8d3ebb8 -
feat(levels): add the subjects board with the wings flight mechanic (#41)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureBoard three (subjects, order=2), reached after the animal board. The judge reads which academic subject a sentence sounds like (maths, science, philosophy, economics, literature, languages, art, music). New mechanic — wings: - `[wings]` tiles render as hand-drawn accent wing keycaps (wordless, like start/⏎). - Hopping onto one lifts the doodle into the air: it sprouts wings (new "fly" pose) and rises to cruise altitude, wings slowly flapping on their own timer (independent of the idle "boil", so they keep beating mid-hop). - The next two hops glide FREE — airborne, no word appended, no budget spent. - The third hop descends "down from the sky" and lands for real, e.g. onto a ⏎ to press submit. Wings are a clean exit: lock in the sentence you've written, then soar over the rest of the keys to the button without typing them. Flight state resets on board change, death, fresh attempt, and swap-tile transitions. Adds takeoff (soar) and wing-beat (flap) sounds. Verified locall…45107cc -
feat(emotion): replace sarcastic and surprised targets with scared (#39)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureDrop the "sarcastic" and "surprised" emotion targets/labels from the home board and add a single "scared" target in their place, taking the list from 8 targets to 7. The grid's "yikes"/"hurt"/"disturb"/"angry" words make a scared read reachable. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>9cebd73 -
feat(emotion): restore the "!" punctuation tile at (1,3)
Swap the right-hand "little" back to "!" so the feelings board keeps a punctuation tile that attaches to words (e.g. "great!"). start (1,1) and the ⏎ submit (2,3) are unchanged, so the parity that keeps two-word reads reachable still holds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>95e6b80 -
feat(emotion): reshape the feelings board and expand to 8 targets (#36)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureRedraw the home board's grid (slowly→yikes, the old "!" tile → little) and grow the collectible set from 3 to 8 emotions: happy, elated, irked, sarcastic, distraught, furious, betrayed, surprised. The judge's candidate labels track the targets. Update the solution-path tests that referenced the removed "!" tile and refresh the judge live-eval's board sentences for the same reason. All level invariants still hold — grid rectangular, start blank, every target scoreable, solvable within budget. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>3402747 -
refactor(judge): simplify prompt to a direct similarity instruction
Replace the few-shot "<sentence> is the same as" -> "<label>" framing with a single system instruction: name the targets and ask for the one most similar to the player's message, sent the bare sentence as the user turn. Drops the per-board few-shot examples and the Level.examples field along with all the "is the same as" suffix plumbing. The Modal endpoint is prompt-agnostic (it scores whatever messages arrive), so no redeploy is needed for this to take effect in the app. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>491911f
-
feat(levels): retheme the home board to happy/betrayed/surprised (#23)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureSwap the home board's targets from happy/sad/angry/scared to happy/betrayed/surprised, change the (1,0) tile from "apple" to "yikes", and recalibrate the judge few-shot examples to the new labels (hurt→betrayed, yikes→surprised). The start tile and ⏎ submit tile keep their positions, so grid parity is unchanged. The live board-sentence eval was coupled to the old labels and stripped the few-shot examples to measure zero-shot discrimination — which never surfaces "betrayed"/"surprised" as a first answer token. Rework it to mirror the actual in-game judge() call (passing level.examples), which is the discrimination players really get and what makes those labels reachable. Verified: full suite green (30 passed incl. live HF eval); rendered the board in-app and confirmed grid + target chips match. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>aa58329 -
fix(ui): restore the ⏎ submit tile and a solid start outline (#20)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureRevert the submit tile's label from "=" back to "⏎" (the carriage-return glyph) across the level grids, board engine, tests, and docs. The judge prompt is "<sentence> is the same as" now, so the tile is a purely visual marker — the rename touches no scoring logic. Also drop the dashed rim on the start tile so it reads as a normal solid keycap; only the submit tile keeps its dashed "press me" cue. 23 fast tests pass; verified both boards render in-browser (fake judge). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>48c6837 -
feat(judge): enrich prompt with targets and per-level few-shot examples (#17)
Ben Blaker +1: Claude Opus 4.8 (1M context)Unverified signatureReshape the judge prompt that scores a board sentence against the level's candidate labels: - Add a system message listing the still-needed `targets`, threaded through judge() -> score_labels(). - Replace the bare "=" in the user message with "is the same as", reading as an equivalence while still ending right where the answer token is predicted (constrained-decoding logprob mechanism unchanged). - New optional `Level.examples` field: per-level (sentence, label) pairs expanded into few-shot user/assistant turns to calibrate the judge. Kept server-side only (not in client_value) so they don't spoil the puzzle. emotion and animal boards each get four board-vocabulary examples. Update the check_logprobs diagnostic to mirror the new prompt shape, and the live eval test to pass all labels as unbiased targets. All non-slow tests pass. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>d39c87a -
refactor(judge): simplify to a "<sentence> =" prompt; rename ⏎ tile to =
The judge prompt is now just the assembled sentence followed by " =", and the board's candidate labels alone constrain the answer (emotions on one board, animals on another). The submit tile changes from ⏎ to = so the tile you hop onto is literally the prompt's operator. - levels: Level drops category/few_shot/question, keeping grid + labels. Grids use "=" for submit tiles. - judge: score_labels(sentence, labels) sends one message, no examples. - engine / tests / README / logprobs probe: ⏎ -> =. 23 fast tests pass; verified both boards submit onto "=" in-browser (fake judge). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>edcc51c -
feat(levels): modular drop-in level API + animal board
Make adding a board a one-file drop-in, and ship a second level. - levels/ package: each board is a self-contained Level (grid + its own judge spec — category, few-shot, labels), auto-discovered from its file; order/home set play order and the boot board. Replaces the single level.py. - judge is now category-agnostic: score_labels takes a Level, and judge() resolves the board from the level_id the client sends (labels/few-shot stay server-side). - engine: empty "" tiles are walkable but wordless; board build factored into buildTiles/buildTargets/loadLevel so boards swap client-side; camera reframes to board size; checked targets persist per board. - nav: hand-drawn ink arrows walk between boards — "next" unlocks after the first target is collected, "back" returns to the previous board. - animal board: 5x5, central start, four ⏎ corners, walkable blanks, ten animals to collect. 25 fast tests pass; verified both boards in-browser with the offline judge. Co-Authored-By:…4a497b2