The number was never the decision
A PvP host can now pick a turn time limit from 30 seconds to 3 minutes, for accessibility. Almost everywhere the old fixed 60 seconds showed up, the actual design underneath it never depended on that number at all.
A PvP host can now choose how long each turn lasts, 30, 60, 90, 120, or 180 seconds, instead of a fixed 60, so a player who needs more time to type, whether from a disability or just less keyboard experience, gets an accommodation the previous single window couldn’t offer. Grilled to the same decision-only shape as the profanity-filtering design, the wayfinder session locked twelve decisions in one sitting, no map needed, before any code changed.
The first of those decisions to reach the codebase wasn’t a line of implementation at all: ADR-0018, the document describing PvP’s timeout mechanism, the stored deadline plus a waiting client’s claim plus the server’s own clock verifying it, needed a small correction rather than a sibling. Its opening line used to read “the server never enforces the 60-second PvP turn timeout on its own”; the number came out, and a trailing clause went in instead, noting that the timeout’s length is now the game’s configured duration while “the enforcement mechanism below is unaffected by that value.”
The ADR’s own words had baked “60 seconds” into a sentence about a mechanism that never actually depended on it, the deadline-and-claim design works exactly the same whether the number stored in it is thirty thousand milliseconds or three hundred thousand. Amending it in place said so plainly, rather than a new ADR implying a second decision had been made where there was only ever one.
The same number-versus-mechanism split showed up twice more in the implementation. The countdown that turns a player’s remaining time from calm to urgent used to compare a raw seconds count against two hardcoded thresholds tuned for a 60-second game; extracted into its own small selector, it now compares against ratios of whatever duration the game is actually using, preserving the original ten-and-twenty-second feel proportionally instead of literally:
const URGENT_RATIO = 10 / 60;
const WARNING_RATIO = 20 / 60;
export function selectCountdownStage(
remainingSeconds: number | null,
isMyTurn: boolean,
turnDurationMs: number
): CountdownStage | null {
if (remainingSeconds === null) return null;
if (!isMyTurn) return 'muted';
const totalSeconds = turnDurationMs / 1000;
if (remainingSeconds <= totalSeconds * URGENT_RATIO) return 'urgent';
if (remainingSeconds <= totalSeconds * WARNING_RATIO) return 'warning';
return 'ok';
}
A three-minute game would otherwise sit comfortably green for nearly its whole length and a thirty-second one would spend a third of its life screaming urgent; keeping the same felt experience across every preset meant the thresholds could never be absolute in the first place. The create-form slider carries its own version of the same idea in reverse: since the five presets aren’t evenly spaced, thirty seconds apart except the last sixty-second gap, no plain step-based range control can land on exactly these five values, so the slider’s own state is an index into the preset array, zero through four, never the raw seconds. The one number in this whole feature that genuinely doesn’t move is the small fixed count of consecutive missed turns that still forces a forfeit, regardless of the chosen duration: the duration itself is already the accommodation, and scaling that count on top of a longer window would be solving the same problem twice.