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>
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>
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>
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>
- 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>
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>
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>
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>
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>
?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>
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>
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>
/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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Efter at værten sprang en kæde over, stod storskærmen stille til den
oprindelige deadline. Færre end 3 spillere tilbage, når kæderne skal
starte, sender rummet tilbage til lobbyen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ny app tegnoggaet med en ren motor i samme stil som Fup og Fakta:
kæder der går bordet rundt (ord, tegn, gæt ...), timere, kladder ved
timeout, validering af tegninger som vektorstrøg, afsløringens plan,
hjerter, point og priser. Temaer i data/themes.json og speakerens
replikker i narrator/lines.json, med tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
113 af de 232 gamle spørgsmål var velkendte fun facts eller kunne regnes
ud af sætningen. De er erstattet af webverificerede, mere nichede fakta i
samme kategori, så ikke alle kender svaret på forhånd.
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
63 nye, webverificerede spørgsmål med vægt på det, de færreste kender:
"Danmarks historie" (22, bronzealder til 1928), "Politisk historie"
(21, dansk politik fra 1849) og 20 nye i "Historie" (verdenshistorie
uden for de vante fortællinger). Begge nye kategorier har deres egen
intro-lyd, normaliseret til -20 LUFS som de andre.
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
Fest-spillet hedder nu Fest-Z (kategorierne "Fest-Z: …"), og telefonerne
får zoomer-emojis (💀😭🧢🗿💅🍻) i stedet for familie-sættet. Serveren
sender sættet i tilstanden, så klienten altid viser det, spillet tager imod.
Reglerne og speakeren taler om slang og memes frem for pop-sladder.
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
Fest-pakken handler nu om ungdomskultur: "Fest: slang" (årets ord, slangens
oprindelse, dansk ungdomssprog) og "Fest: internettet" (memes, creators, spil),
ved siden af "Fest: nu". "Fest: retro" er taget ud.
Hjernen får sin egen fest-instruks (zoomer-speaker, tår må nævnes), så
afsløringens replikker og kommentarer også taler zoomer. Telefonens
drillerier har en fest-pulje, og de sidste faste replikker har fået
fest-udgaver.
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
Ny spørgsmålspakke "fest" (aldrig med i "Alle"): 43 faktatjekkede
spørgsmål om dansk pop i to kategorier, Fest: retro og Fest: nu.
Et fest-spil tæller tår ved siden af point: narret giver en tår,
ingen fandt sandheden giver alle en tår, gange rundens faktor
(finalen er en shot). Afsløringen, opsummeringen, stillingen og
telefonen viser tårene, og der er en pris til aftenens tørstigste.
Speakeren bruger zoomer-replikker (<begivenhed>_fest), egne regler
og FEST_VOICE_ID til alt.
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
- Alle 232 spørgsmål har en kort, overbevisende kommentar til sandheden og
hver af husets løgne (1.015 i alt, ens tone og lige mange lyd-tags), så
lyden kan ligge i cachen; hjernen spørges kun om spillernes egne løgne.
Mangler blot én kommentar, bruges skabelonerne til alle svar, så stilen
aldrig røber, hvem der har skrevet hvad
- Bemærkninger, når en løgn afleveres, er nu faste replikker med navnet
(også uden hjerne); hjernens udgave er et tilvalg (BRAIN_PROGRESS)
- Telefonens drillerier bruger en fast pulje på 28 (BRAIN_TEASES slår
hjernens til)
- Flere varianter til opsummering, oplæsning, velkomst og spil igen
- Én fælles liste over tilladte lyd-tags
- Lukkede forbindelser logges ikke længere som fejl
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
- Hjernen må bruge en fast liste af lyd-tags ([laughs], [whispers] …); andre
[ord] fjernes, så de ikke læses op
- Tags vises aldrig på skærme og telefoner
- Oplæsningen siger ikke længere svaret to gange, når hjernen gentager det
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
- 87 nye spørgsmål med kilder: Star Wars (inkl. Legends), Harry Potter,
Ringenes Herre, Lægevidenskab, E-faktura, IT-sikkerhed, Computerhistorie
- Spørgsmålspakker pr. kategori (familie, nørd, arbejde); værten vælger
Alle/Familie/Nørd, og arbejdspakken kun under "Flere valg"
- Lydeffekter i flere udgaver, der vælges tilfældigt (aldrig samme to gange
i træk); jingles og tænkemusik til de nye kategorier; ekstra tænke- og
afsløringsmusik
- Musik hentes og afkodes først, når den skal spilles, og slippes igen
- tts_warm --budget: forvarmer spørgsmål, forklaringer og kategori-replikker
(de næste spørgsmål først) inden for et tegnbudget
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
- Runde 2 og finalen: speakeren læser svarene op ét ad gangen (med hjernen
en overbevisende kommentar pr. svar), i samme takt på storskærm og telefoner
- Emoji-reaktioner fra telefonerne, der må spammes; de flyver op på storskærmen
og tælles på svaret i fokus
- Opsummeringen følger speakeren: "lad os rydde op", eksplosioner, så pointene
- Speakeren kommenterer, hvordan løgnene skrider frem, uden at røbe indhold,
og driller dem, der falder for svage løgne
- Reglerne forklares med kort og stemme før rummets første spil
- "Lyv for mig" låser forslaget i feltet (halve point), og feltet bliver ikke
længere kæmpestort
- Svar vises med versaler, og spillernes løgne gemmes med små bogstaver, så
store forbogstaver ikke afslører dem
- Løgne og navne renses: kun bogstaver, tal og lidt tegnsætning
- Valgfrit workspace-id til Anthropic-brugernøgler
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
Fejl fra første rigtige spil: alle kendte svaret og sendte det igen og
igen. Hver gang kom en ny replik i kø, og da skærmen venter på speakeren,
kom spillet aldrig videre. Nu kommenteres det højst én gang pr. spørgsmål
som en sidebemærkning, der ikke holder skærmen tilbage, og når tiden er
gået, venter skærmen højst tolv sekunder på speakeren.
Stemmen er mere levende (lavere stability, mere style), de hyppigste
begivenheder har fået flere replikker, og spørgsmål som alle finder to
gange, tages ud. Spillet vælger nu de mindst brugte spørgsmål først.
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
Lydfilerne var op til 17 dB højere end speakeren (kategori-lyden -4 LUFS
mod speakerens -21). Alle effekter er nu normaliseret til -20 LUFS og
musikken til -23 LUFS. Speakeren går gennem sin egen kompressor med et
løft, og mens den taler, dykker effekterne og musikken, og musikken får
skåret taleområdet ned. En limiter til sidst forhindrer klipning.
Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu