feat: improved debuff control and prepared games#15
Open
Conversation
There was a problem hiding this comment.
Pull request overview
Adds new admin UX and backend support for round preparation and debuff management (apply to all, clear active debuffs, and “infinite” duration handling), plus ensures debuffs are reset on puzzle switches.
Changes:
- Extend admin protocol with
launch_roundandclear_debuff, and implement corresponding backend handlers. - Add new admin panels: “Active Debuffs” (view/clear) and “Prepare Next Round” (select puzzle + initial debuffs).
- Update debuff UI to support “All players” targeting and an ∞ duration display/sentinel.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/player/DebuffSelector.tsx | Add “All players” option and encode ∞ duration via duration=0. |
| frontend/src/player/DebuffQueue.tsx | Display ∞ for long durations. |
| frontend/src/admin/SpectatorController.ts | Treat empty debuff lists as a clear signal for spectators. |
| frontend/src/admin/NextRoundPanel.tsx | New UI to select next puzzle and configure initial debuffs for round launch. |
| frontend/src/admin/adminState.ts | Add new admin command types and PreparedDebuff type. |
| frontend/src/admin/Admin.tsx | Integrate new admin panels into the dashboard layout. |
| frontend/src/admin/ActiveDebuffsPanel.tsx | New UI to view active debuffs per player and issue clear commands. |
| frontend/package-lock.json | Lockfile regeneration changes. |
| backend/main.py | Implement infinite-duration sentinel, clear-debuff command, launch-round command, spectator debuff broadcasting, and debuff resets on puzzle switch. |
Files not reviewed (1)
- frontend/package-lock.json: Language not supported
Comments suppressed due to low confidence (2)
frontend/src/player/DebuffQueue.tsx:12
formatDurationreturns "∞" for any debuff with > 1 hour remaining. Debuff durations can legitimately exceed an hour (e.g. repeated stacking inadminister_debuffaccumulates duration), so this will mislabel long-but-finite debuffs as infinite. Consider detecting infinity via a much higher threshold aligned with the server sentinel (e.g. ~1 year), or having the server explicitly mark infinite debuffs.
function formatDuration(ms: number): string {
if (ms > 3_600_000) return "∞";
const total = Math.max(0, Math.ceil(ms / 1000));
const m = Math.floor(total / 60);
const s = total % 60;
return `${m}:${s.toString().padStart(2, "0")}`;
backend/main.py:756
- Broadcasting
spectate_debuffsto all admins (even when they are not spectating a player) means controllers can accumulate incremental debuff updates. When an admin later starts spectating a player, the server also sends a full debuff snapshot (debuffs_json) for that player, and the client-sideupdateDebuffslogic merges rather than replaces—this can lead to duplicate debuff entries. To avoid this, consider clearing before sending snapshot debuffs (send an empty debuffs message first) or introducing a distinct "replace debuffs" message type for snapshots.
data = json.dumps(converted)
for admin in self.admins.values():
if converted["type"] in ("spectate_state", "spectate_debuffs") or admin.is_spectating(player_name):
try:
# TODO: use queue tasks like with players
asyncio.create_task(admin.ws.send(data, True))
except Exception:
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
49
to
55
| type: "administer_debuff", | ||
| players: [selectedPlayer], | ||
| players: selectedPlayer === "*" ? (players ?? []) : [selectedPlayer], | ||
| name: selectedName, | ||
| debuff_type: info.type, | ||
| strength, | ||
| duration, | ||
| duration: duration === 120 ? 0 : duration, | ||
| }); |
Comment on lines
+1003
to
+1014
| elif msg["type"] == "administer_debuff": | ||
| if error := manager.administer_debuff(msg): | ||
| await send(ws, error) | ||
| elif msg["type"] == "clear_debuff": | ||
| player_names = msg.get("players") | ||
| name = msg.get("name") | ||
| targets = list(manager.players.keys()) if player_names == "all" else player_names | ||
| for player_name in targets: | ||
| manager.clear_debuff(player_name, name) | ||
| elif msg["type"] == "launch_round": | ||
| puzzle_id = msg["puzzle"] | ||
| initial_debuffs = msg.get("initial_debuffs", []) |
Comment on lines
+1020
to
+1021
| debuff_cmd["players"] = list(manager.players.keys()) | ||
| manager.administer_debuff(debuff_cmd) |
also adds UI functionality for the prepared game's debuff pool. currently does nothing as minigames have not been implemented
a5aacee to
cbab814
Compare
Extract `name` from JWT for the welcome message display while keeping `sub` (telegram ID) as the stable player identifier. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
clear_debuffcommand andlaunch_roundcommand addedfixes #13, fixes #14