Skip to content

feat: add persistent live and daily turn timers - #90

Open
Enn3Developer wants to merge 4 commits into
n/account-game-membershipsfrom
n/turn-timers
Open

feat: add persistent live and daily turn timers#90
Enn3Developer wants to merge 4 commits into
n/account-game-membershipsfrom
n/turn-timers

Conversation

@Enn3Developer

Copy link
Copy Markdown
Owner

No description provided.

@Enn3Developer Enn3Developer added this to the 0.1.0 milestone Sep 5, 2026
@Enn3Developer Enn3Developer added type: feat New gameplay or feature work area: client OpenPolytopia/ Godot project area: server OpenPolytopia.Server/ dedicated server area: common OpenPolytopia.Common/ shared library area: netcode TCP transport, packet protocol, serialization area: gameplay Rules, tribes, troops, tech tree breaking-change Breaks save format, packet protocol, or public API labels Sep 5, 2026
@Enn3Developer Enn3Developer self-assigned this Sep 5, 2026
@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown

Claude finished @Enn3Developer's task in 36s —— View job


Summary

Adds persistent turn timers to the server: games run either a Live mode (per-player time banks that tick only on their turn) or a Daily mode (24-hour deadlines with manual skip/kick), surviving reconnects and server restarts via snapshot persistence.

Changes

  • Server: New TurnClock/TurnClockState (OpenPolytopia.Server/TurnClock.cs) tracks per-player banks, timeouts, elimination, and daily deadlines using injected now timestamps (no wall-clock reads, fully testable).
  • Server: GameServer.Timers.cs wires clock polling into the request pipeline — expired live turns are auto-skipped/eliminated before each action (ProcessTimers), turn changes from any source resync the clock (SynchronizeClocks), and a new ResolveOverdueTurnPacket handler lets another player skip or kick an overdue daily turn.
  • Server: GameServer.Persistence.cs bumps snapshot schema to version 2, persisting TurnClockState per session; legacy (v1) saves are migrated to a fresh Daily clock with a full 24h grace period.
  • Common: Gameplay action packets (MoveTroop, Attack, TrainTroop, ResearchTech, Build, Capture, EndTurn) gain an ExpectedTurn field so stale/delayed requests are rejected after an automatic skip; new GameActionResult.InvalidParameters.
  • Client: Lobby.cs renders the countdown, adds "Skip overdue turn"/"Kick overdue player" buttons (kick has a confirmation dialog) gated on daily mode and turn ownership.
  • Tests: New TurnClockTest, GameServerTimerIntegrationTest, and TimerMigrationTest cover clock bookkeeping, end-to-end timer flows, and legacy-save migration.

Worth a look

  • PacketRegistrar.cs moves _registered = true to after all packets are registered — fixes a potential race, but worth confirming intent since it's unrelated to the timer feature itself.
  • Snapshot version bump (1→2) is a breaking change to save-file format; migration path for missing timer mode defaults to Daily with a fresh 24h window — confirm this default is acceptable for in-flight Live games upgraded from v1.
  • ExpectedTurn semantics differ by mode (must match exactly in Live; 0 is accepted as "no guard" in Daily) — worth double-checking client call sites always populate it correctly for Live games.

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: client OpenPolytopia/ Godot project area: common OpenPolytopia.Common/ shared library area: gameplay Rules, tribes, troops, tech tree area: netcode TCP transport, packet protocol, serialization area: server OpenPolytopia.Server/ dedicated server breaking-change Breaks save format, packet protocol, or public API type: feat New gameplay or feature work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant