Analysis of the 26-comment r/gachagaming thread from two days after the
first Pages deploy, with every claim checked against the tree at 6fc3c0b.
Two criticisms recur and only two: the game list is too short to be
anyone's tracker, and the design reads as unfinished. Nobody questioned a
single date, which is the thing most of this codebase's rules exist to
protect.
Recording it because the priority list it ends on is what the next
commits act on — P1c, more games, best-source-first, one commit each. The
saved thread it quotes is left untracked.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
17 KiB
Community feedback — first public release
Source: FEEDBACK.HTML, a saved copy of the r/gachagaming thread
"[PROMO] I made an event tracker for those playing multiple gacha games at the same time, to know
which events to prioritize." — 26 comments from 15 accounts (20 comments from 14 readers, 6 replies
from OP). Read 2026-08-17, two days after the first Pages deploy.
Every quote below is from that thread. Every "what the code does today" note was checked against the
tree at 6fc3c0b.
The one-paragraph read
The idea landed and the execution did not get in the way: multiple people called it useful unprompted, one bookmarked it, and nobody questioned a single date — which is the thing this codebase spends most of its rules protecting. Two criticisms recur, and only two. First and loudest: the game list is too short to be someone's tracker. Every reader who did not already play one of the six covered games bounced off, politely. Second: the visual design reads as unfinished, and one reader judged it from the screenshot alone and never opened the site. A third, narrower note is already coming true — with two games selected the list is long enough to lose the point of the app.
Nobody asked for accounts, sync, or a login. Nobody complained about mobile. Nobody mentioned the daily-checklist feature at all, in either direction.
What works
The premise is the product. Four separate readers described the problem in the app's own terms before saying anything about the app:
"hmm this is actually what I need right now playing 4 games (3 hoyo + wuwa)."
"It's helpful for me at least since I play so many games and looks like I have to catch up with some of them."
"AI slop or not, this makes prioritizing across games much easier."
The cross-game-prioritisation framing needs no explaining to this audience. Keep it as the headline.
Date accuracy drew zero complaints. In 26 comments nobody said an end date was wrong, nobody
said an event was missing from a covered game, and nobody said a countdown looked off. For a
two-day-old scraper over six games that is the single best signal in the thread. The skip-never-guess
rule and the endsAt: null discipline are earning their keep — and this is also the thing that will
silently stop being true if the refresh pipeline stalls (see P0).
No one asked for an account. Not one reader asked to log in, sync across devices, or save to a profile — including the reader juggling ten games, who asked for customisation, not sync. The no-accounts constraint costs nothing with this audience.
The AI-slop self-deprecation was forgiven, not shared. Two readers went out of their way to say it did not matter:
"I don't typically like the way AI is used these days, but I've always thought it had the potential to actually help us out. This is one of those cases, thanks for this man."
That framing is a net negative to keep using, though — see P3.
The reader who wanted a specific interface wanted the one that already exists. Asked what would
improve the UI, the one reader who criticised the design answered "i really like paimon.moe timeline
for GI." That is a horizontal Gantt per game with today pinned — which is exactly
src/client/components/Timeline.tsx, already built, already the shape the PRD specifies as F1. The
feature is done. Its discoverability is not.
What needs work, in priority order
P0 — Confirm the live site is serving live data
Why first: the entire value proposition is that the dates are right today. Everything else in this document is worthless if this is broken.
What I can see: snapshots/ contains exactly one page — endfield-wikigg-events.html — against
seven registered sources in src/ingest/adapters/index.ts. Snapshots are tracked in git on purpose
(snapshots/README.md), and scripts/build-feed.ts falls back to fixtures/ when a source has no
snapshot. So the deployed feed is being built from pinned fixture bytes captured 2026-08-14 for
Genshin, HSR, ZZZ, WuWa, NTE and the Game8 Endfield source — five of six games. Those fixtures were
correct when captured; a patch cycle is six weeks, so they will start being wrong within days, and
they will be wrong confidently, which is the exact failure mode the PRD calls the one to prevent.
I cannot tell from a local checkout whether the six Game8 fetches are failing (robots check failing closed, a 403, a template-mismatch throw) or simply have not committed a change yet. That is the first thing to find out.
Steps:
- Read the last few Refresh sources runs in Actions. The runner does not retry and fails closed
on an unreadable
robots.txt, so a systematic Game8 failure would be visible per source there. bun run refresh --dry-runlocally to see the plan and the robots verdict per source without making a request.- If Game8 is being refused, that is a scraping-conduct question before it is a code question —
re-read
CLAUDE.md§ Scraping conduct and decide, rather than working around it. - Regardless of cause: surface it in the UI.
Colophon.tsxalready receivesstaleCount, andApp.tsxcomputesstaleSourcesat a two-day threshold. Verify a reader actually sees that banner today, because if five of six games are on four-day-old fixtures, the app is currently claiming more freshness than it has. - Add a CI assertion that fails the build when a source has neither a snapshot nor a fixture newer than N days. A silent fallback to stale bytes should not be able to deploy.
P1 — Games: the only thing standing between this and daily use
The signal. This is not one comment, it is the shape of the whole thread.
"Sadly I don't play any of those gacha games (despite juggling 10 games atm), will wait till more are added or we are able to customise it."
"This is awesome, bookmarked it. Hope it gets some more games added, like Reverse: 1999."
"Would there be option to add more games?"
Named across the thread, excluding the six already covered:
| Game | Mentions | Notes |
|---|---|---|
| Arknights | 2 | GameId, hue and dailyTasks already exist in games.ts with no source registered. Cheapest possible win. |
| Reverse: 1999 | 1 | Named as the one thing between a bookmark and a habit. |
| Azur Lane | 1 | OP judged doable |
| Blue Archive | 1 | OP judged doable |
| Umamusume | 1 | OP judged doable |
| Persona 5X | 1 | OP judged doable |
| Nikke | 1 | |
| Stella Sora | 1 | |
| Aether Gazer | 1 | |
| Chaos Zero Nightmare | 1 | |
| Girls' Frontline 2 | 1 | |
| Punishing: Gray Raven | 1 | |
| Guardian Tales | 1 | |
| Silver Palace | 1 | Unreleased — no schedule to scrape yet |
Steps:
- Arknights first. Half the work is already committed: the
GameIdexists, so this is aSOURCESentry, a fixture, and a test — no schema change, which is the PRD's own test of whether the data model is right. It is also the most-named game in the thread. - Then work down the list by source quality, not by mention count. Prefer a page that publishes
machine-readable timestamps:
wikigg.tsexists and is the only reasonregionEndscarries real data anywhere, so a wiki.gg or MediaWiki event page for a requested game is aSOURCESentry against an existing parser. A Game8 page is a second choice; anything image-only is not a source. - Use the add-game-source skill per game — it covers the ToS/robots check, fixture capture, registration and the test. One source per pass, verified against the live page, then commit.
- Do not batch six games into one commit. Each adapter is a fixture and a test that has to prove itself; a bad one publishes wrong dates for a game nobody was asking to be wrong about.
- Say the roadmap out loud in the app. A reader who does not see their game currently sees no reason to come back. A line in the colophon listing what is being worked on converts "will wait till more are added" into a return visit.
P1 — The list gets long fast, and the default view should not be the long one
The signal. The most specific, most actionable comment in the thread:
"I just selected Genshin and ZZZ and the list became really long. Once more games are in it's going to be a problem to try and focus in one specific game even with the filters. I feel it would be easier in the eyes if the current interface became a sort of 'Detailed' list view while the default interface focused on the three next closest events to their deadlines and it's on the user to check out these so they get filtered out as the player finish them."
He is measurably right. Genshin's fixture holds 9 events and ZZZ's 12 — 21 rows for the two-game case he tried, out of ~50 across six games. Doubling the game count doubles that.
What the code does today. More of this is built than the comment assumes, which is good news:
NextUp.tsxalready singles out the next event to expire — but exactly one, where he asked for three.GameFocus.tsx(shipped 2026-08-16, after the thread) is precisely the "focus one specific game" control he predicted needing.outstanding()instate/lens.tsalready drops done and ignored events from the instruction surfaces, which is the "they get filtered out as the player finish them" half.
So this is a default and framing problem, not a missing-feature problem.
Steps:
- Widen
NextUpfrom one row to the next three outstanding deadlines. Keep it fed byoutstanding+firstToExpire's ordering so it never points at finished work, and keep reading the minimum end date rather than the head of the list — under "doing first" those differ. - Cap the "Running now" section at a handful of rows with an explicit "show all N" expander, rather
than rendering 21. Grouping stays as-is; this is truncation of the view, not a re-sort, so the
deadline-order guarantee in
CLAUDE.md§ Conventions is untouched. - Persist the view.
const [view, setView] = useState<View>("soon")inApp.tsx:68is component state, so every reload throws the reader back to the list even if they chose the timeline last time. It belongs inprefsnext tosortandfocusGame. - Adopt his vocabulary. "Detailed" is a better name for the full list than the current split implies, and it tells the reader the short view is the intended one.
P2 — The visual design is the only thing anyone criticised
The signal.
"but from the screenshot the UI looks very bad :("
"probably the colour or design style. It's true that I wasn't able to check out the whole site and only judged from the screenshot (as I said in the beginning)."
Two things are true at once here: it is one person's opinion, and it was formed entirely from the promo screenshot — the reader said so twice. That makes it partly a first-impression problem you control completely, and it cost a visit from someone who was otherwise the exact target user.
Steps:
- Rename the "Calendar" tab to "Timeline." The one reader who told you what good looks like named paimon.moe's timeline, and OP had to ask him whether he had found the view — "Have you checked out the calender view? :)" A reader hunting for a timeline does not read "Calendar" as one, and the tabs are 12px text in the top-right corner.
- Consider making the timeline the default view.
docs/PRD.mdF1 specifies the calendar view as the default; the shipped app defaults to"soon". The timeline is also the better screenshot and the thing that reads as "designed" rather than "a list." If P1's three-deadline view lands, that becomes a genuine three-way call — decide it deliberately rather than by inheritance. - Reshoot the promo screenshot before the next post: timeline view, three or four games with overlapping bars, today's rule visible. The current one apparently showed the dense list.
- Take one focused pass on colour. The palette carries two orthogonal axes on purpose — game hue
(
games.ts) and urgency (time.ts/URGENCY_COLOR) — and seven saturated hues next to three urgency colours is where "AI-generated default" reads from. The frontend-design skill is the right tool; the constraint to hand it is that the two axes must stay separable at a glance, because that separation is what lets one look answer both "whose event is this?" and "how long have I got?" - Do not rebuild the interface. One person disliked the colours from a screenshot; several others used the app and said it was helpful. This is a polish pass, not a rewrite.
P2 — Custom events and custom games: the tail no adapter list will ever cover
The signal. Asked twice, independently, and it is the only feature request from the reader with the largest collection of games:
"Or can you add a custom game option, we can input out own event description and time frames?"
"will wait till more are added or we are able to customise it"
Fourteen games were named in one thread. No feasible adapter set covers a ten-game juggler, so this is the feature that makes the app usable for readers you will never scrape for — and it needs no scraping, no ToS question, and no server.
Steps, and the constraints they must respect:
- Store user-authored events in
localStoragealongsideprogress/daily/ignored, and add them toexportProgress— a backup that silently omits hand-entered events is a lossy backup, the same argument the code already makes for streaks. - Never mint a user event's ID the standard way.
${game}:${slug}:${date}anddailies:<game>are live key spaces and a collision corrupts real marks. Give user events their own prefix, and run the schema-guardian agent on the change — this is exactly the class of changeCLAUDE.md§ Event IDs flags. - Mark provenance in the UI. A hand-entered date must be visibly the reader's own, never
attributed to a source, and must not flow into merge or sanitisation. The trust boundary at
src/ingest/sanitize.tsis for pages we do not control; this is a different path entirely. - A custom game needs a name and a colour but no adapter, and must not appear as a scraped game
with an empty feed. Note that
gamesinApp.tsx:154is derived from feed rows, so a custom game needs threading through deliberately rather than added toGAMES. - This is currently out of scope in
docs/PRD.md("user-submitted events"). The thread is an argument to change that decision — make the change in the PRD first, with the reasoning, rather than letting the code drift from the spec.
P3 — Smaller notes worth acting on
- Drop the "AI-SLOP" framing from the next post. It was volunteered, not extracted — and the one criticism the thread produced was about visual polish, which is precisely what that framing invites a reader to look for. The one reader who criticised the design judged the screenshot harshly having been told in advance it was slop. The work stands on its own.
- A non-English reader turned up on day one. "Por fin algo que de verdad me sirve" — finally
something that's actually useful to me. Localisation is explicitly out of scope in the PRD and
should stay there for now; note only that dates and countdowns already localise through
Intl, so the copy is the whole cost when it becomes worth paying. - The "catching up" reader is a real second use case, but do not build for it yet. Three readers
described being behind rather than being busy: "I have to catch up with some of them,"
"I haven't touched Wuwa, zzz, HSR and arknights in a long time," and a third reader's plan to play
one gacha in concentrated bursts. The
status("partway through") andeffortfields plus the "doing first" sort already serve this. Resist adding a "you haven't played X in N days" nudge:CLAUDE.mddraws a hard line between what the app shows and what it tells you to do, and nagging someone about a game they consciously dropped is the app arguing with them. - The daily-checklist feature got no signal at all — not one comment, positive or negative, in 26. It shipped detection-off and experimental two days ago, which is the right posture. Do not invest further until someone mentions it; one reader's alternative was a notepad ("while i simply put mine in a notepad. i'm playing 6 games").
Suggested order of work
- P0 — diagnose the refresh pipeline; make stale data loud and un-deployable. Hours.
- P1a — Arknights adapter (
GameIdalready exists). One pass ofadd-game-source. - P1b — three deadlines in
NextUp, cap the long list, persistview, rename Calendar → Timeline. Small, all in the client, all directly requested. - P1c — two or three more games, best-source-first, one commit each. Publish the roadmap in the colophon.
- P2 — colour and screenshot pass; then decide the default view deliberately.
- P2 — custom events, starting with the PRD decision and a schema-guardian review.
Everything in P0 and P1b is a change to code that already exists. That is the cheapest half of this list and it addresses the two loudest complaints in the thread.