566 Commits
Author SHA1 Message Date
agwandClaude Opus 5.5 d22f1d5e2e Tegn og Gæt: tegn dit eget ord på telefon, storskærm og speaker
CI / test (push) Successful in 1m25s
Telefonen og storskærmen siger "Tegn dit eget ord" i trin 1 ved et
lige antal spillere, og speakeren har fem faste replikker til det
(forvarmes med de andre faste). dev.html?game=tegn har fasen draw-own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:59 +02:00
agwandClaude Opus 5.5 5de261acd7 Tegn og Gæt: kæden slutter altid på et gæt
Ved et lige antal spillere får kæden et trin mere: i trin 1 tegner
ejeren sit eget ord, og rotationen starter et trin senere. Antal trin
hedder nu steps og bruges i step-eventet, snapshot og afsløringen;
self.n er antal spillere. Snapshot får step.own til trin 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:59 +02:00
agwandClaude Opus 5.5 7a5c37290f Spionen: skærmenes overskrifter følger, hvem der blev fanget
CI / test (push) Successful in 47s
Fra review og QA:
- Telefonen siger "Du slap væk!" til en spion, der ikke selv blev fanget
  (også når den anden spion blev det), "Du gættede ordet!" til den fangede
  spion, der gættede, og agenterne får "I fangede den ene spion", når den
  anden slap.
- Går den eneste spion i runden, siger storskærmen "Spionen forlod
  missionen" og telefonerne "Spionen forlod spillet" i stedet for, at
  spionen vandt (result.spies_left).
- Lighedsstemplet siger "spionerne slipper" med to spioner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:59 +02:00
agwandClaude Opus 5.5 b83a464e24 Spionen: to spioner i flertal, også når de slipper
Fra QA: med to spioner åbnede resultatet stadig med en replik i ental, når
begge slap (lighed, ingen stemmer) eller den anklagede var uskyldig. Nu er
der result_free_two og result_innocent_two (den sidste også generisk).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:58 +02:00
agwandClaude Opus 5.5 3ed6f252ec Docs: Spionen i PROTOCOL.md og README
Faser, tider, stikordenes og gættets regler, afstemning, to spioner, point
og priser, handlinger og fejlkoder, hvad der er hemmeligt hvor, og et
snapshot. README nævner spillet, mappen, bots og dev.html.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:57 +02:00
agwandClaude Opus 5.5 78fa557da4 dev.html: Spionens skærme i alle faser
?game=spion viser storskærmen og tre telefoner (en agent, spionen og
publikum) i alle faser, også med rollekortet vist (clue-open, vote), dommen
med stempel og ved lighed, og resultatet med to spioner. Telefonernes data
er som serverens: ingen stikord i clues, intet svar under dommen.
spion.js kan vise kortet uden tryk (kun til harnessen). Stemmesøjlerne er
lige lange, også når en spiller har publikumsstemmer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:56 +02:00
agwandClaude Opus 5.5 3ec45ca66b tts_warm: Spionens replikker (--only spion)
Spionens faste replikker (de faste, reglerne, temaerne, rundernes nummer og
starten for 4-10 spillere) står i budget-køen efter Tegn og Gæts og før Fup
og Fakta's spørgsmål; de generiske står sammen med de andre spils generiske,
og menuen har en intro mere. Samme tekst i to spil er ét klip ("Temaet er
Dyr."). --dry-run uden nøgle:

  menuens intro 3 klip/854 tegn; generiske 360/19195; Tegn og Gæt 286/11771;
  Spionen 166/7152; Fup og Fakta faste 167/9227; fest 56/2657.
  --only spion: intro 1/283, generiske 99/5010, faste 166/7152.

Replikken med ordet ved resultatet forvarmes ikke (et klip pr. ord og
variant); uden live-stemme siges den generiske.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:55 +02:00
agwandClaude Opus 5.5 5b24404eac Spionen: rettelser fra review og QA, og bots
Replikker:
- To spioner siges i flertal ("Spionerne var ..."), også i den generiske
  udgave; fanges den ene, og den anden slipper, er det en halv sejr
  ("Den ene spion er fanget, men den anden slap væk"), ikke "Agenterne
  vinder". Storskærmens overskrift følger med.
- Er spionen gået i løbet af runden, siges "Spionen forlod missionen", og
  navnet står stadig i afsløringen (motoren husker spionernes navne fra
  rundens start; storskærmen viser dem uden farve).
- Fire små replikker skrevet om (vedkommende, "Måske er det ansigtet",
  skarpeste øje = flest rigtige stemmer, vinderen gentog ikke den faste).

Ord: Spionen bruger ikke ord under tre bogstaver ("is", "fe"); de står inde
i for mange andre ord (isvaffel), til at stikordene kan holdes fri af dem.
Mad har 17 ord, Eventyr 15.

Test: speaker-testen kører uden rigtige ventetider (37 s til 4 s for hele
filen); skift-testen venter på det nye spils lobby i stedet for at gætte
på tiden.

deploy/bots.py --game spion: tilfældige stikord (prøver et andet, hvis det
afvises), tilfældige stemmer og gæt; værten forkorter snakken. En stemme,
der kommer et øjeblik efter, at fasen sluttede, er ikke en fejl.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:54 +02:00
agwandClaude Opus 5.5 d5d60ad75d Spionen: rum, speaker, skærme og register
- party/games.py: Spionen i menuen (4-10 spillere, 10-15 min, runder 3/4/5,
  regler til/fra), så intro og skift af spil i rummet virker.
- party/spion.py: SpionRoom med telefonens handlinger (start, submit_clue,
  vote, spy_guess, react, play_again), speakerens replikker pr. begivenhed
  og et "ti sekunder" før stikordenes deadline. Reglernes oplæsning er
  BaseRoom's.
- Speakeren (spionen/narrator/lines.json og generic.json) siger aldrig
  ordet eller hvem der er spion før resultatet: dommen spørger kun, svaret
  kommer med gættet eller resultatet. Replikker med navne eller ordet har
  generiske afløsere, så spillet kører med WPP_TTS_LIVE=off. Replikken med
  ordet ved resultatet forvarmes ikke (et klip pr. ord); uden live-stemme
  siges den generiske ("Spionen og ordet står nu på skærmen").
- spion.js: telefonens rollekort (skjult, til man trykker, og lukker igen
  ved hver ny fase), stikord, afstemning med store knapper, spionens gæt og
  resultatet; storskærmens tema, stikordene et ad gangen, snakken med
  nedtælling, stemmerne og stemplet "SPION!"/"Uskyldig!" i dommens sidste
  sekunder, gættet og resultatet. Under dommen viser telefonen kun
  "Stemmerne er talt". host.js: et spil kan melde sine egne tidsfaser
  (spring over).

Test (test_spion): helt spil over WebSocket med fire telefoner, og skift
fra Tegn og Gæt til Spionen i samme rum; hver besked til hver telefon
læses for ordet og spionlisten. Speakeren: ordet siges aldrig før
resultatet, og alt uden navne eller ordet er forvarmet. Replikkerne er med
i sprogtesten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:54 +02:00
agwandClaude Opus 5.5 ccb925b89a Spionen: et stikord må ikke indeholde ordet
Fra QA: sammensatte ord med ordet i (pingvinunge, hundehus, pizzabager,
togskinne) blev godtaget, og så stod ordet på storskærmen for spionen.
Nu afvises et stikord fra en, der kender ordet, hvis ordet står inde i det
(ord på tre bogstaver eller flere; "is" ville ellers ramme alt for meget).
Prisen er, at et andet ord, der tilfældigvis indeholder ordet, også
afvises ("hvalp" til "hval"); en lækage er værre end en afvisning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:53 +02:00
agwandClaude Opus 5.5 2980a7d7b0 Rum: reglernes oplæsning ligger i BaseRoom
Tegn og Gæts _narrate_rules (et regelkort pr. replik, i replikkens længde)
flyttes uændret til BaseRoom, så Spionen kan bruge den samme. Fup og Fakta
har sin egen og er uberørt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:52 +02:00
agwandClaude Opus 5.5 d17493f76b Spionen: spionen kan ikke aflure de andres stikord
Fra review. Stikordet må skiftes i hele fasen, og et stikord, en anden
havde skrevet, blev afvist med "har en anden allerede skrevet". Så kunne
spionen prøve kandidater og få at vide, hvilke spor de andre havde
skrevet. Nu holdes spionens stikord hverken op mod ordet eller de andres
stikord (skriver spionen det samme som en anden, står det to gange på
skærmen, og det er et godt spor). Afviger fra "samme stikord to gange"
for spionens vedkommende.

Desuden:
- Stikord holdes op mod ordet og dets bøjninger, men ikke stavefejl
  ("hvalp" er et fint stikord til "hval"); stavefejl tæller stadig i
  spionens gæt.
- Om den anklagede var spion står kun i storskærmens data under dommen;
  telefonerne får det først, når gættet begynder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:51 +02:00
agwandClaude Opus 5.5 a448cd2b73 Spionen: spilmotor og test
Ren motor i samme stil som Tegn og Gæt (now som parameter, events til
speakeren, snapshot pr. rolle). En runde: stikord (40 s), stikordene på
storskærmen ét ad gangen i tilfældig rækkefølge, snak (60 s), afstemning
(30 s), dommen, spionens sidste gæt (30 s) og resultatet. 4-10 spillere,
3-5 runder (standard 4).

- Roller: én spion, to fra otte spillere; ingen er spion to runder i træk,
  hvis det kan undgås. Tema og ord skifter (intet ord to gange i et spil).
- Stikord: ét ord, højst 20 tegn; ikke temaet og ikke et stikord, en anden
  har skrevet i runden. For dem, der kender ordet, heller ikke ordet selv,
  en bøjning eller en lille stavefejl af det. Spionens stikord holdes ikke
  op mod ordet, for en afvisning ville røbe det.
- Samme ord (stikord og spionens gæt): uden store/små bogstaver, mellemrum
  og bindestreger, bøjninger (en/et/er/erne/ene/e/s, også med fordoblet
  konsonant og uden slut-e), og små stavefejl efter længden: ingen under
  fire bogstaver, én op til syv, to derover. Kun standardbiblioteket.
- Afstemning: ikke på sig selv; flest stemmer bliver anklaget; lighed eller
  ingen stemmer: ingen anklages, og spionerne slipper. Publikum stemmer for
  sjov (vises for sig, tæller ikke).
- To spioner: den anklagede er fanget og gætter; den anden slap. En stemme
  på en af dem er rigtig.
- Point: +100 for at stemme på en spion, +300 til en spion, der slap, +200
  til en fanget spion, der gætter ordet. Priser: Bedste løgner, Skarpeste
  øje, Mest mistænkt.
- Hænger aldrig: manglende stikord og stemmer løber ud; afbrudte holder
  ikke runden tilbage; går den anklagede spion, slutter runden; er der
  færre end fire tilbage, slutter spillet efter runden.
- Hemmeligheden: ordet står kun i kortet til dem, der kender det; hvem der
  er spion står ingen steder før dommen. Testen læser hvert snapshot i hver
  fase (og fejler, hvis ordet sættes i temaet eller på spionens kort).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:50 +02:00
agwandClaude Opus 5.5 211a9c1fab Temaer: julens and er med i Spionen igen
Et godt konkret ord (julemiddagens and); fra review. Jul har nu 18 ord til
Spionen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:49 +02:00
agwandClaude Opus 5.5 2ceb5290f8 Temaer: fælles temabank i party/data/themes.json
Tegn og Gæts temaer flyttes til ét sted (party/data/themes.json med
loaderen party/themes.py), så Spionen kan bruge de samme i stedet for en
kopi. Navne og ord er uændrede, så Tegn og Gæt og dets forvarmede
{tema}-replikker opfører sig som før.

Spionen skal bruge ord, det er nemt at give stikord til: spy_themes() giver
de temaer, der har mindst 15 konkrete navneord i ét ord. "spion": false
udelader et tema (film og serier: titler), og "spion_skip" enkelte ord (si,
and, frikvarter, lektier, hygge). Det giver 13 temaer med 15 til 18 ord.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:49 +02:00
agwandClaude Opus 5.5 477e10557a Speaker: bedste tegning siger ikke "aftenens kunstner" lige før vinderen
CI / test (push) Successful in 58s
Tegn og Gæts faste vinder-replik bruger "Aftenens kunstner", så den
generiske pris for bedste tegning, der kan komme lige før, siger nu
"Kunstneren er fundet". Fra QA.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:48 +02:00
agwandClaude Opus 5.5 0f0138e772 tts_warm: fest-replikkerne forvarmes også uden FEST_VOICE_ID
Fundet i bot-røgtesten med WPP_TTS_LIVE=off: uden FEST_VOICE_ID taler et
fest-spil med standardstemmen, men tts_warm lavede kun de faste fest-
replikker (fest-velkomst, fest-reglerne, fest-drillerierne), når der var
en fest-stemme. Så var de tavse uden live-kald. Nu laves de altid, med
fest-stemmen eller standardstemmen som rummet, og uden at gentage dem, der
allerede står i "faste replikker" (56 klip, 2657 tegn uden fest-stemme).
Med FEST_VOICE_ID sat er intet ændret.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:42 +02:00
agwandClaude Opus 5.5 33849186ba tts_warm: --only tegn tager ikke Fup og Fakta's fest-replikker med
De fælles fest-replikker blev filtreret på stemmen, så uden FEST_VOICE_ID
kom de med i en Tegn og Gæt-kørsel. Nu filtreres der på nøglen:
--only tegn giver 131 generiske klip (7669 tegn). Fra review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:36 +02:00
agwandClaude Opus 5.5 4d1a2ad01d Hjernen: ingen kald til replikker, der alligevel ikke kan siges
Kan stemmen ikke laves live (WPP_TTS_LIVE=off, ingen nøgle, pause efter en
fejl eller lav saldo), siges en fast replik i stedet for hjernens, så
kaldene var spildt. Nu springes de over, når tts.live_ok() er falsk:
fremskridt under løgnene, drillerier, afsløringens og oplæsningens
kommentarer og slutanmeldelsen. Dommeren (judge_lie) kaldes som før, for
den afgør, om en løgn er sandheden. Lederens beslutning efter review.

Test: i off kaldes dommeren én gang og ingen af de andre; med live-stemme
kaldes de alle som før. test_brain's rum-tests siger nu selv, at stemmen
er live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:30 +02:00
agwandClaude Opus 5.5 8cba2e8071 tts_warm: forvarm de generiske replikker lige efter introen
De generiske replikker (fælles, Fup og Fakta, Tegn og Gæt og afsløringens
intro med første kæde) står i budget-køen efter menuens intro og før
Tegn og Gæts faste replikker; rækkefølgen bag dem er uændret. Fest-
replikkerne laves med fest-stemmen, som rummet siger dem. --only begrænser
til det valgte spil, og --dry-run viser dem på deres egen linje:

  generiske replikker: 310 klip, 16737 tegn (--only tegn: 153 klip, 8685 tegn)

Test: alt, et rum kan sige som generisk afløser, ligger i forvarmningen med
den stemme, rummet slår op med.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:24 +02:00
agwandClaude Opus 5.5 cf6d484422 Speaker: forvarmede generiske replikker, når stemmen ikke kan laves live
WPP_TTS_LIVE (settings.TTS_LIVE): auto (standard) eller off.

Én søm i BaseRoom._synth: kan en replik hverken findes i cachen eller laves
live, og kender den en generisk afløser (narrator.Line), siges en af de
generiske, der ligger i cachen. Rummets kø, afsløringens og oplæsningens
tidslinjer og drillerierne går alle igennem den, og storskærmen (og
telefonens drilleri) viser det, der faktisk siges. Et nyt spil får det ved
at bruge Narrator med sin egen generic.json.

tts:
- enabled() = der er en stemme (cachede klip kan spilles uden nøgle);
  can_fetch() = nøgle og stemme (tts_warm og nye klip).
- off: kun cachen, aldrig et kald.
- auto: efter 401, 402, 429 eller timeout holdes der pause med live-kald i
  fem minutter; saldoen tjekkes højst hvert femte minut i baggrunden, og
  under LIVE_MIN_CREDITS laves intet live. Et spil venter aldrig på det.

Hjernen: dens replikker caches aldrig. Kan de ikke siges, siges den faste
replik, hjernen erstattede (hvis den er cachet), ellers dens generiske
udgave; drillerier falder tilbage til de faste drillerier. Hjernen selv
kaldes som før. Tegn og Gæt: afsløringens intro plus første kæde har en
generisk afløser med samme intro.

Tavse, når de ikke er forvarmet: oplæsningen af spørgsmålet og dets note,
oplæsningen af spillernes svar og hjernens slutanmeldelse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:18 +02:00
agwandClaude Opus 5.5 9ebbdfdc4d Speaker: hjerter giver point; ingen trekant i familiesættet
To replikker sagde, at hjerter ikke giver point, men i Fup og Fakta giver
hvert hjerte 100 point. Og "En trekant af mistænksomhed" er skiftet ud med
en replik, der ikke kan misforstås til en familieaften. Fra review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:12 +02:00
agwandClaude Opus 5.5 dc09632044 Speaker: de generiske replikker skrevet om efter review
- Antal spillere: hvert antal fra to til ti har sine egne replikker i
  stedet for de samme tre skabeloner ("Vi er ...", "Med ... spillere",
  "Så er vi ..."); tallet er stadig et ord og aldrig først.
- Fest: slangen er skåret ned ("bestie" fra 21 til 2), og flere fest-
  replikker er sjove på dansk uden et slangord.
- "på skærmen" står én gang i stedet for elleve; næsten-dubletter
  (fuldt hus, gemme sig, kaos, vibe check, favoritten) er væk.
- Flade priser, der bare gentog prisens navn, er skrevet om, og bonus
  nævnes ikke i hver anden replik.
- Rettet: kædens intro (et navn starter ikke en kæde, og en kæde kan
  overleve), "Det er da hyggeligt", aftenens kunstner, "ingen tår denne
  gang", og lie_start lover ikke længere oplæsning, der måske ikke kommer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:06 +02:00
agwandClaude Opus 5.5 ecf94bcbf0 Speaker: generiske replikker uden navne, til forvarmning
Replikker med navne og spillertekst kan ikke laves på forhånd, så uden
live-stemme var de øjeblikke tavse. Nu har hver af dem en generisk udgave,
der giver mening uden navnet (navnet står på skærmen):

- fælles (party/generic_lines.json): 22 velkomster til en ny spiller og
  tre pr. antal spillere fra to til ti (tallet som ord, aldrig først), med
  fest-udgaver til Fup og Fakta's fest-pakke.
- Fup og Fakta (fupogfakta/narrator/generic.json): VIP venter, runde to,
  finalen, stillingen, kategori, narret, husets løgn, sandheden fundet,
  af ingen og af alle, publikums favorit, vinder, priserne og hvem der er
  færdig; fem eller flere hver, og tre i fest-tonen.
- Tegn og Gæt (tegnoggaet/narrator/generic.json): VIP venter, tema, første
  og næste kæde, overlevede, forvandlet, priserne og vinderen.

Narrator.line() giver nu en Line, der kender sin generiske afløser
(generic(accept) vælger kun blandt dem, accept godtager, fx dem i cachen).
Filerne er nøglet på begivenheden, så et nyt spil kun skal skrive sin egen
generic.json. Test: antal, ingen tankestreger, intet tal først i en sætning,
ingen dubletter, kendte lyd-tags, og at alle navnebegivenheder i begge spil
har en generisk udgave (i fest-tonen, hvor der er en fest-replik).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:59:00 +02:00
agwandClaude Opus 5.5 0149bf9bd3 Tegn og Gæt: forrige spils ord står ikke i ordfeltet
CI / test (push) Successful in 50s
Fejl (fundet af QA, også i drift siden 7367b72): telefonen huskede
kladderne under nøglen kode:trin:fase, fx "KLMT:0:word". Nøglen går igen i
næste spil i samme rum, og kladderne blev aldrig glemt, så ved "Spil igen"
(og ved skift til Tegn og Gæt igen) stod det ord, man sendte sidst, allerede
i feltet. Nu glemmes kladderne uden for opgaverne (lobby, tema, afsløring,
slut); inden for et trin overlever de stadig en ny render.

Test: tegn.js's afterPlay kørt i node med en lille falsk DOM (springes over
uden node); den fejler på den gamle tegn.js.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:58:27 +02:00
agwandClaude Opus 5.5 c26a0d52f9 Docs: spilregistret, menuen og skift af spil
PROTOCOL.md: /host/ er menuen (med ?code ved skift), /host/intro/<spil>,
/host/new's felter pr. spil, "game" i alle snapshots (også Fup og Fakta's)
og hvordan et skift af spil virker for telefonerne. README: menuen, skift
af spil, hvor et nyt spil registreres, og dev.html?game=menu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:50:36 +02:00
agwandClaude Opus 5.5 25ea21a4fb Rum: et lukket rum kan ikke vækkes igen
Efter et skift af spil midt i en runde kan det gamle rums sene opgaver
(speakerens oplæsning, dommeren, ventetider) kalde changed() eller
_schedule_timer() bagefter og starte timeren igen uden spillere. Nu sætter
close() et flag, og changed, timeren, udsendelsen, nye replikker og Tegn og
Gæts trin-snapshots gør intet i et lukket rum. Forslag fra review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:49:57 +02:00
agwandClaude Opus 5.5 4cdc497bd0 dev.html: spilmenu, intro og skift af spil
?game=menu viser menuen, introen for hvert spil og menuen/introen ved skift
af spil (rum med 11, så noten om publikum ses). Harnessen får registret fra
games-fixture.js, som test_games holder i takt med party/games.py (og kan
skrive igen med WPP_WRITE_FIXTURE=1). Fup og Fakta-fixtures har game: 'fof',
så brandet er rigtigt igen, og baren har links mellem spillene.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:47:54 +02:00
agwandClaude Opus 5.5 d6a4bb0b52 tts_warm: forvarm menuens intro-replikker først i --budget-køen
Introen pr. spil (navn, tagline og trin, standardstemmen) er præcis den
tekst, /host/intro/<spil> sender til tts.synth, så cache-nøglen passer.
Den står først i budget-køen før Tegn og Gæts replikker og følger
--budget, --reserve og --only (kun det valgte spils intro). Uden --budget
siger kommandoen, hvor mange der mangler; --dry-run tæller dem.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:45:01 +02:00
agwandClaude Opus 5.5 8440be6f84 Skift spil i samme rum: "Vælg andet spil" efter podiet
Podiet har nu "Spil igen" og "Vælg andet spil". Det sidste går til menuen
med rummets kode (/host/?code=ABCD); menuen viser rummet og hvor mange der
venter, og Start sender koden med.

Sømmen ligger i rooms.add_room: får et nyt rum en kode, der allerede kører,
overtager det nye rum spillerne og forbindelserne (BaseRoom.take_over), og
det gamle lukkes (timere og stemmekø). Spillerne joines i det nye spil i den
rækkefølge de kom, med samme navn og token; dem over det nye spils max
bliver publikum. Hver forbindelses room og member_id peges om, så ingen
consumer hænger fast i det gamle rum, og telefonerne får det nye spils
lobby med det samme uden at joine igen. En telefon, der genindlæser, kommer
ind med sit gamle token.

Test (WebSocket): et helt Fup og Fakta-spil til podiet, skift til Tegn og
Gæt i samme rum, og et helt Tegn og Gæt-spil på de samme forbindelser; og
10 spillere til Fup og Fakta (8 spiller, resten er publikum).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:43:24 +02:00
agwandClaude Opus 5.5 0800736b9e Spilmenu på /host/: kort pr. spil og intro med speaker
/host/ er nu en menu bygget af registret (menu.js): et kort pr. spil med
navn, tagline, ikon, antal spillere og ca. varighed. Vælges et spil, kommer
introen med trinene, spillets egne indstillinger (Fup og Fakta's pakker inkl.
arbejde og fest, Tegn og Gæts regler til/fra), Start og Tilbage.

- Fjernbetjening og tastatur: pilene flytter fokus til det nærmeste valgbare
  i den retning, Enter/OK vælger, Escape/Backspace/TV'ets Tilbage og
  browserens tilbage går til menuen. Alt er knapper, også indstillingerne,
  så Enter altid gælder det fokuserede (fejlen fra 64aac36 kan ikke komme
  igen ad den vej). Mus og touch virker som før.
- Speakeren læser introen op: /host/intro/<spil> giver lyden til den faste
  tekst (navn, tagline og trin) med standardstemmen, {} uden stemme.
- Uden JavaScript: én startknap pr. spil fra registret.
- Den gamle pakke-formular og dens CSS er væk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:36:55 +02:00
agwandClaude Opus 5.5 900e6af20d Spilregister: party/games.py, ét sted for alle spil
Hvert spil registrerer nøgle, navn, tagline, min/max spillere, ca. minutter,
trin, SVG-ikon, sine egne skærme (JS), sine indstillinger og en funktion, der
laver rummet. Views, consumers, host.js og play.js slår op i registret i
stedet for at spørge efter det enkelte spil:

- /host/new laver rummet via registret; indstillingerne renses mod spillets
  egne (ukendt spil giver 400).
- Rummets tilstand har altid "game" (= rummets kind), også Fup og Fakta's.
- Telefonens handlinger går til rummets play_action (Fup og Fakta's er flyttet
  fra consumeren til rummet, uændrede).
- host.js og play.js finder spillets skærme i window.WPPGameUI[nøgle];
  tegn.js melder sig der. Storskærmens navn, fanetitlen og pladsholderen før
  første tilstand kommer fra rummets spil, ikke fra et standardspil.
- Telefonens join-side viser rummets spil, når koden er kendt, og lobbyen
  siger "Vi spiller ...".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:29:27 +02:00
agwandClaude Opus 5.5 64aac361cd Værtsside: hvert spil er sin egen startknap
Fejl: spillet blev valgt med radioknapper, hvor Fup og Fakta var afkrydset
som standard. En TV-fjernbetjening flytter fokus uden at afkrydse, og
Enter/OK på en radio sender formularen med den afkrydsede radio, ikke den
fokuserede. Så "Tegn og Gæt" + OK gav game=fof og et Fup og Fakta-rum.

Nu er hvert spil en submit-knap med name="game", så den knap, man trykker
på, er det spil, der startes. Testen fejler på den gamle skabelon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 21:12:21 +02:00
agwandClaude Opus 5.5 7367b72505 Bots: vent op til 20 minutter på et helt spil
CI / test (push) Successful in 1m10s
Tegn og Gæt med 10 spillere tog 8 m 48 s, tæt på den gamle grænse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 19:46:49 +02:00
agwandClaude Opus 5.5 f9066bf6af Bots: navne nok til 10 spillere i Tegn og Gæt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 19:45:49 +02:00
agwandClaude Opus 5.5 53027a1ed9 Tegn og Gæt: ord, gæt og tal starter ikke en sætning i replikkerne
Tre replikker satte et indsat ord eller tal først i en sætning, så det
fik lille forbogstav på skærmen. Testen fanger det nu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 19:45:49 +02:00
agwandClaude Opus 5.5 26537f685a tts_warm: Tegn og Gæt under --budget og --reserve
Tegn og Gæts replikker står nu først i budget-køen i stedet for at blive
lavet før budget-tjekket, så forvarmningen ikke bruger af reserven.
Uden --budget laves ingen nye, og kommandoen siger det. Fup og Fakta's
faste replikker og budget-køens rækkefølge er som før.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 19:24:22 +02:00
agwandClaude Opus 5.5 45a146f548 tts_warm: forvarm også Tegn og Gæt (--only, --dry-run)
Tegn og Gæts faste replikker, reglerne, {tema}-replikkerne for alle
temaer og spillets start for 3-10 spillere laves først, med den
almindelige speaker; derefter Fup og Fakta som før. Teksterne kommer
fra samme Narrator-kode, som rummet bruger, så cache-nøglen er den
samme. --only fof|tegn vælger ét spil, og --dry-run tæller klip og
tegn uden at kalde ElevenLabs (også uden nøgle).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 19:19:38 +02:00
agwandClaude Opus 5.5 d885ecb9dc Tegn og Gæt: spillets start uden tal først i en sætning
"Så kører vi. tre kunstnere" fik lille forbogstav på skærmen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 19:19:37 +02:00
agwandClaude Opus 5.5 0ef58bdfce Bots: to blanke linjer før main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:13:32 +02:00
agwandClaude Opus 5.5 5a98917864 Bots: Tegn og Gæt-bots sover kun før en handling
Under afsløringen kom snapshots hurtigere, end en bot med en pause
efter hver besked kunne læse dem, og forbindelsen faldt (ping-timeout).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:01:31 +02:00
agwandClaude Opus 5.5 9b0f604a69 Tegn og Gæt: speakerens replikker i afsløringen kun til storskærmen
Replikken til kædens slutning nævner sidste gæt, så telefonerne får
planen uden audio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:01:31 +02:00
agwandClaude Opus 5.5 4071a78bb0 Tegn og Gæt: ingen tankestreg i tegn.js
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:46:42 +02:00
agwandClaude Opus 5.5 ef1acfbdac Docs: Tegn og Gæt i protokollen og README
Nye beskeder, snapshot-felter, tegningernes format og grænser,
afsløringens tidslinje, point og priser.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:34:15 +02:00
agwandClaude Opus 5.5 a3310c2325 Bots: --game tegn spiller et helt Tegn og Gæt
Bots tegner tilfældige streger, gætter tilfældige ord, bruger af og
til forslaget og giver hjerter under afsløringen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:33:07 +02:00
agwandClaude Opus 5.5 6c60d56409 Dev-harness: Tegn og Gæts skærme med ?game=tegn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:33:07 +02:00
agwandClaude Opus 5.5 d8c4836e65 Tegn og Gæt: tegning på telefonen og afsløring på storskærmen
tegn.js: lærred med touch, fire farver, to penselstørrelser, fortryd
og ryd; strøgene gemmes som vektorer og sendes som kladde undervejs.
Storskærmen viser temaer, trin og afsløringen kæde for kæde, hvor
tegningerne tegnes frem. host.js og play.js kalder hertil, når rummet
kører Tegn og Gæt; lobby, regler og podium deles med Fup og Fakta.
Speakerens replikker bruger ikke genitiv af navne (Sus' kæde).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:33:07 +02:00
agwandClaude Opus 5.5 d991279196 Tegn og Gæt: telefonerne ser kun det, storskærmen har vist
Under afsløringen får telefonerne kun de bidrag, der allerede er vist
(og om kæden overlevede, når slutningen er vist). Rummet sender et
nyt snapshot, hver gang et trin begynder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:11:58 +02:00
agwandClaude Opus 5.5 ab7ab1e8f1 Tegn og Gæt: rum, WebSocket og valg af spil
TegnRoom ved siden af Fup og Fakta-rummet; værten vælger spil på
/host/new (Fup og Fakta er standard). Storskærmen får tegningerne i
én besked pr. afsløring. WebSocket-test af et helt spil.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:05:22 +02:00
agwandClaude Opus 5.5 e2862d6200 Rum: fælles BaseRoom til timer, udsendelse og speaker
Det, der ikke handler om Fup og Fakta, flytter op i BaseRoom, så et
andet spil kan bruge det. Speakeren kan få sin egen lines.json.
Fup og Fakta opfører sig som før.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:05:22 +02:00