feat(games): track Reverse: 1999, which resets at 05:00

Adds the r1999 GameId and its metadata, plus GameMeta.resetHourLocal for
the fact that makes it unlike every other game here: it rolls its day at
05:00 server time rather than 04:00, on a single global UTC-5 server, so
its day-key boundary is 10:00 UTC.

resetOffsets could not carry that. Landing 10:00 UTC through the offset
would mean claiming a UTC-6 server, and serverOffsetUtc answers more
questions than this one. The new field overrides RESET_HOUR_LOCAL per game
and is absent everywhere else, so no existing reader's logged day moved —
a test pins that for the games that already had readers.

Both facts are read off the source, not assumed: all 154 rows of the
wiki's event list state (UTC-5) and run 05:00 to 04:59, an event ending
one minute before the reset the next one begins on.

No adapter yet, so the game has no events until one lands.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Lucas Winther
2026-08-17 22:45:40 +02:00
co-authored by Claude Opus 5
parent 7926a70850
commit 1a65a1f06c
6 changed files with 105 additions and 3 deletions
+21
View File
@@ -39,6 +39,21 @@ export interface GameMeta {
* docs/DATA-MODEL.md.
*/
resetOffsets?: Partial<Record<Region, number>> | undefined;
/**
* The hour of the server's own day this game rolls over on, when it is not
* `RESET_HOUR_LOCAL` (04:00).
*
* Most gacha servers reset at 04:00 local. Reverse: 1999 resets at 05:00, and
* the difference is not cosmetic: `resetOffsets` alone cannot express it,
* because bending a game's stated server offset to land the right instant
* would put every other reader of that offset an hour out.
*
* Like `resetOffsets` this feeds `dayKey`, which is a **localStorage key**, so
* the same warning applies — changing it for a game that already has readers
* re-labels the game-day their logged ticks fall in. Absent means 04:00, which
* is why adding this field moved no existing game.
*/
resetHourLocal?: number | undefined;
}
export const GAMES: Record<GameId, GameMeta> = {
@@ -66,6 +81,12 @@ export const GAMES: Record<GameId, GameMeta> = {
// from the regional default, and an offset invented here would move real
// readers' day keys. Add one only against evidence — see games.ts § resetOffsets.
p5x: { id: "p5x", name: "Persona 5: The Phantom X", short: "P5X", hue: "#D62246" , studio: "Perfect World", dailyTasks: "Daily missions, stamina" },
// Reverse: 1999 runs one global server on a fixed UTC-5 and rolls its day at
// **05:00**, not the 04:00 every other game here uses. Both facts come from
// the source rather than from habit: all 154 rows on the wiki's event list
// state `(UTC-5)`, and every one of them starts at 05:00 and ends at 04:59 —
// an event ending one minute before the reset that the next one begins on.
r1999: { id: "r1999", name: "Reverse: 1999", short: "R1999", hue: "#C9A227" , studio: "Bluepoch", dailyTasks: "Daily missions", resetOffsets: { asia: -5, america: -5, europe: -5 }, resetHourLocal: 5 },
};
export const GAME_LIST: GameMeta[] = Object.values(GAMES);