Skip to content

Stagger scoreboard sends to prevent buffer overflows on full servers - #313

Merged
darkshade9 merged 2 commits into
aqtion-alphafrom
full_scoreboard
May 24, 2026
Merged

Stagger scoreboard sends to prevent buffer overflows on full servers#313
darkshade9 merged 2 commits into
aqtion-alphafrom
full_scoreboard

Conversation

@darkshade9

Copy link
Copy Markdown

Scoreboard layout messages are now spread across multiple server frames instead of being sent to all clients simultaneously. This prevents packet buffer overflows that could crash the server or disconnect legacy clients with small reliable message limits (~1400 bytes).

  • Periodic scoreboard updates (every 3 seconds) are staggered per-client across the full cycle, so a 32-player server sends ~1 per frame instead of 32 at once. teams_changed still forces immediate update.
  • Intermission scoreboard sends are spread across 4 frames (~0.4s) instead of bursting all clients in a single frame.
  • On-demand score key (TAB) switched from reliable to unreliable send, since the periodic refresh catches any dropped packets within 3 seconds.
  • MAX_SCOREBOARD_SIZE raised from 1024 to 1300 bytes and MAX_PLAYERS_PER_TEAM raised from 8 to 10, using the headroom from reduced burst pressure while staying within legacy packet limits.
  • Document scoreboard delivery changes and the configurable scoreboard field codes (previously undocumented) in action.md.

darkshade9 and others added 2 commits March 24, 2026 15:32
Scoreboard layout messages are now spread across multiple server frames
instead of being sent to all clients simultaneously. This prevents
packet buffer overflows that could crash the server or disconnect
legacy clients with small reliable message limits (~1400 bytes).

- Periodic scoreboard updates (every 3 seconds) are staggered per-client
  across the full cycle, so a 32-player server sends ~1 per frame
  instead of 32 at once. teams_changed still forces immediate update.
- Intermission scoreboard sends are spread across 4 frames (~0.4s)
  instead of bursting all clients in a single frame.
- On-demand score key (TAB) switched from reliable to unreliable send,
  since the periodic refresh catches any dropped packets within 3 seconds.
- MAX_SCOREBOARD_SIZE raised from 1024 to 1300 bytes and
  MAX_PLAYERS_PER_TEAM raised from 8 to 10, using the headroom from
  reduced burst pressure while staying within legacy packet limits.
- Document scoreboard delivery changes and the configurable scoreboard
  field codes (previously undocumented) in action.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review feedback on the scoreboard stagger commit (ebf1254):

1. DeathmatchScoreboard (TAB key) was switched from reliable to unreliable
   with the rationale that "the periodic refresh catches drops". But the
   periodic refresh runs only once per 3 seconds, which is too slow to mask
   a dropped TAB response — a user pressing TAB on a lossy connection saw a
   blank scoreboard for up to 3 seconds. Single-client unicasts also don't
   contribute to the full-server burst problem the stagger was reducing.
   Revert that one site to reliable.

2. The per-client stagger formula used `i % (3 * HZ)` for slot assignment.
   At default HZ=10 the cycle is 30 frames; on servers with maxclients > 30
   (common: 32-64), high-index clients collided modulo-30 with low-index
   clients while some frame slots received two updates and others stayed
   idle. Expand the cycle to max(3*HZ, maxclients) so every client gets a
   unique slot. Common case (maxclients <= 30) is unchanged; large servers
   trade slightly slower refresh (maxclients/HZ seconds) for perfect
   distribution.

Note on the buffer-size review finding (MAX_SCOREBOARD_SIZE not propagated):
verified false — A_NewScoreboardMessage already uses MAX_SCOREBOARD_SIZE for
both `string` and `buf` declarations. The reviewer was looking at an older
file state.
@darkshade9
darkshade9 merged commit bf2b998 into aqtion-alpha May 24, 2026
8 checks passed
@darkshade9
darkshade9 deleted the full_scoreboard branch May 24, 2026 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant