feat: decide the order games are listed in

Nothing did. Every surface that lists a game rendered App's `games`, which is
the order lanes first appear in the feed — whichever game happened to hold the
first event row. It is arbitrary, it moves as events come and go, and it was
the same complaint the first-run picker had.

So `orderGames` is one rule in one place, and `prefs.gameOrder` is where the
reader's own answer goes. Absent means they have never placed a game rather
than an empty order, which is the distinction `knownGames` already draws and
the same trap: every install predating the field is in that state, and reading
it the other way would hand them a blank list. They get A–Z by the name on
screen instead.

Two properties carry the weight, and both are tested rather than asserted. The
result is always a permutation of the lanes given, because a game dropped
here looks exactly like a game switched off and switching it on would not
bring it back. And a lane the order does not name trails the ones it does, so
a game we add later never lands in the middle of a hand-made order and a
retired source keeps its slot for when it returns.

Nothing reads it yet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Opus 5 committed 2026-08-20 06:00:32 +02:00
1 parent 7b6ee62235
commit 88d5ea2e43
3 files changed
+290

No files matched your search

+22
View File
@@ -47,6 +47,28 @@ export interface Prefs {
* them in.
*/
knownGames?: LaneId[];
/**
* The order the reader put their games in.
*
* Absent means they have never placed one — not that they have no order, and
* not an empty order. Every install predating this is in that state, so the
* fallback has to be a rule rather than a stored value: `orderGames` sorts
* alphabetically by name, which is what the first-run picker already does.
* A game added later trails everything they placed by hand.
*
* `| undefined` is explicit because `exactOptionalPropertyTypes` is on and
* "Reset to A–Z" is a patch that writes the field away — `{ gameOrder:
* undefined }` has to be assignable for the reset to typecheck, and
* `JSON.stringify` drops it on the way to storage.
*
* Not a key space and not a migration: one more field in the single `prefs`
* blob, like `timelineGroup`. It rides the export for free, though note that
* `importProgress` restores progress, dailies, ignores and the reader's own
* games — never prefs — so an imported file does not bring an order back.
* That asymmetry predates this field and applies to region, theme and view
* alike.
*/
gameOrder?: LaneId[] | undefined;
/**
* One game to look at right now, or null for all of them.
*