Files
escape-builder/TODOS.md
Claude Agent d67f6ddc15 S3 pas 1: Bomberman complet în gameArcade
Înlocuiește labirintul simplu cu Bomberman (port din scratch/bomberman-proto.html):
bombe + explozii în lanț, cutii distructibile, AI dușmani BFS urmărire, 3 vieți +
respawn cu progres puzzle păstrat, plasare aleatoare (PRNG seedat), buton bombă +
overlay game-over. Păstrează contractul motorului: openPuzzle/onDoorSolved/showFinal/
modalOpen/roomReady — uși=N puzzle-uri (modal real), cufăr=scăpare. Demo regenerat.

Verificat: smoke 21/21 (zero regresie) + gameplay 6/6 in arcade-ul integrat
(bombă sparge cutie, AI urmărește, respawn păstrează progres, ușă→modal real,
cufăr→final) + captură vizuală. Board: TODOS.md S3 pas 1 [x].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 10:25:48 +00:00

7.5 KiB
Raw Blame History

TODOS — Escape Room Builder

Backlog post-PR1 și note tehnice pentru iterațiile viitoare. Referință plan complet: ~/.gstack/projects/romfast-escape-builder/ceo-plans/2026-06-12-campania-multi-stil.md

Acest fișier e BOARD-UL DE PROGRES (sursa durabilă). Task list-ul din harness se resetează între sesiuni → se uită. Aici nu. La fiecare sesiune: citește board-ul activ de mai jos ÎNTÂI, mută [ ]→[~]→[x] pe măsură ce avansezi, commit-uiește schimbarea. Convenție: [ ] neînceput · [~] în lucru · [x] gata+verificat · [!] blocat.


▶ BOARD ACTIV — Iterația 2 (Adventure Mode / restyle)

Direcția cerută de user (decizii confirmate, vezi HANDOFF.md). Model hibrid ca la PR1: părțile grele se prototipează în PARALEL în scratch/, verificate jucabile, apoi integrator le portează în escape-builder.html (un singur fișier, integrare secvențială).

  • S1 — fix sunet campanie (GATA, verificat în browser) Cauză reală: orchestratorul crea beep._ctx lazy la primul parent.beep() din iframe; gestul din iframe NU deblochează AudioContext-ul părintelui → ctx suspended → tăcere. (Ipoteza HANDOFF „beep nedefinit" era greșită; beep e la escape-builder.html:1725.) Fix: deblocare ctx în handler-ul btn-start (gest direct pe părinte), escape-builder.html:1928. Verificat: scratch/verify-audio-s1.mjs → ctx running după start (era NO_CTX). Smoke 21/21. TODO la S4: portează asertarea beep._ctx.state==='running' în tests/smoke.mjs.
  • S2a — prototip Bomberman completscratch/bomberman-proto.html (GATA, 8/8 verificat de mine) Grid 15×13, bombe timer 2.4s + explozii lanț, cutii distructibile, AI dușmani BFS urmărire, 3 vieți + respawn cu progres puzzle PĂSTRAT (stare separată), PRNG seedat (window.__seed), uși roșii openPuzzle(id,cb) + cufăr = scăpare. Hooks window.__game. Test: scratch/verify-bomberman.mjs (+ pw-bomberman.config.mjs). Am corectat testul AI: dușmanii merg DOAR pe podea → cei închiși în cutii nu se mișcă (corect); testul curăță cutiile. Note S3: dușmanii confinați de cutii e intenționat — la integrare asigură căi sau acceptă.
  • S2b — prototip hartă overworldscratch/overworld-proto.html (GATA, 7/7 verificat de mine) Hartă tile 20×18, player top-down (săgeți/WASD/dpad), 4 uși + exit deblocat după toate. Orchestrator identic cu gameCampaign: mountRoom/roomReady/nextRoom/roomError/timeout 4s, resume localStorage, idempotență. Hooks test window.__map. Test: scratch/test-overworld.mjs. Note S3: stub makeSrcdocTPL[style].replace('__CFG__', fn); DOOR_TILES paralel cu puzzles; backslash dublu la portare. Ordine rezolvare LIBERĂ.
  • S2c — STYLES.md — direcție restyle pentru cele 5 stiluri (GATA, 775 linii). Top 3 impact/efort: terminal .line.dim fix WCAG (3.1:1→6.1:1); classic card glow + progres bar; chat header backdrop-filter + bulă NPC distinctă. Consumat de S3.
  • [~] S3 — integrare în escape-builder.html (secvențial: Bomberman → Overworld → restyle; smoke după fiecare) Portează prototipurile (template literals → DUBLEAZĂ backslash-urile) + regenerează demo-urile. Pas 1: Bomberman → gameArcade. Pas 2: Overworld → gameCampaign. Pas 3: restyle 5 stiluri. - [x] Pas 1 — Bomberman în gameArcade (GATA). Păstrează openPuzzle/onDoorSolved/showFinal/ modalOpen()/roomReady; uși=N puzzle-uri, cufăr=scăpare. Demo regenerat. Smoke 21/21 + verificare gameplay 6/6 (scratch/verify-arcade-integrated.mjs) + captură. - [ ] Pas 2 — Overworld în gameCampaign. - [ ] Pas 3 — restyle 5 stiluri (din STYLES.md).
  • [!] S4 — extinde tests/smoke.mjs (blocat de S3) — bomberman, hartă, audio, regresie.

Stare la 2026-06-13: PR1 livrat (a42c960, suita 21/21). Iterația 2 = neîncepută; scratch/ are doar artefacte PR1, fără proto-uri noi.


Post-PR1 (după ship-ul campaniei)

Muzică accelerată la timer (PR2 / T10)

  • Audio ambient în campanie: track calm → accelerare progresivă sub 1 minut.
  • Ownership: părintele deține AudioContext; camerele nu știu de muzică.
  • Fallback: zero pedeapsă dacă AudioContext lipsă (webview restricitve).
  • Edge: muzica se oprește la speechSynthesis.cancel() dacă vocea e activă simultan.
  • Legat de: T10 (PR2), timer countdown în bara chrome (§Design pct. 10).

Edge case-uri voce (SpeechSynthesis) — PR2

  • speechSynthesis.getVoices() poate fi gol sincron → ascultă voiceschanged.
  • Fără voce ro-* → fallback la vocea default (nu crash, nu tăcere).
  • Voce activă mid-cameră → speechSynthesis.cancel() la demontare cameră (pater deține).
  • parent.voiceSay(text) = no-op în jocurile simple (funcția nu există) → guard typeof parent.voiceSay === 'function'.
  • Referință: D10 din plan; E2 Etapa 2 pct. 3.

Unificarea finale() din terminal pe SNIP.finalJs (PR2 primul pas)

  • Astăzi terminalul are propria funcție finale() (escape-builder.html:863) care NU folosește SNIP.finalJs.
  • Migrarea pe SNIP.finalJs deblochează ramura _campaign uniformă pentru toate cele 5 motoare.
  • Prim pas al Etapei 2 (D7): migrarea gameClassic pe libJS+SNIP → regresie manuală pe classic.
  • Referință: planul §Etapa 2 pct. 1; D7.

Audit a11y motoare existente (post-PR1, sub harness Playwright)

  • Ținte tap ≥ 44px: dpad arcade, butoane tf/choice, butonul "Trimite" din chat.
  • Contrast ≥ 4.5:1: text terminal dim (#1f9c4a pe #04130a — verifică), hint text clasic.
  • @media (prefers-reduced-motion: reduce): dezactivează pop, flip, flipin, shake, confetti, bin — stările finale apar direct.
  • Focus & Enter: "Deschide ușa" (campanie) focusabil + Enter; dpad arcade accesibil cu keyboard.
  • aria-label pe progres: bara chrome din campanie (aria-label="Camera X din Y").
  • Referință: §Design pct. 13 (TD5, PR2); D19 din plan.

Iterația 2 — Adventure Mode v0

(decizie office-hours: fundația contractului de azi e infrastructura directă)

  • Contract de montare (nextRoom, roomReady, roomError) se refolosesc as-is.
  • Motoarele noi (orice stil) implementează aceleași 3 puncte + parent.beep.
  • gameCampaign se extinde cu ramificare: if (answer === 'left') nextRoom({dir: 'left'}).
  • Builder UI: adaugă câmpul "ramificare" per puzzle; drag & drop între camere.
  • Referință: design doc §NOT in scope "Adventure Mode v0".

Iterația 3 — Joc-în-URL + QR

(depinde de măsurarea dimensiunii JSON comprimate)

  • gameHTML(cfg) → URL data: sau LZW/gzip → QR code printabil.
  • Open Question 2 din design doc: câte puzzle-uri încap în 2KB (URL QR L)?
  • Alternative: GitHub Pages export automat; sau link scurt cu backend minimal.
  • Referință: design doc §NOT in scope "Joc-în-URL + QR".

Known improvements (oricând)

  • updateHud duplicat: arcade linia 1003 și point linia 1283 au funcții identice → consolidat în SNIP (T8 din plan, igienă PR1).
  • persist() fără try/catch: builder-ul poate crăpa pe storage plin → guard (D12, T8).
  • esc(L) la inserția innerHTML din point (:1274): un < în câmpul letter strică scena SVG (D13, T8).
  • Validare 0 puzzle-uri: export și preview blocate cu mesaj ghidant (T5).
  • Stil invalid la import JSON: avertisment în builder + rotație automată (T5, D8).