- 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
This commit is contained in:
+28
-5
@@ -32,6 +32,7 @@ Alle beskeder er JSON `{"action": "...", ...}`.
|
||||
| `lie_for_me` | | fase `lie`; svar: `suggestion` |
|
||||
| `guess` | `answer_id` | fase `guess`; spillere og publikum, én gang |
|
||||
| `like` | `answer_id` | kun fase `reveal`; slår til/fra; ikke eget svar og ikke sandheden (`answer_invalid`) |
|
||||
| `react` | `emoji` (en af `😂 😱 👏 🤯 🙈 🔥`) | fase `present`, `guess`, `reveal`; må spammes (serveren dropper stille over 6/s pr. person). Intet svar; storskærmen får `react`. Tælles på det svar, der er i fokus på storskærmen. |
|
||||
| `play_again` | | VIP i fasen `final` |
|
||||
| `ping` | | svar `pong` |
|
||||
|
||||
@@ -45,6 +46,7 @@ Alle beskeder er JSON `{"action": "...", ...}`.
|
||||
| `joined` | `token`, `player_id`, `role` (`player`/`audience`) |
|
||||
| `suggestion` | `text` (svar på `lie_for_me`) |
|
||||
| `tease` | `text`, `image` (URL), `sound` (URL eller `null`) – kun til den spiller, der lige faldt for en løgn, i det øjeblik stemplet "LØGN" lander på storskærmen. Telefonen viser et fuldskærms-drilleri (~2,5 s, lukkes ved tryk), spiller `boo` og derefter `sound`, hvis lyden er låst op. Højst 2 pr. spørgsmål. |
|
||||
| `react` | `emoji`, `color` (afsenderens farve), `answer_id` (svaret i fokus eller `null`) – kun til storskærmen; emojien flyver op over skærmen. |
|
||||
| `error` | `code`, `message` (dansk, kan vises direkte) |
|
||||
| `pong` | |
|
||||
|
||||
@@ -55,7 +57,7 @@ Fejlkoder: `unknown_room`, `unknown_token`, `name_taken`, `name_invalid`, `not_a
|
||||
```jsonc
|
||||
{
|
||||
"code": "KLMT",
|
||||
"phase": "lobby", // lobby | category | intro | lie | guess | reveal | scores | final
|
||||
"phase": "lobby", // lobby | category | intro | lie | present | guess | reveal | scores | final
|
||||
"server_time": 1790000000000,// ms epoch; klienten udregner sin forskydning
|
||||
"deadline": 1790000060000, // ms epoch eller null
|
||||
"join_url": "https://party.weircon.dk/?code=KLMT",
|
||||
@@ -71,8 +73,15 @@ Fejlkoder: `unknown_room`, `unknown_token`, `name_taken`, `name_invalid`, `not_a
|
||||
"chosen_id": null}, // kun i fase category; id når der er valgt (ellers null)
|
||||
"intro": {"category": "Dyreriget", "slug": "dyreriget", "final": false}, // kun i fase intro
|
||||
"question": {"category": "Dyreriget", "prompt": "En flok _____ kaldes et parlament.",
|
||||
"slug": "dyreriget"}, // lie/guess/reveal
|
||||
"answers": [{"id": "a1", "text": "ugler"}], // guess + reveal (i reveal med "likes"); egen løgn udeladt i guess
|
||||
"slug": "dyreriget"}, // lie/present/guess/reveal
|
||||
"present": { // kun i fase present (runde 2 og finalen)
|
||||
"started_at": 1790000000000, // ms epoch; null = serveren laver stadig lyd
|
||||
"intro_ms": 1500, "steps_ms": [3100, 2900], // speakerens intro, så ét svar ad gangen
|
||||
"ids": ["a3", "a1"], // oplæsningens rækkefølge (steps_ms/audio følger den)
|
||||
"intro_audio": {"url": "…", "ms": 1200}, // eller null
|
||||
"audio": [{"url": "…", "ms": 2600, "text": "Krager. Det giver da mening…"}] // pr. svar eller null
|
||||
},
|
||||
"answers": [{"id": "a1", "text": "ugler"}], // present + guess + reveal (i reveal med "likes"); egen løgn udeladt i present/guess
|
||||
"reveal": { // kun i fase reveal
|
||||
"steps": [ // løgne først (kun dem der blev valgt), sandheden sidst
|
||||
{"answer_id": "a3", "text": "krager", "is_truth": false, "house": false,
|
||||
@@ -86,8 +95,13 @@ Fejlkoder: `unknown_room`, `unknown_token`, `name_taken`, `name_invalid`, `not_a
|
||||
],
|
||||
"all": [ // opsummeringen: ALLE svar, også dem ingen valgte
|
||||
{"id": "a7", "text": "skildpadder", "is_truth": false, "house": true,
|
||||
"authors": [], "assisted": [], "picked": false, "likes": 0} // picked=false → svaret "eksploderer"
|
||||
"authors": [], "assisted": [], "picked": false, "likes": 0, // picked=false → svaret "eksploderer"
|
||||
"reactions": 3} // emojis sendt, mens svaret var i fokus
|
||||
],
|
||||
"summary": { // opsummeringens tidsplan i ms fra halens start, eller null
|
||||
"start_ms": 1200, "explode_at": 3900, "points_at": 7200, // ikke-valgte eksploderer fra explode_at (250 ms imellem); point tælles fra points_at
|
||||
"audio": [{"url": "…", "ms": 2100, "at": 1600}] // speakerens "lad os rydde op" / "så til pointene", afspilles ved at
|
||||
},
|
||||
"deltas": [{"player_id": "p1", "delta": 1500}], // point i dette spørgsmål pr. spiller (inkl. hjerter)
|
||||
"step_ms": 4000, // standardlængde pr. trin (bagudkompatibel)
|
||||
"steps_ms": [4200, 3900], // faktisk længde pr. trin (følger speakerens replik)
|
||||
@@ -134,6 +148,15 @@ Trin `i` starter ved `started_at + sum(steps_ms[0..i-1])`. Inden for et trin vis
|
||||
(~28 % / højst 1,1 s), så stemplet (~55 % / højst 2,3 s). Efter sidste trin kører opsummeringen i `tail_ms`:
|
||||
alle svar (`all`), de ikke-valgte eksploderer, og `deltas` tælles op. `deadline` = slutningen af halen.
|
||||
Mens `started_at` er `null`, venter serveren på speakerens lydfiler (højst ~10 s) og sætter så tiderne.
|
||||
Opsummeringen følger `summary`: speakeren siger noget i stil med "dem her troede ingen på, lad os rydde op",
|
||||
så eksploderer de ikke-valgte svar, så "og så til pointene", og først derefter tælles pointene op.
|
||||
|
||||
### Oplæsningens tidslinje (fasen `present`)
|
||||
|
||||
I runde 2 og finalen læser speakeren svarene op, før der gættes: først `intro_ms`, så svar `i` fra
|
||||
`started_at + intro_ms + sum(steps_ms[0..i-1])`. Hvert svar præsenteres overbevisende (med hjernen en
|
||||
kommentar pr. svar, som aldrig må afsløre, hvad der er sandt). Storskærm og telefoner viser svarene i samme takt;
|
||||
der kan først gættes i `guess`. `deadline` = slutningen + 1 s.
|
||||
|
||||
### Lyd- og billedfiler
|
||||
|
||||
@@ -152,7 +175,7 @@ klienten slår alle lyde op her og falder tilbage til `/static/party/sfx/<navn>.
|
||||
|
||||
For hvert spørgsmål: `category` (15 s; skiftende spiller vælger blandt 4; i finalen springes fasen over) → `intro` (≈5 s; storskærmen præsenterer kategorien med sin jingle, speakeren siger kategorien, og serveren venter til speakeren er færdig) → `lie` (60 s, speakeren læser spørgsmålet op; slutter når alle har løjet) → `guess` (30 s, slutter når alle spillere har gættet) → `reveal` (automatisk: `sum(steps_ms)` + `tail_ms`; værten kan `skip`). Efter sidste spørgsmål i en runde: `scores` (10 s). Efter finalen: `final`.
|
||||
|
||||
Rækkefølge: `category → intro → lie → guess → reveal (→ scores)`; i finalen `intro → lie → guess → reveal → final`.
|
||||
Rækkefølge: `category → intro → lie → guess → reveal (→ scores)`; i runde 2 `category → intro → lie → present → guess → reveal (→ scores)`; i finalen `intro → lie → present → guess → reveal → final`.
|
||||
|
||||
- Løgn lig sandheden (eller næsten lig) afvises med `lie_is_truth`. Ens løgne slås sammen, og alle forfattere får point.
|
||||
- Spillere, der ikke løj i tide, får ingen løgn; huset fylder op med lokkesvar, så der er mindst `max(4, spillere+1)` svar.
|
||||
|
||||
Reference in New Issue
Block a user