From 04c69fd3df515ad7d96fd404facdf5830b1b0adc Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Wed, 19 Aug 2026 03:52:02 +0200 Subject: [PATCH] feat: add Umamusume, from Game8's banner list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit uma.moe stays declined — its API sits behind a Cloudflare Turnstile proof header, and an adapter would mean defeating a deliberate access control. This is the surface that is simply open, and it needed the parser change in the commit before this one to be readable at all. The stable URL matters: Game8 also publishes monthly "August 2026 Release Schedule" pages whose id changes every month, which a static registry cannot follow. "List of All Banners" does not move. Four current banners, both columns of the side-by-side table, and none of the Previous Banners below them. The tenth game8 source, so it carries the same CI blindness as the other nine and only a manual refresh moves it. Co-Authored-By: Claude Opus 5 (1M context) --- AGENTS.md | 21 +- docs/DATA-MODEL.md | 4 +- docs/INGESTION.md | 2 +- docs/PRD.md | 4 +- .../uma/game8-events-2026-08-19.expected.json | 86 + fixtures/uma/game8-events-2026-08-19.html | 1771 +++++++++++++++++ src/ingest/adapters/index.ts | 15 + src/shared/games.ts | 5 + src/shared/schema.ts | 1 + test/adapters/game8.test.ts | 34 + 10 files changed, 1928 insertions(+), 15 deletions(-) create mode 100644 fixtures/uma/game8-events-2026-08-19.expected.json create mode 100644 fixtures/uma/game8-events-2026-08-19.html diff --git a/AGENTS.md b/AGENTS.md index 47eabfb..8d7e686 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,8 +37,8 @@ A web app that aggregates live and upcoming events across popular gacha games, p calendar, sorts them by end date or by what the reader is partway through, tracks day-by-day progress on events that repeat daily, and lets a user mark events completed. -**Status: working app, refreshing itself on a schedule.** Schema, eight parsers, seventeen sources across -sixteen games, the full interface, offline support, a static server, a Docker image and CI all exist and +**Status: working app, refreshing itself on a schedule.** Schema, eight parsers, eighteen sources across +seventeen games, the full interface, offline support, a static server, a Docker image and CI all exist and are tested. The refresh runner (`bun run refresh`) fetches, caches raw snapshots and rebuilds the feed; `.github/workflows/refresh.yml` runs it twice a day and commits only when a page actually changed. The SQLite layer and the review queue are still specified in `docs/` but not built, so the @@ -119,7 +119,7 @@ src/client/ React app, service worker, manifest theme.ts — dark or light, and what a game hue reads as on each scripts/ build-feed.ts, build-static.ts, parse-fixture.ts (offline), refresh-sources.ts (fetches) serve.ts static server + /api/health -test/ 674 tests +test/ 683 tests fixtures// raw HTML + .expected.json per source — pinned, kept forever snapshots/ current page per source, rewritten by refresh — see its README ``` @@ -164,7 +164,7 @@ These come from how gacha games actually schedule things, and they cause most bu - **Skip, never guess.** Every function in `dates.ts` returns `null` rather than inferring a missing year, month, or end. `readColumnTable` drops a row it cannot date. An omitted event is a recoverable disappointment; a confidently wrong date is the failure this product exists to prevent. -- **Parsers are keyed by site, not game.** One `game8` parser serves nine sources and `fandom` two; +- **Parsers are keyed by site, not game.** One `game8` parser serves ten sources and `fandom` two; `wikigg`, `akwiki`, `bawiki`, `holodoriwiki`, `iopwiki` and `stellasorawiki` serve one each — the first two share a host family and have entirely different templates, and the last two are both Miraheze wikis whose page templates have nothing in common. Adding a source for a known site is one `SOURCES` entry; a new @@ -256,9 +256,9 @@ Sources are community wikis. Treat them as a guest would: - Honor `robots.txt`; set a descriptive `User-Agent` with a contact URL. - One request per source per refresh cycle, minimum 6 hours apart. -- **Space requests to one host**, honouring its `Crawl-delay` and defaulting to 2s. Nine of the - seventeen sources are game8.co pages, so the per-source floor alone still permits one cycle to arrive - as nine back-to-back requests to a single site — which is the shape an edge network throttles, and +- **Space requests to one host**, honouring its `Crawl-delay` and defaulting to 2s. Ten of the + eighteen sources are game8.co pages, so the per-source floor alone still permits one cycle to arrive + as ten back-to-back requests to a single site — which is the shape an edge network throttles, and what a burst looks like from the far end regardless of our intent. - Send `If-None-Match` / `If-Modified-Since`; treat `304` as "skip, unchanged". - Cache raw snapshots so re-parsing never re-fetches. **Iterate against fixtures, not the network.** @@ -270,9 +270,9 @@ training, and no `User-agent: *` rule applies to our paths. Keep it that way: do rate, and do not add an LLM that consumes page content. **game8.co does not answer a GitHub Actions runner** (confirmed 2026-08-17). Its edge returns -`202 Accepted` with a bot-management body to every one of the nine game8 sources, from the first +`202 Accepted` with a bot-management body to every one of the ten game8 sources, from the first scheduled cycle onward — `last confirmed: never` — while the same URLs return `200` and parse -cleanly from a normal address. So `robots.txt` permits us and the network does not, and those nine +cleanly from a normal address. So `robots.txt` permits us and the network does not, and those ten games have only ever been built from checked-in fixtures in CI. The per-host spacing above does not fix this and was not meant to: a 202 on the very first request @@ -300,6 +300,7 @@ re-litigated each pass: | `iopwiki.com` | **Built** (2026-08-19), Girls' Frontline 2 — see § IOP Wiki below. `robots.txt` is two lines, `User-agent: *` and `Crawl-Delay: 20`, no `Disallow` anywhere | | `stellasora.miraheze.org` | **Built** (2026-08-19), from the front page's `Current Banners` module and **not** `/wiki/Banner_List` — see § Stella Sora below | | `game8.co/games/Chaos-Zero-Nightmare` | **Built** (2026-08-19). Zero parser work — the existing `game8` parser reads it. The ninth game8 source, so fixture-backed in CI from day one | +| `game8.co/games/Umamusume-Pretty-Derby` | **Built** (2026-08-19), off the stable `List of All Banners` page, not the monthly release-schedule pages whose URL changes every month. Cost a widening of `game8.ts`'s section and column vocabulary — see § Working on parsers | `.github/ISSUE_TEMPLATE/feature_request.yml` points readers at that table by heading, so a source request can be checked against it before anyone writes it up — the loudest feedback on the first @@ -625,6 +626,6 @@ to an open page). Four things hold it up: (PRD F7). `freshness()` in `src/shared/feed.ts` is the one definition: it takes the newest `lastSuccessAt` and **never `generatedAt`**, which is a build stamp that would call a fixture-backed calendar minutes old, and it treats a game as only as fresh as its *oldest* source, - so one live wiki cannot vouch for a stalled sibling. Given that nine sources cannot be fetched + so one live wiki cannot vouch for a stalled sibling. Given that ten sources cannot be fetched from CI at all (§ Scraping conduct), this disclosure is the only thing standing between a reader and a confidently stale calendar — do not let a future change source it from the build clock. diff --git a/docs/DATA-MODEL.md b/docs/DATA-MODEL.md index b1610c7..b5c85df 100644 --- a/docs/DATA-MODEL.md +++ b/docs/DATA-MODEL.md @@ -10,7 +10,7 @@ import { z } from "zod"; export const GameId = z.enum([ "genshin", "hsr", "zzz", "wuwa", "arknights", "endfield", "nte", "nikki", "p5x", "r1999", - "ba", "fgo", "holodori", "gfl2", "stellasora", "czn", + "ba", "fgo", "holodori", "gfl2", "stellasora", "czn", "uma", ]); export const EventType = z.enum([ @@ -308,7 +308,7 @@ nothing to add, which is the point worth carrying to the next game: an override the game moves nobody, while the same override added a year later re-labels every tick already logged under the old clock. Get it right at introduction or accept a migration. -Infinity Nikki, P5X, Blue Archive and Chaos Zero Nightmare carry **no `resetOffsets` +Infinity Nikki, P5X, Blue Archive, Chaos Zero Nightmare and Umamusume carry **no `resetOffsets` entry**, so they take the regional default. That is an assumption, not a verified server map — none of those sources states one. Two of the 2026-08-19 additions are worth separating out, because they are silent for different reasons and neither is the usual one: diff --git a/docs/INGESTION.md b/docs/INGESTION.md index cebf8fd..4e9f9b5 100644 --- a/docs/INGESTION.md +++ b/docs/INGESTION.md @@ -48,7 +48,7 @@ Consequences worth internalising: | Parser | Site | Sources using it | |---|---|---| -| `game8` | game8.co article calendars | Genshin, Star Rail, Wuthering Waves, ZZZ, Endfield, NTE, Infinity Nikki, Persona 5: The Phantom X, Chaos Zero Nightmare | +| `game8` | game8.co article calendars | Genshin, Star Rail, Wuthering Waves, ZZZ, Endfield, NTE, Infinity Nikki, Persona 5: The Phantom X, Chaos Zero Nightmare, Umamusume | | `wikigg` | wiki.gg MediaWiki `mp-event` templates | Endfield | | `akwiki` | arknights.wiki.gg's `mrfz-wtable` "Ongoing/upcoming" table | Arknights | | `fandom` | Fandom wikis via the MediaWiki `action=parse` API — two page templates: `Event \| Time Period \| Version` wikitables, and FGO's picture-fenced `ONGOING EVENTS` blocks | Reverse: 1999, Fate/Grand Order | diff --git a/docs/PRD.md b/docs/PRD.md index f1c9863..d048e44 100644 --- a/docs/PRD.md +++ b/docs/PRD.md @@ -59,7 +59,7 @@ have a source — this table is the launch scope, not a roster to keep in sync. Adding a game must require no change to `GachaEvent` — only a `GameId` entry, its `games.ts` metadata, and a source registration. That is the test of whether the data model is right, and it has -held: the sixteen games here have cost the event schema nothing. Per-game *metadata* does occasionally +held: the seventeen games here have cost the event schema nothing. Per-game *metadata* does occasionally grow (Reverse: 1999 needed `resetHourLocal` for a 05:00 reset), which is a different file and moves no stored key. A game may have several sources; see `docs/INGESTION.md` § Three layers. @@ -90,7 +90,7 @@ default `"game"` — the board every existing reader already has). Merged, the o `endingSoonestFirst`, the same comparator behind the list's "Ending soonest" (F2), so the two views cannot mean different things by the same words and an unannounced end still sorts behind every dated one rather than claiming a place in the queue. Merged there is also no lane heading to say whose -event a bar is, and hue alone cannot answer that once sixteen games share a stack — so each bar +event a bar is, and hue alone cannot answer that once seventeen games share a stack — so each bar carries its game's short name, with the full name in its tooltip. A bar too narrow for a tag and a title both keeps the title: a chopped game name reads as a broken word, and the hue and the tooltip still answer it. diff --git a/fixtures/uma/game8-events-2026-08-19.expected.json b/fixtures/uma/game8-events-2026-08-19.expected.json new file mode 100644 index 0000000..b37be5d --- /dev/null +++ b/fixtures/uma/game8-events-2026-08-19.expected.json @@ -0,0 +1,86 @@ +[ + { + "id": "uma:3-star-guaranteed-1-5-anniversary-scout-character:2026-07-22", + "game": "uma", + "title": "3 Star Guaranteed 1.5 Anniversary Scout (Character)", + "type": "other", + "summary": null, + "startsAt": "2026-07-22T00:00:00.000Z", + "startPrecision": "day", + "endsAt": "2026-08-27T00:00:00.000Z", + "endPrecision": "day", + "regionScoped": false, + "regionEnds": null, + "sourceUrl": "https://game8.co/games/Umamusume-Pretty-Derby/archives/536311", + "sourceId": "uma-game8-events", + "status": "published", + "confidence": 0.85, + "extractionMethod": "parser", + "version": 1, + "firstSeenAt": "2026-08-14T00:00:00.000Z", + "updatedAt": "2026-08-14T00:00:00.000Z" + }, + { + "id": "uma:3-star-guaranteed-1-5-anniversary-scout-support:2026-07-22", + "game": "uma", + "title": "3 Star Guaranteed 1.5 Anniversary Scout (Support)", + "type": "other", + "summary": null, + "startsAt": "2026-07-22T00:00:00.000Z", + "startPrecision": "day", + "endsAt": "2026-08-27T00:00:00.000Z", + "endPrecision": "day", + "regionScoped": false, + "regionEnds": null, + "sourceUrl": "https://game8.co/games/Umamusume-Pretty-Derby/archives/536311", + "sourceId": "uma-game8-events", + "status": "published", + "confidence": 0.85, + "extractionMethod": "parser", + "version": 1, + "firstSeenAt": "2026-08-14T00:00:00.000Z", + "updatedAt": "2026-08-14T00:00:00.000Z" + }, + { + "id": "uma:daiichi-ruby-power-ssr-and-k-s-miracle-guts-sr:2026-08-12", + "game": "uma", + "title": "Daiichi Ruby Power SSR and K.S. Miracle Guts SR", + "type": "other", + "summary": null, + "startsAt": "2026-08-12T00:00:00.000Z", + "startPrecision": "day", + "endsAt": "2026-08-21T00:00:00.000Z", + "endPrecision": "day", + "regionScoped": false, + "regionEnds": null, + "sourceUrl": "https://game8.co/games/Umamusume-Pretty-Derby/archives/536311", + "sourceId": "uma-game8-events", + "status": "published", + "confidence": 0.85, + "extractionMethod": "parser", + "version": 1, + "firstSeenAt": "2026-08-14T00:00:00.000Z", + "updatedAt": "2026-08-14T00:00:00.000Z" + }, + { + "id": "uma:seeking-the-pearl-rocket-star:2026-08-12", + "game": "uma", + "title": "Seeking the Pearl (Rocket☆Star)", + "type": "other", + "summary": null, + "startsAt": "2026-08-12T00:00:00.000Z", + "startPrecision": "day", + "endsAt": "2026-08-21T00:00:00.000Z", + "endPrecision": "day", + "regionScoped": false, + "regionEnds": null, + "sourceUrl": "https://game8.co/games/Umamusume-Pretty-Derby/archives/536311", + "sourceId": "uma-game8-events", + "status": "published", + "confidence": 0.85, + "extractionMethod": "parser", + "version": 1, + "firstSeenAt": "2026-08-14T00:00:00.000Z", + "updatedAt": "2026-08-14T00:00:00.000Z" + } +] diff --git a/fixtures/uma/game8-events-2026-08-19.html b/fixtures/uma/game8-events-2026-08-19.html new file mode 100644 index 0000000..11ea928 --- /dev/null +++ b/fixtures/uma/game8-events-2026-08-19.html @@ -0,0 +1,1771 @@ +List of All Banners: Which Banner to Pull? | Umamusume: Pretty Derby|Game8 + + + + + + + + +

What can you do as a free member?

Member benefits illustration

Create your free account today and unlock all our premium features and tools to enhance your gaming experience.

Member benefits illustration

Create your free account today and save articles to your watchlist and get notified when they're updated with new information.

Member benefits illustration

Create your free account today and save your favorite games for quick access later, synced across all your devices.

Member benefits illustration

By creating a Game8 account and logging in, you'll receive instant notifications when someone replies to your posts.

Comment rating feature illustration

By creating a Game8 account and logging in, you can make use of convenient features in the comments section, such as rating and sorting comments.

Premium archive feature illustration

By creating a Game8 account and logging in, you can access Premium articles that are exclusively available to members.

Map tool feature illustration

By creating a Game8 account and logging in, the items you checked on the map tool will be saved.

Site Interface

Guest
Free Member
Article Watchlist
Game Bookmarks
Cross-device Sync
Light/Dark Theme Toggle
User Profiles
Direct Feedback
Comment Rating
Comment Notification
Premium Articles

Game Tools

Guest
Free Member
Interactive Map Access
Interactive Map Pins
Interactive Map Comments
Interactive Map Pins Cross-Device
Check List
Event Choice Checker
Deck Builder Cross-Device
Message Board Notification
Message Board Cross-Device
Build Planner
Stat Calculator
Diagnostic Tool
Weapon/Armor Wishlist
Team Builder
Character Scoring
Tier List Maker

Want more information?Learn more

+
Umamusume: Pretty Derby

List of All Banners: Which Banner to Pull?

+ + +Add to Watchlist (31)

All Banners Guide
This is a list of banners for Umamusume: Pretty Derby. Check out the list of all banners and who you should pull for in this guide.

+ + + + + + + + + + + + +
Banner Guides
List of All BannersUpcoming Banners
Best Upcoming Banners (2026)
+ + +

Best Banners to Pull (August 2026)

Fine Motion Wit SSR and Maruzensky Speed SSR Rerun

+ + + + + + + + + +
BannerAvailability (UTC)
+August 2026 - Aston Machan Aston Machan
Fine Motion (Wit SSR) and Maruzensky (Speed SSR) Reruns
August 25 - September 2, 2026
+ +

The best banner to go for in August 2026 would be the rerun banner of Fine Motion Wit SSR and Maruzensky Wit Speed SSR. Both are meta cards for a long while.

+ +

Fine Motion Wit will last until it is power crept by Mejiro Ramonu Wit SSR on the release of the Grand Masters scenario. It will still serve as a strong secondary Wit card after her. Maruzenksy Speed will stay as strong Front Runner card and a good general stat stick.

+ +

For trainees, Aston Machan is the meta pick for August 2026 due to being a strong Sprinter for the competitive environment. She has a bunch of useful skills for a Front Runner, notably Groundwork and Taking the Lead.

+ +

Upcoming Banners: Character and Support Card Release Order

+

List of All Banners

All Current Banners

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Standard Banners
BannerRatingAvailability
+Seeking the Pearl Banner Seeking the Pearl (Rocket☆Star) + +★★★★☆ + +8/12/2026 - 8/21/2026 +
+Daiicih Ruby and KS Miracle Banner Daiichi Ruby Power SSR and K.S. Miracle Guts SR + +★★★★☆ + +8/12/2026 - 8/21/2026 +
Paid Banners
BannerRatingAvailability
+1-5 GSSR Character Banner 3 Star Guaranteed 1.5 Anniversary Scout (Character) +★★★★☆7/22/2026 - 8/27/2026
+1-5 GSSR Support Banner 3 Star Guaranteed 1.5 Anniversary Scout (Support) +★★★★☆7/22/2026 - 8/27/2026
+Paid Trainee BannerHead Start Scout (Character) +★★★★☆Permanent
(One Time Use)
+Paid Support Card BannerHead Start Scout (Support) +★★★★☆Permanent
(One Time Use)
+

Previous Banners

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BannerRatingAvailability
+Yukino Bijin Banner Yukino Bijin (Darl'n Snowflake) + +★★★☆☆ + +8/5/2026 - 8/13/2026 +
+Falco and Suzuka Banner Smart Falcon Power SSR and Silence Suzuka Speed SSR + +★★☆☆☆ + +8/5/2026 - 8/13/2026 +
+Umamusume - Winning Ticket and Narita TaishinWinning Ticket (Dream Deliverer) and Narita Taishin (Difference Engineer) + +★★★☆☆ + +7/27/2026 - 8/10/2026 +
+Light Hello and Agnes Tachyon Speed SSR Light Hello (Pal SSR) and Agnes Tachyon (Speed SSR) + +★★★★★ + +7/22/2026 - 8/10/2026 +
+Smart Falcon Twilight Triumph Smart Falcon (Twilight Triumph) + +★★★☆☆ + +7/22/2026 - 8/10/2026 +
+Copano RickeyCopano Rickey (Eightfold☆Fortune) + +★★★★★ + +7/16/2026 - 7/26/2026 +
+Manhattan Cafe CardManhattan Cafe (Stamina SSR) and Seiun Sky (Wit SR) + +★★★☆☆ + +7/16/2026 - 7/26/2026 +
+Bamboo Memory Bamboo Memory (Iron Ambition) + +★★★☆☆ + +7/7/2026 - 7/16/2026 +
+Ikuno Dictus and Yukino Bijin Ikuno Dictus (Guts SSR) and Yukino Bijin (Wit SSR) (Rerun) + +★★☆☆☆ + +7/7/2026 - 7/16/2026 +
+Mejiro McQueen and Gold Ship +Summer Gold Ship and Summer Mejiro McQueen + +★★★★☆ + +7/2/2026 - 7/14/2026 +
+Maruzensky and Nakyama Festa Support Maruzensky (Speed SSR) and Nakayama Festa (Wit SSR) + +★★★★☆ + +7/2/2026 - 7/14/2026 +
+Seiun Sky and Narita Brian Rerun Banner +Seiun Sky and Narita Brian (Rerun) + +★★★☆☆ + +6/25/2026 - 7/4/2026 +
+Heirs to the Throne Banner +Heirs to the Throne (SSR Group) and El Condor Pasa (SR Speed) + +★★★☆☆ + +6/25/2026 - 7/4/2026 +
+Air Shakur Banner +Air Shakur (unsigned) +★★★☆☆6/18/2026 - 6/27/2026
+Air Groove Gold City Banner Air Groove (SSR Power) and Gold City (SR Wit) +★★☆☆☆6/18/2026 - 6/27/2026
+Summer Camp Taiki and Dober Scout +Taiki Shuttle and Mejiro Dober (Summer Camp Alts) +★★★★☆6/11/2026 - 6/22/2026
+Summer Camp Support Scout El Condor Pasa (Guts SSR) and Matikanetannhauser (Wit SSR) +★★☆☆☆6/11/2026 - 6/22/2026
+Sweep Tosho Banner Sweep Tosho +★★★☆☆6/4/2026 - 6/14/2026
+Taiki Shuttle SSR Banner Taiki Shuttle (Speed SSR) and Oguri Cap (Guts SR) +★★★☆☆6/4/2026 - 6/14/2026
+Inari One Scout Inari One +★★★☆☆5/28/2026 - 6/7/2026
+Admire Vega Rerun Scout Admire Vega (Power SSR) and Sakura Chiyono O (Stamina SSR) +★★★☆☆5/28/2026 - 6/7/2026
+Wedding Curren Chan and Fine Motion + Wedding Curren Chan and Wedding Fine Motion +★★★☆☆5/18/2026 - 5/29/2026
+Haru Urara and Ikuno Dictus Banner Haru Urara (Power SSR) and Ikuno Dictus (Stamina SSR) +★★☆☆☆5/18/2026 - 5/29/2026
+Mejiro Palmer banner +Mejiro Palmer +★★★☆☆5/10/2026 - 5/20/2026
+Fuku Rice Rerun +Matikanefukukitaru (Speed SSR) and Rice Shower (Power SSR) +★★★☆☆5/10/2026 - 5/20/2026
+Ines Fujin Banner +Ines Fujin +★★★☆☆4/30/2026 - 5/10/2026
+Mr. CB Wit Banner +Mr. C.B. Wit SSR and Tokai Teio Stamina SR +★★★★☆4/30/2026 - 5/10/2026
+Cheerleader Banner +Cheerleader Nice Nature and Cheerleader King Halo +★★★★☆4/26/2026 - 5/8/2026
+Cheerleader Support Banner +Seeking the Pearl SSR and Bamboo Memory Guts SSR +★★★☆☆4/26/2026 - 5/8/2026
+Yaeno Muteki banner +Yaeno Muteki +★★★☆☆4/20/2026 - 4/29/2026
+Twin Turbo Ines Fujin banner +Twin Turbo SSR and Ines Fujin SSR +★★☆☆☆4/20/2026 - 4/29/2026
+Nishino Flower Banner +Nishino Flower +★★★★★4/12/2026 - 4/20/2026
+Daiwa Scarlet and Sweep Tosho Banner +Daiwa Scarlet Power SSR and Sweep Tosho Wit SR +★★☆☆☆4/12/2026 - 4/20/2026
+Seiun Sky and Fuji Kiseki Banner +Alt. Seiun Sky and Fuji Kiseki +★★★☆☆4/5/2026 - 4/18/2026
+Symboli Rudolf and Sirius Symboli Banner +Symboli Rudolf Stamina SSR and Sirius Symboli Wit SSR +★★★☆☆4/5/2026 - 4/18/2026
+Paid Trainee Banner3★ Guaranteed 1st Anniversary Scout (Character) +★★★★☆3/22/2026 - 4/13/2026
(One Time Use)
+Paid Support Card BannerSSR Guaranteed 1st Anniversary Scout (Support) +★★★★☆3/22/2026 - 4/13/2026
(One Time Use)
+Mejiro Bright Banner +Mejiro Bright +★★★☆☆3/26/2026 - 4/06/2026
+Rerun Zenno Rob Roy SSR and Curren SSR Chan Banner +Zenno Rob Roy Speed SSR and Curren Chan Wit SSR +★★★☆☆3/26/2026 - 4/06/2026
+Satono Diamond Banner +Satono Diamond +★★★☆☆3/22/2026 - 4/02/2026
+Marvelous Sunday and Curren Chan Support Banner +Marvelous Sunday Guts SSR and Curren Chan Speed SR +★★☆☆☆3/22/2026 - 4/02/2026
+Paid Trainee Banner3★ Guaranteed New Year's Scout (Character) +★★★★☆2/05/2026 - 3/25/2026
(One Time Use)
+Paid Support Card BannerSSR Guaranteed New Year's Scout (Support) +★★★★☆2/05/2026 - 3/25/2026
(One Time Use)
+Kitasan Black Matikanetannhauser Banner +Kitasan Black and Matikane Tannhauser +★★★★☆3/12/2026 - 3/23/2026
+Narita Top Road Support Banner +Narita Top Road (Speed SSR) +★★★★☆3/12/2026 - 3/23/2026
+ + Admire Vega +★★★☆☆3/05/2026 - 3/13/2026
+ +Kawakami Princess (Speed SSR) and Fine Motion (Wit SSR) +★★★★☆3/05/2026 - 3/13/2026
+ Mejiro Ardan +★★★☆☆2/25/2026 - 3/05/2026
+ Agnes Digital (SSR Power) and Ines Fujin (SR Wit) +★★☆☆☆2/25/2026 - 3/05/2026
+Valentine Mihono Bourbon and Eishin Flash Valentine Mihono Bourbon and Eishin Flash +★★★★★02/18/2026 - 03/01/2026
+Nishino Flower and Sakura Bakushin O Nishino Flower (SSR Wit) and Sakura Bakushin O (SSR Guts) +★★☆☆☆02/18/2026 - 03/01/2026
+Sakura Chiyono O Sakura Chiyono O +★★★☆☆02/11/2026 - 02/19/2026
+Kashimoto and Tazuna Riko Kashimoto (SSR Pal) and Tazuna Hayakawa (SSR Pal) (Reruns)★★★★★02/11/2026 - 02/19/2026
+Smart Falcon Rerun Smart Falcon (Rerun)★★★★☆02/05/2026 - 02/14/2026
+Sasami Anshinzawa Sasami Ashinzawa (SSR Pal) and Tamamo Cross (SR Guts) +★☆☆☆☆02/05/2026 - 02/14/2026
+Admire Vega and Matikane Fukukitaru Admire Vega (SSR Power) and Matikane Fukukitaru (SSR Speed) +★★★★★01/29/2026 - 02/09/2026
+TM Opera O and Haru Urara New Year New Year Haru Urara and T.M. Opera O +★★★★★01/29/2026 - 02/09/2026
+ Tamamo Cross
Nice Nature (Wit SSR) and Oguri Cap (Power SSR) +
★★★★★1/23/2026 - 1/31/2026
+Fine MotionFine Motion (Noble Seamair) +★★★☆☆1/15/2026 - 1/23/2026
+Manhattan Cafe Card (Cute) Manhattan Cafe and Inari One(Support)★★★☆☆1/15/2026 - 1/23/2026
+Oguri Cap and Biwa HayahideOguri Cap (Ashen Miracle) and Biwa Hayahide (Rogue Caroler) (Character)★★★★★1/5/2026 - 1/20/2026
+Mayano Top Gun and Narita TaishinMayano Top Gun and Narita Taishin (Support)★★★☆☆1/5/2026 - 1/20/2026
+Mejiro Dober Banner Mejiro Dober (Character)★★★★☆12/28/2025 - 1/7/2026
+Daitaku Helios Vodka Banner Daitaku Helios and Vodka (Support)★★☆☆☆12/28/2025 - 1/7/2026
+Tosen Jordan banner Tosen Jordan (Character)★★☆☆☆12/18/2025 - 12/29/2025
+KItasan Black Banner Kitasan Black and El Condor Pasa (Support Card)★★★★★12/18/2025 - 12/29/2025
+Symboli Rudolf Gold City Banner Symboli Rudolf and Gold City (Character)★★☆☆☆12/14/2025 - 12/25/2025
+Curren Chan Narita Brian Banner + Curren Chan and Narita Brian (Support)★★★☆☆12/14/2025 - 12/25/2025
+Manhattan Cafe Banner Manhattan Cafe (Character)★★★☆☆12/9/2025 - 12/16/2025
+Nakayama Festa and Sirius Symboli Banner Nakayama Festa and Sirius Symboli (Support)★★★☆☆12/9/2025 - 12/16/2025
+Kawakami Princess Banner Kawakami Princess (Character)★☆☆☆☆12/1/2025 - 12/10/2025
+Seiun Sky and Yaeno Muteki Banner Seiun Sky and Yaeno Muteki (Support)★★☆☆☆12/1/2025 - 12/10/2025
+Guaranteed SSR Scout 3 Star Guaranteed Half Anniversary (Character) +★★★★☆11/03/2025 - 12/09/2025
(One Time Use)
+Guaranteed 3 Star Scout SSR Guaranteed Half Anniversary (Support) +★★★★☆11/03/2025 - 12/09/2025
(One Time Use)
+Vampire and Mummy Character Banner Rice Shower and Super Creek (Character)★★★☆☆11/24/2025 - 12/6/2025
+Tamamo and Zenno Support Banner Tamamo Cross and Zenno Rob Roy (Support)★★★☆☆11/24/2025 - 12/6/2025
+Ikuno Dictus Support Banner Ikuno Dictus and Fine Motion (Support)★★☆☆☆11/19/2025 - 11/28/2025
+Agnes Digital Trainee Banner Agnes Digital (Character)★★★☆☆11/19/2025 - 11/28/2025
+Biko and Bakushin Spotlight Support ScoutBiko Pegasus and Sakura Bakushin O (Support)★★★☆☆11/11/2025 - 11/21/2025
Hishi Akebono Pretty Derby Scout Hishi Akebono (Character)★★☆☆☆11/11/2025 - 11/21/2025
Riko and Rice Banner Rice Shower and Riko Kashimoto (Support)★★★★★11/06/2025 - 11/17/2025
Matikane Fukukitaru Lucky Tidings Banner Matikane Fukukitaru (Lucky Tidings) (Character)★★☆☆☆11/06/2025 - 11/17/2025
Eishin Flash Banner Eishin Flash (Character)★★★☆☆10/30/2025 - 11/9/2025
Nice Nature SSR Banner Nice Nature and Tosen Jordan (Support)★★★★☆10/30/2025 - 11/9/2025
Meisho Doto BannerMeisho Doto (Character)★★★☆☆10/21/2025 - 10/30/2025
Tokai Teio and Special Week BannerTokai Teio and Special Week (Support)★★☆☆☆10/21/2025 - 10/30/2025
Summer Special Week and MaruzenskySummer Special Week and Maruzensky★★★★★10/14/2025 - 10/27/2025
Sweep Tosho and Winning Ticket BannerSweep Tosho and Winning Ticket★★☆☆☆10/14/2025 - 10/27/2025
Gold City Banner MainGold City (Authentic / 1928)★★★☆☆10/7/2025 - 10/16/2025
Nishino Flower BannerVodka (SSR) and Nishino Flower (SSR)★★☆☆☆10/7/2025 - 10/16/2025
Fuji Kiseki BannerFuji Kiseki (Shooting Star Revue)★★★☆☆10/3/2025 - 10/10/2025
Mejiro Ryan Banner PageMejiro Ryan (SSR) and Mejiro Ardan (SR)★★☆☆☆10/3/2025 - 10/10/2025
+El Condor Pasa and Grass Wonder BannerEl Condor Pasa (Kukulkan Warrior) and Grass Wonder (Saintly Jade Cleric) +★★★☆☆9/21/2025 - 10/4/2025
+Seiun Sky and King Halo SSR CardsSeiun Sky (SSR) and King Halo (SSR) +★★☆☆☆9/21/2025 - 10/4/2025
+Hishi Amazon BannerHishi Amazon +★★★☆☆9/17/2025 - 9/25/2025
+Bamboo Memory and Shinko WindyBamboo Memory and Shinko Windy +★★★★☆9/17/2025 - 9/25/2025
+Seiun Sky BannerSeiun Sky +★★★★★9/7/2025 - 9/18/2025
+Silence Suzuka Tamamo Cross BannerSilence Suzuka and Tamamo Cross +★★★☆☆9/7/2025 - 9/18/2025
Wedding Mayano Top Gun Air Groove BannerMayano Top Gun (Sunlight Bouquet) and Air Groove (Quercus Civilis) +★★★★☆8/28/2025 - 9/10/2025
Kawakami Princess Hishi Akebono BannerKawakami Princess and Hishi Akebono★☆☆☆☆8/28/2025 - 9/10/2025
+Narita Brian BannerNarita Brian +★★★☆☆8/20/2025 - 8/31/2025
+Sakura Chiyono O BannerSakura Chiyono O +★★★☆☆8/20/2025 - 8/31/2025
+Smart FalconSmart Falcon +★★★★☆8/11/2025 - 8/22/2025
+Tazuna and Super Creek RerunTazuna and Super Creek +★★★★★ 8/11/2025 - 8/22/2025
+Narita TaishinNarita Taishin +★★★★☆8/3/2025 - 8/13/2025
+Yaeno MutekiYaeno Muteki +★★★☆☆8/3/2025 - 8/13/2025
Curren Chan
Curren Chan
★★★★★7/27/2025 - 8/7/2025
Yukino Bijin BannerYukino Bijin★★★☆☆7/27/2025 - 8/7/2025
Tokai Teio
Tokai Teio and
Mejiro Mcqueen
★★★☆☆7/16/2025 - 8/1/2025
Kitasan Black
Kitasan Black and Satono Diamond
★★★★★7/16/2025 - 8/1/2025
Biwa Hayahide
Biwa Hayahide
★☆☆☆☆7/10/2025 - 7/22/2025
Mejiro Palmer
Mejiro Palmer
★☆☆☆☆7/10/2025 - 7/22/2025
Mihono BourbonMihono Bourbon ★☆☆☆☆7/2/2025 - 7/10/2025
Twin TurboTwin Turbo★★★☆☆7/2/2025 - 7/10/2025
T.M OperaT.M. Opera O★★★★★6/26/2025 - 7/2/2025
Oguri CapOguri Cap★★★★★6/26/2025 - 7/2/2025
+ +

Although the banners for these characters have ended, they can still be obtained through future banners. However, the chance of obtaining them is lower compared to when they were featured, when their rates were boosted.

+ +

This means that pulling for specific characters becomes more difficult with normal banners because more trainees and support cards are added to the gacha pool.

+

How Can I Determine if I Have Pulled an SSR?

Four Ways to Confirm You Pulled SSR Trainee

+ + + + + + + + + + + + + + + + + +
Rainbow GateChairman Akikawa
Rainbow GateChairman Akikawa
Luxurious DoorGate Message
Luxurious DoorGate Message.png
+ +

There are four different ways to figure out that you've gotten an SSR Trainee when pulling on the Gacha.

+ +
    +
  • When a gate turns into rainbow color.
  • +
  • When Chairman Akikawa appears
  • +
  • When the door behind Tazuna is color red
  • +
  • When the Eclipse first. the rest nowhere message appears at the top of the gates
  • +
+

Gate Messages

+
Gate Message.png
+ + + + + + + + + + + + + + + + + + + + + + +
MessageProbability of 3 StarGate Color
Eclipse first. the rest nowhere.GuaranteedRainbow
Favorite Star.Medium chanceGold to Rainbow
Long-Shot Star.Small chanceSilver to Rainbow
+ +

The message at the top of the gates indicate your chances of getting a 3 Star Trainee during that pull. Eclipse first. the rest nowhere means that you'll get a guaranteed 3 Star Trainee.

+ +

Refer to the table above to see what each of the messages mean when you pull in the gacha.

+

Rainbow Sticky Note for Support Cards

+

Banner
You can quickly see if your pull will have an SSR by looking at the notebook during the pull animation. If you pull a Rainbow Sticker note, you'll get an SSR.

+

Pull Rates

Pull Rates for Umamusume and Support Cards

+ + + + + + + + + + + + + + + + + + + + + +
RarityScout 10 Times (1st-9th Scout)Scout 10 Times (10th Scout)
★★★/SSR3%3%
★★/SR18%97%
★/R79%-
+ +

When you're doing a 10 pull for either an Umamusume or Support Card, the first to ninth result will use the same rate as a single scout while the tenth result of a 10 pull will always guarantee a 3 Star/SR or higher.

+

Umamusume: Pretty Derby Related Guides

+

Umamusume Pretty Derby
Umamusume: Pretty Derby Wiki Front

+

Guides by Category

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Umamusume: Pretty Derby Categories
Umamusume Pretty Derby - Stories StoryCareer Banner.pngCareer Mode
Umamusume Pretty Derby - Races RacesBanners Banners
Characters CharactersUmamusume Tips and Tricks Guides Tips and Tricks
Umamusume Pretty Derby - News NewsSupport Cards Support Cards
Skills SkillsGame Modes.pngGame Modes
Events and Choices Partial Banner Events and ChoicesChampions Meeting Partial Banner Champions Meeting
Items ItemsReview Partial Banner.pngReview
+

Premium Guides

+ + + + +
+Premium Partial Banner +
+Sign up for a free membership or Log in to read these premium articles! +
+ +

List of All Premium Articles

+ + +

Comment

8 Dư Ảnh Của Ký Ức Dư Ảnh Của Ký Ức about 1 month

Cảm ơn rất nhiều về các thông tin mà bạn chia sẻ! Tôi đã tốn 200 lượt gacha để đổi lấy golshi áo tắm và tôi nghĩ đây là sự đầu tư đúng, kỹ năng độc quyền của cô ấy như là Hax vậy, tôi nghĩ cô ấy sẽ luôn là một nhân vật meta với kỹ năng độc quyền đó.

7 Anonymous Anonymous 6 months

is this page not being updated anymore?? it's been almost a month :(

Author

    +

    All rights reserved

    + + +
    Guide Index
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    \ No newline at end of file diff --git a/src/ingest/adapters/index.ts b/src/ingest/adapters/index.ts index 8ac5288..46daa26 100644 --- a/src/ingest/adapters/index.ts +++ b/src/ingest/adapters/index.ts @@ -154,6 +154,21 @@ const SOURCES: SourceSpec[] = [ url: "https://game8.co/games/Chaos-Zero-Nightmare/archives/559899", parserId: "game8", }, + { + id: "uma-game8-events", + game: "uma", + // `uma.moe` stays declined — its API sits behind a Cloudflare Turnstile + // proof header, and an adapter would mean defeating a deliberate access + // control. This is the surface that is simply open. + // + // The stable URL matters here: Game8 also publishes monthly + // `August 2026 Release Schedule` pages whose id changes every month, which + // a static registry cannot follow. "List of All Banners" does not move. + // + // The tenth game8 source, with the same CI blindness as the other nine. + url: "https://game8.co/games/Umamusume-Pretty-Derby/archives/536311", + parserId: "game8", + }, ]; function toAdapter(spec: SourceSpec): Adapter { diff --git a/src/shared/games.ts b/src/shared/games.ts index e03bb73..51ece4b 100644 --- a/src/shared/games.ts +++ b/src/shared/games.ts @@ -135,6 +135,11 @@ export const GAMES: Record = { // No `resetOffsets`: the source is Game8, which states day-precision prose // and no clock at all — the same silence p5x has, and the same answer. czn: { id: "czn", name: "Chaos Zero Nightmare", short: "CZN", hue: "#B84A9C", studio: "Smilegate", dailyTasks: "Daily missions" }, + // No `resetOffsets`. The source's own column is headed `Availability (UTC)`, + // which states the zone the *dates* are in and says nothing about where the + // server's day rolls — and every row on it is a bare date anyway, with no + // time of day to read a reset out of. Same silence as p5x and czn. + uma: { id: "uma", name: "Umamusume: Pretty Derby", short: "Umamusume", hue: "#6FBF44", studio: "Cygames", dailyTasks: "Daily races, missions" }, }; export const GAME_LIST: GameMeta[] = Object.values(GAMES); diff --git a/src/shared/schema.ts b/src/shared/schema.ts index 51b7529..39e6e81 100644 --- a/src/shared/schema.ts +++ b/src/shared/schema.ts @@ -17,6 +17,7 @@ export const GameId = z.enum([ "gfl2", // Girls' Frontline 2: Exilium "stellasora", // Stella Sora "czn", // Chaos Zero Nightmare + "uma", // Umamusume: Pretty Derby ]); export type GameId = z.infer; diff --git a/test/adapters/game8.test.ts b/test/adapters/game8.test.ts index a146a97..852bae5 100644 --- a/test/adapters/game8.test.ts +++ b/test/adapters/game8.test.ts @@ -45,6 +45,7 @@ const CASES: Array<{ adapter: Adapter; fixture: string }> = [ { adapter: adapter("gfl2-iopwiki-events"), fixture: "fixtures/gfl2/iopwiki-events-2026-08-19" }, { adapter: adapter("stellasora-stellasorawiki-events"), fixture: "fixtures/stellasora/stellasorawiki-events-2026-08-19" }, { adapter: adapter("czn-game8-events"), fixture: "fixtures/czn/game8-events-2026-08-19" }, + { adapter: adapter("uma-game8-events"), fixture: "fixtures/uma/game8-events-2026-08-19" }, ]; async function runAdapter(adapter: Adapter, fixture: string) { @@ -1352,6 +1353,39 @@ describe("Chaos Zero Nightmare (game8)", () => { }); }); +describe("Umamusume (game8 banner pages)", () => { + const fixture = "fixtures/uma/game8-events-2026-08-19"; + const uma = adapter("uma-game8-events"); + + test("reads the four current banners, both columns of them", async () => { + // Counted off the page: `All Current Banners` lays Standard and Paid + // banners side by side inside one , two rows each. + const events = await runAdapter(uma, fixture); + expect(events.map((e) => e.title)).toEqual([ + "3 Star Guaranteed 1.5 Anniversary Scout (Character)", + "3 Star Guaranteed 1.5 Anniversary Scout (Support)", + "Daiichi Ruby Power SSR and K.S. Miracle Guts SR", + "Seeking the Pearl (Rocket☆Star)", + ]); + const pearl = events.find((e) => e.title === "Seeking the Pearl (Rocket☆Star)"); + // The page prints "8/12/2026 - 8/21/2026" and no time of day. + expect(pearl?.startsAt).toBe("2026-08-12T00:00:00.000Z"); + expect(pearl?.endsAt).toBe("2026-08-21T00:00:00.000Z"); + expect(pearl?.startPrecision).toBe("day"); + }); + + test("never publishes the Previous Banners table", async () => { + // Dated exactly like the live rows and sitting directly below them, so the + // only thing separating them is the heading. `previous events` does not + // match `Previous Banners` — which is why that pattern was added. + const titles = (await runAdapter(uma, fixture)).map((e) => e.title); + expect(titles).not.toContain("Yukino Bijin (Darl'n Snowflake)"); + expect(titles).not.toContain( + "Smart Falcon Power SSR and Silence Suzuka Speed SSR", + ); + }); +}); + describe("game8 column vocabulary", () => { // The parser directly rather than through an adapter: `canParse` guards the // seam against a redesigned *page*, and these are hand-built table snippets.