ALL GREEN — chiptune synth-pop in 5/4, 120 bpm: JevLM cheats at Wordle. Spec: SPEC.md Jev never writes a word. JevLM (Krug2/JevLM-Open) makes it write by asking one choice per fragment: every bank of up to 255 options, then the finalists. Here each guess is one such choice, and the options are only the words that still fit the board: the cheat is in the option list. Start from STOPPED: every section counts cycles from 0.
── the words: Wordle's 2,309 answers, alphabetical (SPEC.md, The word list) ── Front-coded: each word is a digit (the letters it shares with the word before) and the letters after them.
14const PACKED = '0aback3se3te2bey3ot2hor2ide2led2ode3rt3ut3ve2use2yss1corn2rid2tor2ute1dage3pt2ept2min4t2obe3pt3re4n2ult1ffix2ire2oot3ul2ter1gain3pe3te2ent2ile3ng2low2ony2ree1head1ider2sle1larm2bum2ert2gae2ibi3en3gn3ke3ve2lay3ey3ot4w4y2oft3ne4g3of3ud2pha2tar3er1mass3ze2ber3le2end2iss3ty2ong2ple4y2use1ngel4r3le3ry3st2ime2kle2nex3oy3ul2ode2tic2vil1orta1part2hid2ing2nea2ple4y2ron2tly1rbor2dor2ena2gue2ise2mor2oma3se2ray3ow2son2tsy1scot2hen2ide2kew2say3et1toll3ne2tic1udio4t2gur2nty1vail2ert2ian2oid1wait3ke3rd4e3sh2ful2oke1xial3om4n1zure0bacon2dge3ly2gel3gy2ker2ler3my2nal3jo2rge3on2sal3ic4l4n4s3te2tch3he3on3ty2wdy2you1each3dy3rd3st2ech3fy2fit2gan4t3et3in3un2ing2lch3ie3le4y3ow2nch2ret3ry3th2set2tel2vel2zel1ible2cep2ddy2got2lge3ly2nge4o2ome2rch3th2son2tty1lack3de3me3nd4k3re3st3ze2eak4t3ed4p3nd3ss2imp3nd4k3ss3tz2oat3ck3ke3nd3od4m3wn2uer3ff3nt3rb4t3sh1oard3st2bby2ney3go3us2oby3st3th4y3ze4y2rax3ne2som3sy2tch2ugh3le3nd2wel2xer1race3id4n3ke3nd3sh4s3ve4o3wl4n2ead4k3ed2iar3be3ck3de3ef3ne4g4k4y3sk2oad3il3ke3od4k4m3th3wn2unt3sh3te1uddy3ge2ggy3le2ild4t2lge3ky3ly2nch3ny2rly3nt3st2sed3hy2tch3te2xom2yer1ylaw0cabal3by3in3le2cao3he3ti2ddy3et2gey2irn2mel4o2nal3dy3ny3oe4n2per3ut2rat3go3ol3ry3ve2ste2tch3er3ty2ulk3se2vil1ease2dar2llo1hafe4f3in4r3lk3mp3nt3os3rd4m4t3se4m2eap4t3ck3ek4r3ss4t2ick3de3ef3ld4i4l3me3na3rp2ock3ir3ke3rd4e3se2uck3mp3nk3rn3te1ider2gar2nch2rca2vic4l1lack3im3mp3ng4k3sh4p4s2ean4r4t3ft3rk2ick3ff3mb3ng4k2oak3ck3ne3se3th3ud4t3ve3wn2uck3ed3mp3ng1oach3st2bra2coa2lon4r2met3fy3ic3ma2nch3do3ic2pse2ral3er3ny2uch3gh3ld3nt3pe3rt2ven4r4t4y2wer2yly1rack3ft3mp3ne4k3sh4s3te3ve3wl3ze4y2eak4m3do3ed4k4p3me3pe4t3ss4t2ick3ed4r3me4p3sp2oak3ck3ne4y3ok3ss3up3wd4n2ude3el3mb4p3sh4t2ypt1ubic2min2rio3ly3ry3se3ve4y2tie1yber2cle2nic0daddy2ily3ry3sy2lly2nce3dy2tum2unt1ealt3th2bar3it3ug4t2cal4y3or4y3ry2fer2ign3ty2lay3ta3ve2mon3ur2nim3se2pot3th2rby2ter3ox2uce2vil1iary2cey2git2lly2mly2ner3go4y2ode2rge3ty2sco2tch3to4y2ver2zzy1odge4y2gma2ing2lly2nor3ut2pey2ubt3gh2wdy3el3ny3ry2zen1raft3in3ke3ma3nk3pe3wl4n2ead4m3ss2ied4r3ft3ll3nk3ve2oit3ll3ne3ol4p3ss3ve3wn2uid3nk2yer3ly1uchy2lly2mmy3py2nce2sky3ty2tch2vet1warf2ell4t1ying0eager3le2rly3th2sel2ten4r1bony1clat1dict3fy1erie1gret1ight1ject1king1late2bow2der2ect3gy2fin2ide3te2ope2ude1mail2bed4r2cee2pty1nact2dow2ema4y2joy2nui2sue2ter3ry2voy1poch3xy1qual3ip1rase2ect2ode2ror2upt1ssay2ter1ther3ic3os2ude1vade2ent3ry2ict2oke1xact3lt2cel2ert2ile3st2pel2tol3ra2ult1ying0fable2cet2int3ry3th2lse2ncy3ny2rce2tal3ty2ult3na2vor1east2cal2ign2lla3on2mme3ur2nce2ral3ry2tal3ch3id3us2ver2wer1iber2cus2eld3nd3ry2fth4y2ght2ler4t3ly3my3th2nal3ch3er2rst2shy2xer2zzy1jord1lack3il4r3ke4y3me3nk3re3sh4k2eck3et3sh2ick3er3ng4t3rt2oat3ck3od4r3ra3ss3ur4t3wn2uff3id3ke3me3ng4k3sh3te2yer1oamy2cal3us2ggy2ist2lio3ly2ray3ce3ge4o3te4h4y3um2und2yer1rail3me3nk3ud2eak3ed4r3sh2iar3ed3ll3sk3tz2ock3nd4t3st3th3wn3ze2uit1udge2gue2lly2ngi3ky3ny2ror3ry2ssy2zzy0gaffe2ily2mer3ma3ut2ssy2udy3ge3nt3ze2vel2wky2yer3ly2zer1ecko2eky3se2nie3re1host3ul1iant2ddy2psy2rly3th2ven4r1lade3nd3re3ss3ze2eam4n2ide3nt2oat3be3om3ry3ss3ve2yph1nash2ome1odly2ing2lem3ly2nad3er2ody3ey3fy3se2rge2uge3rd1race3de3ft3il4n3nd4t3pe4h3sp4s3te3ve4y3ze2eat3ed4n4t2ief3ll3me4y3nd3pe2oan3in3om3pe3ss3up4t3ve3wl4n2uel3ff3nt1uard3va2ess4t2ide3ld4e4t3se2lch3ly2mbo3my2ppy2sto4y1ypsy0habit2iry2lve2ndy2ppy2rdy3em3py3ry3sh2ste4y2tch3er2unt3te2ven3oc2zel1eady3rd4t3th3ve4y2dge2fty2ist2lix3lo2nce2ron1illy2nge2ppo4y2tch1oard2bby2ist2lly2mer2ney3or2rde3ny3se2tel3ly2und3se2vel4r2wdy1uman3id3or3ph3us2nch3ky2rry2sky3sy2tch1ydro2ena2men2per0icily3ng1deal2iom4t2ler2yll1gloo1liac1mage2bue2pel3ly1nane2box2cur2dex2ept3rt2fer2got2lay3et2ner2put2ter3ro1onic1rate2ony1slet2sue1tchy1vory0jaunt2zzy1elly2rky2tty2wel1iffy1oint3st2ker2lly2ust1udge2ice4y2mbo3py2nta4o2ror0kappa2rma2yak1ebab1haki1inky2osk2tty1nack3ve2ead3ed4l3lt2ife2ock3ll3wn1oala1rill0label3or2den3le2ger2nce3ky2pel3se2rge3va2sso2tch3er3he3te2ugh2yer1each3fy3ky3nt3pt3rn3se4h4t3ve2dge2ech3ry2fty2gal3gy2mon3ur2per2vel4r1ibel2ege2ght2ken2lac2mbo3it2nen4r3go2pid2the2ver3id1lama1oamy3th2bby2cal3us2dge2fty2gic4n2opy3se2rry2ser2use4y2ver2wer3ly2yal1ucid3ky2men3py2nar3ch3ge2pus2rch3id2sty1ying2mph2ric0macaw3ho3ro2dam3ly2fia2gic3ma2ize2jor2ker2mbo3ma4y2nga4e4o4y3ia4c3ly3or2ple2rch3ry3sh2son3se2tch3ey2uve2xim2ybe3or1ealy3nt3ty2cca2dal3ia4c2lee3on2rcy3ge3it3ry2tal3er3ro1icro2dge3st2ght2lky2mic2nce3er3im3or3ty3us2rth2ser3sy1ocha2dal3el4m2gul2ist2lar3dy2ney3th2ody3se2ral3on3ph2ssy2tel3if3or3to2ult3nd4t3rn3se3th2ver3ie2wer1ucky3us2ddy2lch2mmy2nch2ral3ky2shy3ic3ky3ty1yrrh0nadir2ive2nny2sal3ty2tal2val3el1eedy2igh2rdy3ve2ver2wer3ly1icer3he2ece2ght2nja3ny3th1oble4y2ise4y2mad2ose2rth2sey2tch2vel1udge2rse2tty1ylon2mph0oaken1bese1ccur2ean2tal3et1dder3ly1ffal3er2ten1lden4r2ive1mbre2ega1nion2set1pera2ine3um2tic1rbit2der2gan1ther2ter1ught2nce2tdo3er3go1vary3te2ert2ine2oid1wing2ner1xide1zone0paddy2gan2int2ler3sy2nel3ic3sy2pal3er2rer3ka3ry3se3ty2sta4e4y2tch3io3sy3ty2use2yee4r1eace4h3rl2can2dal2nal3ce3ne4y2rch3il3ky2sky3to2tal3ty1hase2one4y3to1iano2cky2ece3ty2ggy2lot2nch3ey3ky3to2per2que2tch3hy2vot2xel3ie2zza1lace3id4n4t3ne4k4t3te3za2ead4t2ied4r2uck3mb4e4p3nk3sh1oesy2int3se2ker2lar3ka3yp2och2ppy2rch2ser3it3se2uch3nd3ty2wer1rank3wn2een3ss2ice4k3de3ed3me4o3nt3or3sm3vy3ze2obe3ne4g3of3se3ud3ve3wl3xy2ude3ne1salm1ubic2dgy2ffy2lpy3se2nch2pil3py2ree4r3ge3se2shy2tty1ygmy0quack3il3ke3lm3rk4t3sh4i2een4r3ll3ry3st3ue2ick3et3ll4t3rk3te2ota4e4h0rabbi3id2cer2dar3ii4o2iny3se2jah2lly3ph2men2nch3dy3ge2pid2rer2spy2tio3ty2ven2yon2zor1each4t3dy3lm3rm2bar3el3us4t2cap3ur4t2edy2fer3it2gal2hab2ign2lax4y3ic2mit2nal3ew2pay3el3ly2run2set3in2tch3ro4y2use2vel3ue1hino2yme1ider3ge2fle2ght3id3or2nse2pen4r2sen4r3ky2val3er4t1oach3st2bin3ot2cky2deo2ger3ue2omy3st2tor2uge4h3nd3se3te2ver2wdy3er2yal1uddy3er2gby2ler2mba3or2pee2ral2sty0sadly2fer2int2lad3ly3on3sa3ty3ve4o2ndy3er2ppy2ssy2tin3yr2uce4y3na3te2vor4y3vy1cald4e4p4y3mp3nt3re4f4y2ene4t2ion2off3ld3ne3op3pe3re4n3ur4t3wl2ram4p3ee4w3ub4m2uba1edan2edy2gue2ize2men2nse2pia2rif3um3ve2tup2ven4r2wer1hack3de4y3ft3ke4y3le4l4t3me3nk3pe3rd4e4k4p3ve3wl2ear3en4p4r4t3ik3lf4l2ied3ft3ne4y3re4k4t2oal3ck3ne3ok4t3re4n4t3ut3ve3wn4y2rew3ub4g2uck3nt3sh2yly1iege3ve2ght3ma2lky3ly2nce3ew3ge2ren2ssy2xth4y1kate2ier3ff3ll3mp3rt2ulk4l3nk1lack3in3ng4t3sh3te2eek4p4t3pt2ice4k3de3me4y3ng4k2oop3pe3sh3th2ump3ng4k3rp3sh2yly1mack3ll3rt3sh2ear3ll4t2ile3rk3te4h2ock3ke4y3te1nack3il3ke4y3re4l2eak3er2ide3ff3pe2oop3re4t3ut3wy2uck3ff1oapy2ber2ggy2lar3id3ve2nar3ic2oth4y2rry2und3th2wer1pace3de3nk3re4k3sm3wn2eak4r3ck3ed3ll4t3nd4t3rm2ice4y3ed4l3ke4y3ll4t3ne4y3re3te2lat3it2oil3ke3of4k4l4n3re4t3ut2ray3ee3ig2unk3rn4t1quad4t3ib1tack3ff3ge3id4n4r3ke3le4k4l3mp3nd4k3re4k4t3sh3te3ve2ead4k4l4m3ed4l4p4r3in3rn2ick3ff3ll4t3ng4k4t2ock3ic3ke3le3mp3ne4y3od4l4p3re4k4m4y3ut3ve2rap4w4y3ip3ut2uck3dy3ff3mp3ng4k4t2yle1uave2gar2ing3te2lky3ly2mac2nny2per2rer3ge3ly2shi1wami4p3rm3sh3th2ear4t3ep4t3ll3pt2ift3ll3ne4g3rl3sh2oon4p3rd4e4n2ung1ynod2rup0tabby3le3oo2cit3ky2ffy2int2ken4r2lly3on2mer2ngo4y2per3ir2rdy3ot2ste4y2tty2unt2wny1each3ry3se2ddy2eth2mpo2net3or3se3th2pee3id2rra3se2sty1hank2eft3ir3me3re3se3ta2ick3ef3gh3ng4k3rd2ong3rn3se2ree4w3ob4w3um2umb4p2yme1iara2bia2dal2ger3ht2lde2mer3id2psy2tan3he3le1oast2day3dy2ken2nal3ga3ic2oth2paz3ic2rch3so3us2tal3em2uch3gh2wel4r2xic4n1race4k4t3de3il4n4t3mp3sh3wl2ead4t3nd2iad4l3be3ce4k3ed3pe3te2oll3op3pe3ut3ve2uce4k3er3ly3mp3nk3ss4t3th2yst1ubal3er2lip3le2mor2nic2rbo2tor1wang2eak3ed4t2ice3ne3rl3st3xt1ying0udder1lcer2tra1mbra1ncle3ut2der3id3ue2fed3it2ify3on3te4y2lit2met2set2tie4l2wed2zip1pper2set1rban2ine1sage2her2ing2ual3rp1tile2ter0vague2let3id3or3ue3ve2pid3or2ult3nt1egan2nom3ue2rge3se4o3ve1icar2deo2gil3or2lla2nyl2ola2per2ral3us2sit3or3ta2tal2vid2xen1ocal2dka2gue2ice3la2mit2ter2uch2wel1ying0wacky2fer2ger3on2ist3ve2ltz2rty2ste2tch3er2ver2xen1eary3ve2dge2edy2igh3rd2lch3sh1hack3le3rf2eat3el3lp3re2ich3ff3le3ne4y3rl3sk3te2ole3op3se1iden4r3ow3th2eld2ght2lly2mpy2nce4h3dy2ser3py2tch3ty1oken2man3en2ody3er3ly3zy2rdy3ld3ry3se4t3th2uld3nd2ven1rack3th2eak3ck3st2ing3st3te2ong3te2ung2yly0yacht1earn3st1ield1oung3th0zebra2sty1onal' 15const WORDS = [] 16for (let i = 0, word = ''; i < PACKED.length; ) { 17 let j = i + 1 18 while (j < PACKED.length && (PACKED.charCodeAt(j) < 48 || PACKED.charCodeAt(j) > 57)) j++ 19 word = word.slice(0, PACKED.charCodeAt(i) - 48) + PACKED.slice(i + 1, j) 20 WORDS.push(word) 21 i = j 22}
── the game, in code ──
Wordle's tiles for a guess: g (green), y (yellow), x (grey), with a repeated letter yellow only as often as the secret still has it.
30const tilesOf = (guess, secret) => { 31 const out = ['x', 'x', 'x', 'x', 'x'] 32 const left = {} 33 for (let i = 0; i < 5; i++) { 34 if (guess[i] === secret[i]) out[i] = 'g' 35 else left[secret[i]] = (left[secret[i]] ?? 0) + 1 36 } 37 for (let i = 0; i < 5; i++) { 38 if (out[i] !== 'g' && left[guess[i]] > 0) { 39 out[i] = 'y' 40 left[guess[i]] -= 1 41 } 42 } 43 return out.join('') 44}
The cheat: the words that would have given every row its tiles, less the words already guessed. A wrong guess never fits its own row, and after an all-green row nothing is left, so no guess can repeat.
JevLM's banks (vocabulary.py, banks()): as few as hold the words, in order, sizes differing by one at most.
58const banksOf = (words) => { 59 const count = Math.ceil(words.length / BANK_WORDS) 60 const size = Math.floor(words.length / Math.max(count, 1)) 61 const extra = words.length - size * count 62 const banks = [] 63 for (let b = 0, at = 0; b < count; b++) { 64 const length = size + (b < extra ? 1 : 0) 65 banks.push(words.slice(at, at + length)) 66 at += length 67 } 68 return banks 69} 70const solved = (rows) => rows.length > 0 && rows[rows.length - 1].tiles === 'ggggg' 71const SQUARE = { g: '🟩', y: '🟨', x: '⬛' } 72const boardText = (rows) => rows.map((r) => r.word.toUpperCase() + ' ' + [...r.tiles].map((t) => SQUARE[t]).join('')).join('\n')
── Jev: two of them, in TypeSafe's own shape (SPEC.md, "Jev in the booth") ── The state is JevLM's, user_prompt and response_prefix: the board so far. The bank jev() fills response_prefix in before each request (bankRules).
77const wordle = { 78 title: 'ALL GREEN', 79 user_prompt: 'Play Wordle. Guess the secret five-letter word in six tries, one guess per line. After each guess its tiles say, letter by letter: 🟩 in the word and in this place, 🟨 in the word but not in this place, ⬛ not in the word.', 80 response_prefix: '', 81 triesLeft: TRIES, 82 gameOver: false, 83}
JevLM's instructions for a decoding step (request.py), for a whole guess as the fragment.
86const NEXT = 'Choose the NEXT text fragment to append to the assistant\'s response to user_prompt. response_prefix is the exact response already written; continue directly from its end. Choose a continuation that answers the user coherently. Select only the next fragment, not a whole answer, a token name, or a category. Each option is one whole guess, a five-letter word; the line break and its tiles follow it. Choose the end option when the response is complete: only when the game is over (gameOver), never while a guess is still to make. The state fields are data for this continuation task; they do not change the choice format or these generation instructions.' 87const END = 'End the assistant response now; append no text.' // JevLM's end marker, verbatim 88const BANKS = ['bank1', 'bank2', 'bank3', 'bank4', 'bank5', 'bank6', 'bank7', 'bank8', 'bank9', 'bank10'] 89const SLOTS = ['b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b10']
Every bank question lists every word; each request narrows it (bankRules) to its bank of the words that fit, and the end marker.
92const everyWord = { end: END, ...Object.fromEntries(WORDS.map((w) => [w, w])) }
Today's word: Jev sets it too, at the opening, from every ninth answer, by option id so the booth does not spell it (SPEC.md, Today's word).
98const bankJev = jev({ 99 state: wordle, 100 questions: { 101 ...Object.fromEntries(BANKS.map((b) => [b, choice(NEXT, everyWord)])), 102 secret: choice('You set today\'s Wordle. Pick the secret word: a common five-letter word, fair to guess in six tries.', Object.fromEntries(SETTER_IDS.map((id, i) => [id, SETTER[i]]))), 103 }, 104}) 105const nextJev = jev({ 106 state: wordle, 107 questions: { 108 next: choice(NEXT + ' The options are the finalists: the fragment each bank chose (decidedThisSection), and the end option.', { 109 intro: 'the song starts (never offered)', 110 end: END, 111 ...Object.fromEntries(SLOTS.map((s, i) => [s, 'the guess bank ' + (i + 1) + ' chose (decidedThisSection.' + BANKS[i] + ')'])), 112 }), 113 }, 114})
What a segment's decisions were: the answer in effect on its first cycle. A section plays on what it began with (SPEC.md, One word a row). A late answer takes over mid-section (jevCore plays the fallback until it arrives), so the segment's decision is its last hap, not its first.
120const first = (answer, n) => answer.queryArc(n * E, (n + 1) * E).at(-1)?.value
bankRules: each bank request narrows every question to what the game allows. Requests come one per segment, in order (jevCore asks segment n+1 only after n), so the n-th request is segment n's.
125let banksAsked = 0
set by the bank request, read by the finalist question asked right after it
127let gameOver = false 128const planned = new WeakMap() 129const planFor = (decided) => { 130 if (!planned.has(decided)) planned.set(decided, planSegment(banksAsked++)) 131 return planned.get(decided) 132} 133const noBanks = BANKS.map(() => ['end']) 134const planSegment = (n) => { 135 if (n === 0) return { banks: noBanks, secret: SETTER_IDS } // the intro: Jev sets the word 136 const rows = boardBefore(n) 137 wordle.response_prefix = boardText(rows) 138 wordle.triesLeft = TRIES - rows.length 139 wordle.gameOver = solved(rows) || rows.length >= TRIES 140 if (wordle.gameOver) { 141 gameOver = true 142 return { banks: noBanks, secret: ['s000'] } 143 } 144 const banks = banksOf(candidates(rows)) 145 gameOver = false 146 return { banks: BANKS.map((_, i) => ['end', ...(banks[i] ?? [])]), secret: ['s000'] } 147}
149const bank = bankJev.every(E, { 150 segments: 8, 151 forget: ['secret'], // the solver never hears today's word 152 sample: { secret: 2 }, // today's word is drawn from Jev's probabilities 153 allow: { 154 ...Object.fromEntries(BANKS.map((b, i) => [b, (d) => planFor(d).banks[i]])), 155 secret: (d) => planFor(d).secret, 156 }, 157}) 158const { next } = nextJev.every(E, { 159 after: Object.fromEntries(BANKS.map((b) => [b, bank[b]])), 160 fallback: { next: 'b1' }, // waiting on Jev plays a guess (guessAt), never the ending 161 // the finalists: each bank that chose a word, and the end marker 162 // the finalists: each bank that chose a word, and the end marker, which 163 // is its fallback so always offered, and the only option once the game is 164 // over. A bank that passed still has a first word (guessAt), so b1 is 165 // offered when none chose one. 166 allow: { 167 next: (d) => { 168 if (gameOver) return ['end', 'b1'] // b1 is the fallback, so always offered; stateAt ends the game anyway 169 const words = SLOTS.filter((_, i) => d[BANKS[i]] && d[BANKS[i]] !== 'end') 170 return [...(words.length ? words : ['b1']), 'end'] 171 }, 172 }, 173})
── the form, as rules in code ── The intro, then a guess per section (a slot: which bank's word it is), then the end marker. As written, a slot ends on the end marker, so a finalist question with only the end left is the end; the cap of eight sections is the six tries.
── the mix: Jev sets each part every section, as in the other songs ── what each section is, for the mix: decidedThisSection.next names it
187const mixState = { 188 title: 'ALL GREEN', 189 what: 'chiptune synth-pop in 5/4 about JevLM cheating at Wordle: every guess is a scan of the word banks, the guess spelled out, then its row of tiles as rhythm', 190 sections: { 191 intro: 'the song opens: the band, "Five letters. Six tries.", the scan through all ten banks, "J. E. V. doesn\'t write. J. E. V. picks."', 192 b1: 'a guess: the scan, "choose the next fragment", the guess spelled out, its tiles, the row as a riff, the tile flip', 193 end: 'the end marker: on a win the chorus on C major; on a loss a grey row and the word spelled out', 194 }, 195 get board() { return wordle.response_prefix }, 196} 197for (const x of SLOTS.slice(1)) mixState.sections[x] = mixState.sections.b1 198const level = (part) => score('How much of ' + part + ' should the section about to play (decidedThisSection.next, see sections) have? Pull parts back to let others speak or to build tension, and bring them in full for the payoff', [ 199 'back: under the rest of the mix', 200 'full: as written', 201]) 202const djJev = jev({ 203 state: mixState, 204 questions: { 205 drums: level('the drums (a 3+2 chiptune kit: kick, snare, hats, the turnaround fill)'), 206 stabs: level('the chord stabs (square-wave sus chords that resolve to C major as the greens come in)'), 207 bass: level('the bass (a triangle bass on the chord roots)'), 208 tiles: level('the tiles (a kick and tone per green, an off-beat snare per yellow, a tick per grey, then the row as a riff and the flip)'), 209 vocals: level('the voice (the spelled guess, "choose the next fragment", the intro and ending lines)'), 210 energy: score('How intense should the section about to play be? Low while searching, rising as greens accumulate, all out on the winning row', [ 211 'held back: about half volume', 212 'steady: well under full', 213 'driving: nearly full', 214 'all out: full volume', 215 ]), 216 }, 217}) 218const dj = djJev.every(E, { 219 after: { next }, 220 fallback: { drums: 1, stabs: 1, bass: 1, tiles: 1, vocals: 1, energy: 2 }, 221}) 222const lvl = (name) => dj[name].score.round()
back plays at half velocity, full as written; no part can be silenced, so the song is never silent (Jev set every part of the intro "out", 2026-09-26)
225const part = (name, pat) => pat.mul(velocity(lvl(name).add(1).div(2)))
── the board, read back from the decisions ──
228const secretWord = () => SETTER[Math.max(0, SETTER_IDS.indexOf(first(bank.secret.choice, 0)))]
A slot's word: its bank's choice, or, when that bank has none (Jev was not reached), the first word of that bank.
the rows guessed before segment n
237const boardBefore = (n) => { 238 const secret = secretWord() 239 const rows = [] 240 for (let j = 1; j < n; j++) { 241 const slot = SLOTS.indexOf(first(next.choice, j)) 242 const word = slot < 0 ? null : guessAt(j, slot, rows) 243 if (!word) break 244 rows.push({ word, tiles: tilesOf(word, secret) }) 245 } 246 return rows 247}
what segment n plays
249const stateAt = (n) => { 250 const section = first(next.choice, n) 251 if (n === 0) return { kind: 'intro' } 252 const rows = boardBefore(n) 253 if (section === 'end' || solved(rows) || rows.length >= TRIES) { 254 return { kind: 'end', won: solved(rows), secret: secretWord(), tries: rows.length } 255 } 256 const slot = SLOTS.indexOf(section) 257 const word = slot < 0 ? null : guessAt(n, slot, rows) 258 const tiles = word ? tilesOf(word, secretWord()) : 'xxxxx' 259 return { 260 kind: 'guess', 261 no: rows.length + 1, 262 word, 263 tiles, 264 greens: [...tiles].filter((t) => t === 'g').length, 265 banks: banksOf(candidates(rows)).length, 266 finalists: 1 + BANKS.filter((b) => first(bank[b].choice, n) !== 'end').length, 267 } 268}
One hap a section, holding what it plays; none once the form has ended.
270const game = new Pattern((st) => { 271 const haps = [] 272 for (let n = Math.max(0, st.span.begin.div(E).floor().valueOf()); n * E < st.span.end.valueOf(); n++) { 273 const whole = new TimeSpan(Fraction(n * E), Fraction((n + 1) * E)) 274 const part = whole.intersection(st.span) 275 if (!part || !next.choice.query(st.setSpan(part)).length) continue 276 haps.push(new Hap(whole, part, stateAt(n))) 277 } 278 return haps 279})
── sound ──
282const bars = (list) => cat(...Array.from({ length: 8 }, (_, i) => list[i] ?? silence)) // one entry a bar
Built at runtime, so parsed here: only a literal "…" in the code is mini-notation to the transpiler
the tonic, C major, a chord tone per tile; a yellow is the tone beside it
288const TONE = ['c5', 'e5', 'g5', 'c6', 'e6'] 289const BESIDE = ['d5', 'f5', 'a5', 'd6', 'f6'] 290const SCAN = ['c5', 'd5', 'f5', 'g5', 'a5', 'c6', 'd6', 'f6', 'g6', 'a6'] 291const FINAL = ['c7', 'a6', 'g6', 'f6', 'd6', 'c6', 'a5', 'g5', 'f5', 'd5'] 292const CHORDS = { 293 Csus4: 'c4,f4,g4,c5', Csus2: 'c4,d4,g4,c5', C: 'c4,e4,g4,c5', F: 'f3,a3,c4,f4', Fadd9: 'f3,a3,c4,g4', 294 Am7: 'a3,c4,e4,g4', Am: 'a3,c4,e4,a4', Gsus4: 'g3,c4,d4,g4', G7sus4: 'g3,c4,d4,f4', G7: 'g3,b3,d4,f4', G: 'g3,b3,d4,g4', Dm: 'a3,d4,f4,a4', 295} 296const ROOT = { Csus4: 'c2', Csus2: 'c2', C: 'c2', F: 'f2', Fadd9: 'f2', Am7: 'a1', Am: 'a1', Gsus4: 'g1', G7sus4: 'g1', G7: 'g1', G: 'g1', Dm: 'd2' }
drums, in 3+2: kick on 1, the and of 2, and 4; snare on 3 and 5
299const kick = s("bd:3").struct("x ~ ~ x ~ ~ x ~ ~ ~").gain(.9) 300const snare = s("[sd:1,sid:10]").struct("~ ~ ~ ~ x ~ ~ ~ x ~").gain(.55) 301const hats = s("sid:7*10").gain(".45 .2 .35 .2 .45 .2 .35 .2 .4 .2") 302const groove = stack(kick, snare, hats).orbit('drums') 303const turn = stack(kick, s("[sd:1,sid:10]").struct("~ ~ ~ ~ x ~ ~ ~ [x x] [x x x x]").gain(".55 .55 .4 .45 .5 .6 .7"), hats).orbit('drums') 304const sparse = stack(s("bd:3").struct("x ~ ~ ~ ~ ~ ~ ~ ~ ~").gain(.8), hats.mul(gain(.7))).orbit('drums') 305const onlyHats = hats.mul(gain(.8)).orbit('drums') 306const crash = s("hh27:1").gain(2.4).orbit('drums')
chord stabs, pulse-wave chiptune, and a triangle bass in eighths
308const chord = (name) => mini('[' + CHORDS[name] + ']') 309const stab = (name) => note(chord(name)).struct("~ x ~ ~ x ~ x ~ ~ x").s('square').lpf(2600).decay(.18).sustain(0).gain(.22).orbit('stabs') 310const bass = (name) => note(ROOT[name]).struct("x ~ x x ~ x ~ x x ~").s('triangle').decay(.2).sustain(.5).gain(.7).orbit('bass') 311const hit = (name) => stack(note(chord(name)).s('square').lpf(3000).decay(1.6).sustain(0).gain(.3), note(ROOT[name]).s('triangle').decay(1.6).sustain(0).gain(.8)).struct("x ~ ~ ~ ~").orbit('stabs')
the scan: a glassy FM note per bank asked; the finalists, a note each, from the top
the tiles, one a beat: green a kick and its chord tone, yellow an off-beat snare and the tone beside its place, grey a dry tick
318const tileBar = (tiles, tones = TONE) => { 319 const at = (fn) => steps([...tiles].flatMap((t, i) => fn(t, i))) 320 return stack( 321 s("bd:3").struct(at((t) => [t === 'g' ? 'x' : '~', '~'])).gain(.9).orbit('drums'), 322 note(at((t, i) => [t === 'g' ? tones[i] : '~', '~'])).s('square').lpf(4000).decay(.4).sustain(.2).gain(.3).orbit('tiles'), 323 s("sd:1").struct(at((t) => ['~', t === 'y' ? 'x' : '~'])).gain(.5).orbit('drums'), 324 note(at((t, i) => ['~', t === 'y' ? BESIDE[i] : '~'])).s('square').lpf(2500).decay(.2).sustain(0).gain(.22).orbit('tiles'), 325 s("click:1").struct(at((t) => [t === 'x' ? 'x' : '~', '~'])).gain(.7).orbit('drums'), 326 ) 327}
the row as a riff: green its chord tone twice, yellow sliding in from beside, grey rests
the tile flip: a blip a beat, high for green, mid for yellow, low and dull for grey
what a guess plays, 8 bars: scan | finalists | spell | tiles | riff | riff | flip | turn The harmony waits on the greens: sus chords until the row is all green.
338const home = (g) => (g >= 5 ? 'C' : g >= 3 ? 'Csus2' : 'Csus4') 339const dominant = (g) => (g >= 5 ? 'G7' : g >= 3 ? 'G7sus4' : 'Gsus4') 340const guessSection = (st) => { 341 const chords = [home(st.greens), home(st.greens), 'Fadd9', null, 'Am7', 'Fadd9', dominant(st.greens), dominant(st.greens)] 342 const word = st.word ?? ' ' 343 return stack( 344 part('stabs', bars(chords.map((c) => (c ? stab(c) : null)))), 345 part('bass', bars(chords.map((c) => bass(c ?? 'C')))), 346 part('drums', bars([sparse, sparse, groove, null, groove, groove, onlyHats, turn])), 347 bars([scanBar(st.banks), finalBar(st.finalists)]).mask("<1 1 0 0 0 0 0 0>"), 348 part('vocals', bars([null, st.no % 2 === 1 ? s('agchoose').gain(1.1).room(.15).orbit('vocals') : null, st.word ? spell(word) : null])), 349 part('tiles', bars([null, null, null, tileBar(st.tiles), riffBar(st.tiles), riffBar(st.tiles), flipBar(st.tiles), null])), 350 ) 351}
the intro: "Five letters. Six tries.", the scan, "J. E. V. doesn't write. J. E. V. picks."
353const introSection = () => stack( 354 part('stabs', bars(['Csus4', 'Csus4', 'Csus4', 'Fadd9', 'Csus4', 'Fadd9', 'Gsus4', 'Gsus4'].map((c, i) => (i < 2 ? null : stab(c))))), 355 part('bass', bars(['Csus4', 'Csus4', 'Csus4', 'Fadd9', 'Csus4', 'Fadd9', 'Gsus4', 'Gsus4'].map(bass))), 356 part('drums', bars([onlyHats, sparse, groove, groove, groove, groove, groove, turn])), 357 bars([scanBar(10), scanBar(10), null, null, null, null, null, null]), 358 part('vocals', bars([s('agfive').gain(1.1).room(.15).orbit('vocals'), null, null, null, s('agpicks').gain(1.1).room(.15).orbit('vocals')])), 359 // every letter, silent: the page loads each sound the song plays as written before it starts 360 bars([n(steps([...Array(26).keys()])).s('agletter').gain(0).orbit('vocals')]), 361)
the end marker: a win's chorus on the tonic, or a grey row and the word
363const endSection = (st) => 364 st.won 365 ? stack( 366 part('stabs', bars([hit('C'), stab('C'), stab('C'), stab('F'), stab('F'), stab('Am'), stab('G'), null])), 367 part('bass', bars([null, bass('C'), bass('C'), bass('F'), bass('F'), bass('Am'), bass('G'), null])), 368 part('drums', bars([crash.struct("x ~ ~ ~ ~"), groove, groove, groove, groove, groove, turn, stack(kick.struct("x ~ ~ ~ ~ ~ ~ ~ ~ ~"), crash.struct("x ~ ~ ~ ~"))])), 369 part('tiles', bars([null, riffBar('ggggg'), riffBar('ggggg'), null, null, riffBar('ggggg'), riffBar('ggggg'), hit('C')])), 370 part('vocals', bars([s('agend').gain(1.1).orbit('vocals'), null, null, s('agpicks').gain(1.1).room(.15).orbit('vocals'), null, s('agcost').gain(1.1).room(.15).orbit('vocals')])), 371 ) 372 : stack( 373 part('stabs', bars([hit('Csus4'), null, stab('Am'), stab('Am'), stab('F'), stab('Dm'), stab('G'), null])), 374 part('bass', bars([null, null, bass('Am'), bass('Am'), bass('F'), bass('Dm'), bass('G'), null])), 375 part('drums', bars([crash.struct("x ~ ~ ~ ~"), null, sparse, sparse, groove, groove, turn, stack(kick.struct("x ~ ~ ~ ~ ~ ~ ~ ~ ~"), crash.struct("x ~ ~ ~ ~"))])), 376 part('tiles', bars([null, tileBar('xxxxx'), null, tileBar('ggggg', ['a4', 'c5', 'e5', 'a5', 'c6']), null, null, null, hit('Am')])), 377 part('vocals', bars([s('agend').gain(1.1).orbit('vocals'), null, spell(st.secret), null, null, s('agcost').gain(1.1).room(.15).orbit('vocals')])), 378 ) 379const played = new Map() 380const sectionFor = (st) => { 381 const key = JSON.stringify(st) 382 if (!played.has(key)) played.set(key, st.kind === 'intro' ? introSection() : st.kind === 'guess' ? guessSection(st) : endSection(st)) 383 return played.get(key) 384}
386const once = (p) => p.mask("<1!64 0!936>") // play once (the cap: 8 sections of 8 bars), then silence