diff --git a/deploy/bots.py b/deploy/bots.py
index 9b72c18..bf3c3fa 100644
--- a/deploy/bots.py
+++ b/deploy/bots.py
@@ -103,7 +103,7 @@ async def _player(ws_base, code, name, n_players, done, rng, stop_at_final):
await asyncio.sleep(rng.uniform(0.05, 0.4))
if st["phase"] in ("present", "guess", "reveal") and rng.random() < 0.25:
for _ in range(rng.randint(1, 8)): # emojis må spammes; serveren drosler
- await ws.send(json.dumps({"action": "react", "emoji": rng.choice(["😂", "😱", "👏", "🤯", "🙈", "🔥"])}))
+ await ws.send(json.dumps({"action": "react", "emoji": rng.choice(st.get("reactions") or ["😂", "😱", "👏", "🤯", "🙈", "🔥"])}))
if st["phase"] == "lobby" and me["vip"] and len(st["players"]) >= n_players and key not in acted:
acted.add(key)
await ws.send(json.dumps({"action": "start"}))
diff --git a/docs/PROTOCOL.md b/docs/PROTOCOL.md
index 71c2fe8..e7f9eb1 100644
--- a/docs/PROTOCOL.md
+++ b/docs/PROTOCOL.md
@@ -32,7 +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. |
+| `react` | `emoji` (en af tilstandens `reactions`: `😂 😱 👏 🤯 🙈 🔥`, i fest-spil `💀 😭 🧢 🗿 💅 🍻`) | 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` |
@@ -185,7 +185,7 @@ Rækkefølge: `category → intro → lie → guess → reveal (→ scores)`; i
- Publikum: forfatteren får `round(500 × multiplikator × andel af publikum narret)`.
- Spil igen: samme spillere, point nulstilles.
-## Fest-spil (pakken "fest", 18+)
+## Fest-Z (pakken "fest", 18+)
Oprettes med `pack=fest` på `/host/new`. Snapshot har altid `fest` (bool). I et fest-spil desuden:
diff --git a/fupogfakta/data/questions_d_fest.json b/fupogfakta/data/questions_d_fest.json
index cde6b59..7fca772 100644
--- a/fupogfakta/data/questions_d_fest.json
+++ b/fupogfakta/data/questions_d_fest.json
@@ -1,6 +1,6 @@
[
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -26,7 +26,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -52,7 +52,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -79,7 +79,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -107,7 +107,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -135,7 +135,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -161,7 +161,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -187,7 +187,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -213,7 +213,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -240,7 +240,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -268,7 +268,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -295,7 +295,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -321,7 +321,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -348,7 +348,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -374,7 +374,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -400,7 +400,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -427,7 +427,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -453,7 +453,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -480,7 +480,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -507,7 +507,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -534,7 +534,7 @@
}
},
{
- "category": "Fest: nu",
+ "category": "Fest-Z: nu",
"packs": [
"fest"
],
@@ -561,7 +561,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -590,7 +590,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -618,7 +618,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -646,7 +646,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -673,7 +673,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -700,7 +700,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -726,7 +726,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -754,7 +754,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -781,7 +781,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -809,7 +809,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -837,7 +837,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -863,7 +863,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -889,7 +889,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -918,7 +918,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -947,7 +947,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -975,7 +975,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -1004,7 +1004,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -1033,7 +1033,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -1061,7 +1061,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -1088,7 +1088,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -1116,7 +1116,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -1144,7 +1144,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -1171,7 +1171,7 @@
}
},
{
- "category": "Fest: slang",
+ "category": "Fest-Z: slang",
"packs": [
"fest"
],
@@ -1198,7 +1198,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1225,7 +1225,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1253,7 +1253,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1282,7 +1282,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1311,7 +1311,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1338,7 +1338,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1368,7 +1368,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1397,7 +1397,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1424,7 +1424,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1452,7 +1452,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1481,7 +1481,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1511,7 +1511,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1539,7 +1539,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1567,7 +1567,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1596,7 +1596,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1625,7 +1625,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1654,7 +1654,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1683,7 +1683,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1711,7 +1711,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1738,7 +1738,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1766,7 +1766,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
@@ -1795,7 +1795,7 @@
}
},
{
- "category": "Fest: internettet",
+ "category": "Fest-Z: internettet",
"packs": [
"fest"
],
diff --git a/fupogfakta/engine.py b/fupogfakta/engine.py
index e2c2e60..c9055d5 100644
--- a/fupogfakta/engine.py
+++ b/fupogfakta/engine.py
@@ -34,6 +34,7 @@ REVEAL_STEP_MS = 4000
PRESENT_STEP_MS = 2600 # pr. svar under oplæsningen, når der ikke er stemme
PRESENT_INTRO_MS = 1500
REACTIONS = ("😂", "😱", "👏", "🤯", "🙈", "🔥")
+REACTIONS_FEST = ("💀", "😭", "🧢", "🗿", "💅", "🍻") # fest: dødt af grin, cap, moai-blik, slay, skål
REACT_PER_SECOND = 6 # man må gerne spamme, men ikke uendeligt
REVEAL_TAIL_MS = 8000 # opsummeringen efter sidste trin: løgne der eksploderer, point der tæller op
@@ -69,15 +70,15 @@ RULES_STEP_MS = 5000
# Fest (18+): samme spil, men det handler om tår. Narret = drik; ingen fandt sandheden = alle drikker.
# Antal tårer følger rundens gange (×1/×2/×3), og finalen kaldes en shot.
RULES_FEST = [
- {"icon": "🤥", "title": "Lyv som en influencer", "body": "Et sandt faktum om dansk pop mangler et ord. Skriv en løgn, der lyder sand.",
- "say": "Yo, bestie, velkommen til festen. I får noget ægte dansk pop-sladder, men der mangler et ord. "
+ {"icon": "🤥", "title": "Lyv som en influencer", "body": "Et sandt faktum om slang, memes eller dansk pop mangler et ord. Skriv en løgn, der lyder sand.",
+ "say": "Yo, bestie, velkommen til festen. I får ægte facts om slang, memes og dansk pop, men der mangler et ord. "
"Jeres job? At lyve så hårdt, at de andre hopper lige i det. Ingen cap."},
{"icon": "🥃", "title": "Narret? Drik!", "body": "Falder du for en løgn, tager du en tår. Point er sekundært.",
"say": "Og nu kommer det vigtige. Falder du for en løgn, så tager du en tår. Det er hele pointen. Point er lowkey ligegyldige."},
{"icon": "🍻", "title": "Ingen fandt sandheden?", "body": "Så drikker alle. Sådan er reglerne.",
"say": "Finder ingen af jer sandheden, så drikker alle sammen. Det er bare sådan, det er."},
- {"icon": "🔥", "title": "Det eskalerer", "body": "Runde 2 er to tårer. Finalen er en shot.",
- "say": "Runde to er to tårer, og finalen er en hel shot. Drik med omtanke, og drik vand imellem. Lad os gå!"},
+ {"icon": "🔥", "title": "Det eskalerer", "body": "Runde 2 er to tår. Finalen er en shot.",
+ "say": "Runde to er to tår, og finalen er en hel shot. Drik med omtanke, og drik vand imellem. Lad os gå!"},
]
@@ -344,6 +345,10 @@ class Game:
return
self._begin_question(now)
+ @property
+ def reaction_set(self) -> tuple[str, ...]:
+ return REACTIONS_FEST if self.fest else REACTIONS
+
@property
def rules(self) -> list[dict]:
return RULES_FEST if self.fest else RULES
@@ -607,7 +612,7 @@ class Game:
def react(self, member_id: str, emoji: str, now: float) -> dict | None:
"""En emoji fra en telefon. Returnerer reaktionen (til storskærmen) eller None, hvis den droppes."""
- if self.phase not in ("present", "guess", "reveal") or emoji not in REACTIONS:
+ if self.phase not in ("present", "guess", "reveal") or emoji not in self.reaction_set:
return None
member = self._member(member_id)
if not member:
@@ -876,6 +881,7 @@ class Game:
],
"audience_count": len(self.audience),
"fest": self.fest,
+ "reactions": list(self.reaction_set),
}
if self.phase not in ("lobby", "final"):
name, mult, count, _read = self.round
diff --git a/fupogfakta/narrator/lines.json b/fupogfakta/narrator/lines.json
index 5e73650..6c33009 100644
--- a/fupogfakta/narrator/lines.json
+++ b/fupogfakta/narrator/lines.json
@@ -482,7 +482,7 @@
"[sighs] {vip}, festen venter på dig. Start nu, bestie."
],
"game_start_fest": [
- "{antal_spillere} spillere, en masse sladder og alt for mange tår. Lad os gå!",
+ "{antal_spillere} spillere, en masse brainrot og alt for mange tår. Lad os gå!",
"[excited] {antal_spillere} spillere er klar. Det her bliver ikke familievenligt. Okay, lidt alligevel."
],
"round1_intro_fest": [
@@ -508,7 +508,7 @@
"lie_start_fest": [
"{kategori}. Skriv en løgn så god, at Se og Hør ville trykke den.",
"Nu er det {kategori}. Lyv som en influencer med en rabatkode.",
- "{kategori}, bestie. Find på noget, der lyder som ægte sladder."
+ "{kategori}, bestie. Find på noget, der lyder ægte, no cap."
],
"lie_hurry_fest": [
"Tiden løber, besties. Skriv noget, hvad som helst!",
@@ -587,7 +587,7 @@
"Igen igen! Fyld op, besties."
],
"present_intro_fest": [
- "Okay, her er svarene. Lyt godt efter, én af dem er ægte sladder.",
+ "Okay, her er svarene. Lyt godt efter, én af dem er den ægte vare.",
"Jeg læser dem op. Den der lyder mest unhinged er måske sandheden."
],
"summary_cleanup_fest": [
diff --git a/fupogfakta/tests/test_engine.py b/fupogfakta/tests/test_engine.py
index a441d37..2c4e66b 100644
--- a/fupogfakta/tests/test_engine.py
+++ b/fupogfakta/tests/test_engine.py
@@ -361,3 +361,13 @@ class FestTests(GameTestCase):
normal = Game("N", bank())
self.assertIs(normal.rules, engine.RULES)
self.assertFalse(normal.snapshot(self.now)["fest"])
+
+ def test_fest_has_its_own_emojis(self):
+ for p, lie in [(self.a, "katte"), (self.b, "hunde"), (self.c, "heste")]:
+ self.g.submit_lie(p.id, lie, self.now)
+ self.assertEqual(self.g.phase, "guess")
+ self.assertEqual(self.g.snapshot(self.now)["reactions"], list(engine.REACTIONS_FEST))
+ self.assertIsNotNone(self.g.react(self.a.id, "💀", self.now))
+ self.assertIsNone(self.g.react(self.a.id, "😂", self.now + 2)) # familie-sættet gælder ikke her
+ normal = Game("N", bank())
+ self.assertEqual(normal.snapshot(self.now)["reactions"], list(engine.REACTIONS))
diff --git a/party/brain/game.py b/party/brain/game.py
index 1339871..5b80278 100644
--- a/party/brain/game.py
+++ b/party/brain/game.py
@@ -37,7 +37,7 @@ Regler for alt, du skriver:
- Brug gerne aftenens hukommelse til en pointe, der bygger videre på noget, der er sket tidligere."""
# Fest-spillet (18+): samme spil, men speakeren er en hypet zoomer, og det handler om tår frem for point.
-SYSTEM_FEST = """Du er speakeren i "Fup og Fakta: Fest", et dansk partyspil for unge voksne (18+) i stil med Fibbage.
+SYSTEM_FEST = """Du er speakeren i "Fup og Fakta: Fest-Z", et dansk zoomer-partyspil for unge voksne (18+) i stil med Fibbage.
Spillet: et kuriøst, sandt faktum vises med et hul. Alle skriver en troværdig løgn. Løgnene blandes med
sandheden, og man skal gætte sandheden. Falder man for en løgn, tager man en tår (to i runde to, en shot i
finalen). Finder ingen sandheden, drikker alle. Tårene betyder mere end pointene.
diff --git a/party/static/party/common.js b/party/static/party/common.js
index c6a1557..014c105 100644
--- a/party/static/party/common.js
+++ b/party/static/party/common.js
@@ -341,7 +341,9 @@
try { return String(s || '').normalize('NFKC').replace(re, ''); } catch (e) { return String(s || ''); }
};
/* emojis, telefonerne kan spamme under oplæsning, gæt og afsløring (samme liste som serveren) */
- WPP.REACTIONS = ['😂', '😱', '👏', '🤯', '🙈', '🔥'];
+ WPP.REACTIONS_BASE = WPP.REACTIONS = ['😂', '😱', '👏', '🤯', '🙈', '🔥'];
+ /* fest-spil har sit eget sæt; serveren sender listen i tilstanden */
+ WPP.useReactions = function (state) { WPP.REACTIONS = (state && state.reactions) || WPP.REACTIONS_BASE; };
WPP.reducedMotion = function () {
try { return window.matchMedia('(prefers-reduced-motion: reduce)').matches; } catch (e) { return false; }
};
diff --git a/party/static/party/dev-fixtures.js b/party/static/party/dev-fixtures.js
index 0a1a48a..366853c 100644
--- a/party/static/party/dev-fixtures.js
+++ b/party/static/party/dev-fixtures.js
@@ -271,6 +271,7 @@
var sips = { p1: 1, p2: 3, p3: 6, p4: 4, p5: 2, p6: 5 };
[host].concat(phones.map(function (ph) { return ph.state; })).forEach(function (st) {
st.fest = true;
+ st.reactions = ['💀', '😭', '🧢', '🗿', '💅', '🍻'];
(st.players || []).forEach(function (p) { p.sips = sips[p.id] || 0; });
if (st.reveal) {
st.reveal.steps.forEach(function (s) {
diff --git a/party/static/party/host.js b/party/static/party/host.js
index 0748da7..568d4ff 100644
--- a/party/static/party/host.js
+++ b/party/static/party/host.js
@@ -784,6 +784,7 @@
/* ---------- offentlig render ---------- */
function renderHost(root, state, ctx) {
+ WPP.useReactions(state);
ctx = ctx || {};
state = state || {};
var u = ui(root);
diff --git a/party/static/party/play.js b/party/static/party/play.js
index 965bff9..86e79be 100644
--- a/party/static/party/play.js
+++ b/party/static/party/play.js
@@ -373,6 +373,7 @@
/* ---------- offentlige render-funktioner ---------- */
function renderPlay(root, state, ctx) {
+ WPP.useReactions(state);
ctx = ctx || {};
root._ctx = ctx;
bind(root);
diff --git a/party/templates/party/host_new.html b/party/templates/party/host_new.html
index 6460407..7ec6c6c 100644
--- a/party/templates/party/host_new.html
+++ b/party/templates/party/host_new.html
@@ -14,8 +14,8 @@
Arbejdsspørgsmål: e-faktura, IT-sikkerhed og kategorier med pakken "arbejde".
- -Dansk pop-sladder med zoomer-speaker. Narret = tag en tår, finalen er en shot.
+ +Slang, memes og dansk pop med zoomer-speaker. Narret = tag en tår, finalen er en shot.