From 16be9d7c15d7abc115691def3a0b2aa559664705 Mon Sep 17 00:00:00 2001
From: Zixer1 <99333209+Zixer1@users.noreply.github.com>
Date: Wed, 15 Jul 2026 20:20:53 -0400
Subject: [PATCH] feat(lobby): surface Doomsday Clock preset + anonymous names
as lobby settings (#4616)
## Description:
Public rotation lobbies can run the **Doomsday Clock** at one of four
presets (slow/normal/fast/veryfast), and lobbies can **anonymize player
names**, but the lobby UI surfaced neither: the Doomsday Clock badge was
generic and there were no settings cards for either. Players couldn't
tell what a lobby was actually set to.
This surfaces both as regular lobby settings, matching how the other
modifiers already display:
- **Settings cards** (join/waiting view): adds a "Doomsday Clock" card
showing the active preset name, and an "Anonymous Players" card,
alongside the existing modifier cards.
- **Lobby badge** (home lobby list): the Doomsday Clock badge now reads
"Doomsday Clock: Fast" instead of the generic label. Falls back to the
plain label when no speed is present (older payloads / non-rotation
lobbies).
Client-only. Both `doomsdayClock.speed` and `anonymizeNames` already
ship in the public `GameConfig`, so no server or schema changes are
needed.
## Please complete the following:
- [] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
## Please put your Discord username so you can be contacted if a bug or
regression is found:
zixer._
---
resources/lang/en.json | 1 +
src/client/GameModeSelector.ts | 1 +
src/client/JoinLobbyModal.ts | 16 ++++++++++++++++
src/client/Utils.ts | 18 +++++++++++++++---
tests/client/DoomsdayModifierBadge.test.ts | 11 +++++++++++
5 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/resources/lang/en.json b/resources/lang/en.json
index 78d5abd23..4047dda79 100644
--- a/resources/lang/en.json
+++ b/resources/lang/en.json
@@ -1149,6 +1149,7 @@
"disable_alliances_label": "Alliances",
"doomsday_clock": "Doomsday Clock",
"doomsday_clock_label": "Doomsday Clock",
+ "doomsday_clock_with_speed": "Doomsday Clock: {speed}",
"gold_multiplier": "x{amount} Gold Multiplier",
"hard_nations": "Hard Nations",
"nukes_disabled": "Nukes Disabled",
diff --git a/src/client/GameModeSelector.ts b/src/client/GameModeSelector.ts
index 66dca4536..80267077e 100644
--- a/src/client/GameModeSelector.ts
+++ b/src/client/GameModeSelector.ts
@@ -314,6 +314,7 @@ export class GameModeSelector extends LitElement {
const modifierLabels = getModifierLabels(
lobby.gameConfig?.publicGameModifiers,
+ lobby.gameConfig?.doomsdayClock?.speed,
);
// Sort by length for visual consistency (shorter labels first)
if (modifierLabels.length > 1) {
diff --git a/src/client/JoinLobbyModal.ts b/src/client/JoinLobbyModal.ts
index 1e2533aa0..27b25961d 100644
--- a/src/client/JoinLobbyModal.ts
+++ b/src/client/JoinLobbyModal.ts
@@ -530,6 +530,22 @@ export class JoinLobbyModal extends BaseModal {
.value=${translateText("common.enabled")}
>`,
);
+ if (c.doomsdayClock?.enabled)
+ cards.push(
+ html``,
+ );
+ if (c.anonymizeNames)
+ cards.push(
+ html``,
+ );
if ((isTeam && !c.donateGold) || (!isTeam && c.donateGold))
cards.push(
html`
+ return getActiveModifiers(modifiers, doomsdayClockSpeed).map((m) =>
translateText(m.badgeKey, m.badgeParams),
);
}
diff --git a/tests/client/DoomsdayModifierBadge.test.ts b/tests/client/DoomsdayModifierBadge.test.ts
index 1a1057e8f..34023b85d 100644
--- a/tests/client/DoomsdayModifierBadge.test.ts
+++ b/tests/client/DoomsdayModifierBadge.test.ts
@@ -12,6 +12,17 @@ describe("doomsday clock public modifier", () => {
expect(mods[0].labelKey).toBe("public_game_modifier.doomsday_clock_label");
});
+ it("names the preset when a speed is provided", () => {
+ const mods = getActiveModifiers({ isDoomsdayClock: true }, "fast");
+ expect(mods).toHaveLength(1);
+ expect(mods[0].badgeKey).toBe(
+ "public_game_modifier.doomsday_clock_with_speed",
+ );
+ expect(mods[0].labelKey).toBe("public_game_modifier.doomsday_clock_label");
+ // The speed is resolved to its translated label and passed as a badge param.
+ expect(mods[0].badgeParams?.speed).toBeDefined();
+ });
+
it("omits the badge when the modifier is absent", () => {
expect(getActiveModifiers({})).toHaveLength(0);
expect(getActiveModifiers(undefined)).toHaveLength(0);