CASE-0016 · MISSION REPORT任務報告
Maintained

pokemon-route

A route for playing the whole Pokemon series, Gen 1 to Gen 9 — twelve games, one story per region, zero dependencies.

pokemon-route screenshot
SPINE
PROBLEM
Twenty-two mainline Pokemon games have shipped, but many retell the same story: paired versions differ by a handful of exclusives, and remakes revisit regions already covered. Choosing which version of each generation to actually play means wading through twenty years of unresolved forum argument, where no source separates a structural fact from an opinion.
ROLE
Sole author — the route thesis and its research, the design system, the hand-written HTML/CSS/JS, the era-accurate sprite pipeline, a dependency-free validator that enforces the project's own rules in CI, and the nginx/Traefik deployment.
OUTCOME
Twelve stops covering the series with nothing repeated, each naming what its generation introduced and which games it drops. Ships at ~196 KB with zero dependencies and no build step, gated by 33 CI checks that enforce the design system itself. Factual corrections are logged openly in CONTRIBUTING rather than quietly patched.
KEY FEATURES
  • Zero dependencies, zero build step — index.html is the artifact, ~196 KB total
  • Era-accurate sprites: each drawn in its own game's style, 1998 through 2025
  • Three-state progress and a meter that reads as progress and hardware timeline
  • 33 CI checks enforcing the project's own design system, not generic linting
OVERVIEW

stars last commit license

A route for playing the whole Pokemon series without playing the same story twice

Twenty-two mainline games have shipped, but many of them tell the same story more than once. Paired versions differ by a handful of exclusive Pokemon; remakes revisit regions already covered. Strip that out and twelve distinct stories remain. pokemon.cativo.dev is that route, with the reasoning for every pick and every omission.

Why I built it

I grew up on these games, lost the thread around the DS era, and picked up Scarlet years later. Rather than start at the end I wanted to go back to the beginning — and the answer to "which version do I actually play?" was scattered across twenty years of forum argument. So I made the decision once, wrote down why, and made the page honest about which calls are genuinely contested.

It doubles as a deliberate exercise in restraint: no framework, no build step, no dependencies, no tracking. index.html is the deployable artifact.

What it does

  • Twelve stops, one story per region. Each opens to reveal the full generation it came from and which of its games were dropped, so nothing is hidden — just folded away.
  • Era-accurate sprites. Every mascot is drawn in the graphical style of its own game, since PokeAPI indexes sprites per version, so the art visibly evolves from 1998 to 2025 as you scroll. The hero is the genuine Red/Blue monochrome Pikachu, remapped to the four real colours of the Game Boy DMG screen.
  • Three-state progress. Not started, playing, cleared — because on a route this long you sit on a single game for months, which a checkbox cannot express. Stored in localStorage; nothing leaves the browser.
  • A meter that reads two ways. Twelve cells grouped into the six hardware eras: how far along you are, and which console you are on, in one control.
  • Mechanical history. Each stop names what its generation introduced, and the growing type chart is drawn as a strip that fills up across the route — three empty slots in Kanto that are not filled until Kalos, six stops later.
  • Keyboard navigation. J/K walk the route, N jumps to the first unfinished stop, ? lists the rest.

The part worth reviewing

tools/validate.py — 33 checks, standard library only, running in CI. It does not check generic things; it enforces this project's own rules. No colour or font may escape the token system. No token may exist only in the dark palette. The anti-pattern list must stay empty. Every image needs alt text and explicit dimensions. The advertised hour total must equal the sum of the stops — a check that caught a stale number the first time it ran. The sharing card's declared dimensions must match the actual PNG, read straight from its IHDR header.

A repo that enforces its own design system in CI says more than any badge does.

On being wrong in public

The page makes factual claims about thirty years of games, so it ships with a rule that corrections get logged rather than quietly patched. CONTRIBUTING.md lists the ones already made: a claim that Sword was the first mainline game on a home console (Let's Go beat it by a year), a description of Challenge Mode as selectable when it is exclusive to Black 2 and unlocks only after the Champion, and an assertion that the Sinnoh remakes reintroduce every problem Platinum solved, when the Grand Underground restores most of what Platinum added.

Stack

Hand-written HTML, CSS and JavaScript — zero dependencies, zero build step, ~196 KB including sprites. Python for the validator and the sharing-card renderer. Deployed to nginx behind Traefik; GitHub Actions runs the checks and a weight budget on every push, with branch protection split across two rulesets so history cannot be rewritten even by me.

Status

Live at pokemon.cativo.dev. MIT — the sprites are not mine and are not covered by it.