Skip to content

feat(games): fill out the game page below the hero - #60

Merged
kris1027 merged 15 commits into
mainfrom
feat/richer-game-page
Oct 26, 2026
Merged

kris1027 merged 15 commits into
mainfrom
feat/richer-game-page

Conversation

@kris1027

Copy link
Copy Markdown
Owner

What

The game page (/games/{id}) now has the same sections a movie page has. The hero gets an art backdrop and a Trailer button. Under it come Overview, Screenshots (with a dialog to see them larger), More like this, and Facts. A section is left out when IGDB has nothing for it.

Why

This builds scope feature G9 and follows spec 0031. Until now a game page showed only the hero. This change also adds the art backdrop that spec 0025 put off, so that item comes off the deferred list in docs/scope/games.md.

Changes

IGDB data (one call per game, as before)

  • IGDB_GAME_FIELDS asks for 21 more fields: storyline, artworks, screenshots, videos, similar games, companies, modes, perspectives, franchises, collections, engines and release dates. getGame is still the only IGDB request. Nothing is written to Postgres.
  • normalize.ts checks each nested entry on its own, so one odd entry gets dropped and getGame keeps working. New Game fields: artUrl, screenshotUrls (deduplicated, sorted by image_id, capped at 12), trailer, similarGameIds, developers, publishers, storyline, gameModes, playerPerspectives, franchises, series, gameEngines, platformReleases.
  • How the trailer is picked: of the videos whose name has "trailer" in it but not "gameplay", and whose id is a valid YouTube id, it takes the one with the lowest id.
  • IGDB_DATE_FORMAT pins IGDB's date_format ids. A release date with a missing or unknown format is skipped, never read as a full day. formatGameReleaseDate in lib/format.ts shows a date at the precision IGDB gives: day, month, quarter, year or TBA.
  • New exported types: GameVideo, PlatformRelease, GameReleaseDate.

Page and components

  • GameHero gets a backdrop from artUrl and puts the existing TrailerButton (the youtube-nocookie dialog) in its actions slot.
  • GameOverview: the summary, then an optional Story, then Developed by and Published by, using the movie page's CrewLines.
  • ScreenshotGallery: a row of thumbnails that opens a controlled dialog with {n} of {total}, Previous and Next (no wraparound), arrow keys, and Escape. When the dialog closes, focus goes back to the thumbnail of the image that was showing.
  • GameMoreLikeThisSection: one cached getGamesByIds batch inside its own Suspense boundary. It keeps IGDB's order, drops hidden and missing games before the cap of 12, and renders G8 cards through CatalogListCards. An IgdbError shows a "Couldn't load similar games from IGDB." line with Retry. Any other error is thrown again.
  • GameFacts uses the shared FactsPanel. A label becomes plural (Franchises, Game engines) only when there is more than one value. Release dates are listed one per platform, earliest first, with TBA last.
  • GameDetailSkeleton now shows the backdrop hero and an overview skeleton.

Shared catalog pieces (TMDB callers are unchanged)

  • These are now exported: CrewLines, FactsPanel, Fact, textFact (title-details.tsx) and MoreLikeThisFrame (title-extras.tsx).
  • SectionErrorLine gets an optional source prop that defaults to "TMDB".

Docs and showcase

  • /showcase gets a "Game page sections" block.
  • G9 is marked done in docs/scope/games.md.
  • Spec 0031 is added with rationale.md and verify.md.

How to test / verify

  • pnpm typecheck, pnpm lint:ci, pnpm test: green on this branch (215 files, 3765 tests). Each commit typechecks on its own.
  • pnpm build: /games/[id] still shows as ◐ (partially prerendered), and the build makes no IGDB call.
  • pnpm igdb:live: checks the new fields, the date_formats ids, and that a quarter date really falls in its quarter.
  • Open /games/1942 (The Witcher 3). You should see the hero with a backdrop, then Overview, Screenshots, More like this, and Facts, in that order. Press Trailer: the dialog opens on 5nLipy-Z4yo, and no iframe exists before you press it.
  • Open screenshot 3. The dialog reads 3 of 12. ArrowRight takes you to 4 of 12. Escape closes it and focus lands on Open screenshot 4 of 12.
  • Open /games/94975 (Wubble Bubbles). You should see only the hero: no backdrop, no Trailer button, and no h2.
  • Look at the new sections and the open dialog at 375px and 1280px. There should be no horizontal page scroll, Previous, Next and Close should be 44px, and focus should be visible.

Risk & rollout

Low to medium risk. No migrations, no new environment variables, no new image hosts. Images still go through lib/images/loader.ts, never /_next/image. Game pages stay noindex until G10, and the GAMES tab is still behind NEXT_PUBLIC_GAMES_LIBRARY.

Tradeoffs the spec accepts:

  • The getGame response is several times bigger now. The hours cache softens this.
  • If getGame fails, every section fails with it. Only More like this can fail on its own.
  • A quarter date can sort before an exact date in the same quarter.
  • A game with no art shifts up a little when it streams in, because the skeleton assumes a backdrop.

Notes for reviewers

  • Four checks in verify.md were not done by hand and are covered only by unit tests: the More like this error line (game-more-like-this.test.tsx), the backdrop source order (normalize.test.ts), similar ids leaving out the game's own id and hidden games, and the plural labels (game-facts.test.tsx).
  • screenshot-gallery.tsx deserves a close look. It uses one controlled dialog for up to 12 thumbnails, with finalFocus pointing at the ref of whichever thumbnail is current.
  • The fixture lib/igdb/__fixtures__/game-1942.json is a fresh full capture, so most of its 371 added lines are IGDB data.

🤖 Generated with Claude Code

kris1027 and others added 5 commits October 26, 2026 20:01
Export CrewLines, FactsPanel, textFact and MoreLikeThisFrame so the game
page can reuse them, and let SectionErrorLine name IGDB as its source
(spec 0031, AC-5, AC-8, AC-9). TMDB callers are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
getGame asks for storyline, artworks, screenshots, videos, similar games,
involved companies, modes, perspectives, franchises, collections, engines
and release dates, still in one cached call. Each nested entry is checked
on its own, IGDB_DATE_FORMAT pins the date precision ids, and
formatGameReleaseDate shows a date at the precision IGDB states
(spec 0031, AC-2, AC-4, AC-10, AC-14).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hero gets an art backdrop and the Trailer button. Under it come
Overview, a Screenshots row with its dialog, More like this through the
G8 cards in its own boundary, and Facts with per platform release dates.
Each section is left out when IGDB has nothing for it (spec 0031).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kris1027 kris1027 added docs Documentation additions and updates feature New user-facing functionality test Automated tests and test infrastructure ui Layouts, styling, and shared interface components labels Oct 26, 2026
@kris1027 kris1027 self-assigned this Oct 26, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in BeStats Oct 26, 2026
@vercel

vercel Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
bestats Ready Ready Preview Oct 26, 2026 7:17pm UTC

kris1027 and others added 10 commits October 26, 2026 20:10
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mats

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kris1027
kris1027 merged commit 82102a1 into main Oct 26, 2026
4 checks passed
@kris1027
kris1027 deleted the feat/richer-game-page branch October 26, 2026 19:20
@github-project-automation github-project-automation Bot moved this from In review to Done in BeStats Oct 26, 2026

This branch was successfully deployed

1 active deployment
Preview — a8d1e8fa Deployed Oct 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation additions and updates feature New user-facing functionality test Automated tests and test infrastructure ui Layouts, styling, and shared interface components

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant