diff --git a/CLAUDE.md b/CLAUDE.md index 7e21078..87bdf1f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -99,8 +99,9 @@ These come from how gacha games actually schedule things, and they cause most bu - **Game8 has no single template.** Three shapes are known so far, and a page may mix them: 1. Label/value detail tables (`Event Start` / `Event End`) — Genshin. 2. Column tables (`Event | Duration | Event Details | Rewards`) — NTE. - 3. Image-grid schedules with a bare `MM/DD` and no end — Arknights: Endfield. **Unsupportable**; - yields nothing by design. + 3. Image-grid schedules with a bare `MM/DD` and no end — unsupportable, yields nothing by design. + 4. Combined cells that fold label, range and blurb together + (`Period: 08/09/26 - 08/30/26 During the event...`) — Arknights: Endfield. Before assuming a new Game8 page will work, dump its structure and check which shape it uses. - **Silent drops are the dangerous failure.** A date format the parser does not recognise makes events vanish with no error. Abbreviated months (`Apr. 29 - May 13, 2026`) are supported for diff --git a/README.md b/README.md index 81e614e..38e9db9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ server, database and scheduler are specified but not built. | Piece | State | |---|---| | Event schema, date parsing, Game8 parser | Built, tested | -| Five game sources (Genshin, Star Rail, Wuthering Waves, ZZZ, NTE) | Built, tested | +| Six game sources | Built, tested | | Cross-source merge and conflict detection | Built, tested | | Web interface, offline support | Built | | Bun server, SQLite, refresh scheduler, review queue | Specified in `docs/`, not built | @@ -82,15 +82,16 @@ date makes you miss content. Given the choice, this ships nothing rather than a | Wuthering Waves | Game8 | 10 | | Zenless Zone Zero | Game8 | 12 | | Neverness to Everness | Game8 | 13 | -| Arknights: Endfield | — | No usable source, see below | +| Arknights: Endfield | Game8 | 2 | Game8 uses a different page template for almost every game — label/value detail tables, column tables, rowspan Start/End pairs — and four different date formats between them. One parser handles all of it; each game costs a registry entry. -**Endfield has no adapter on purpose.** Its Game8 page carries no usable dates: every duration reads -"Permanently Available", and the schedule is an image grid showing `07/16` with no year and no end -date. Supporting it would mean inventing both. It needs a different source. +Endfield yields only two events because most of its page genuinely has no dates — every `Duration` +row reads "Permanently Available" and its version grid shows `07/16` with no year. The two dated +events hide in a combined cell (`Period: 08/09/26 - 08/30/26 During the event...`), which is where +the `MM/DD/YY` parser earns its place. Arknights is defined in the schema and awaiting a source. diff --git a/docs/INGESTION.md b/docs/INGESTION.md index d3a58ca..b722982 100644 --- a/docs/INGESTION.md +++ b/docs/INGESTION.md @@ -94,10 +94,13 @@ Game8 uses at least three page templates and a game's page may use any of them: 2. **Column tables** — `Event | Duration | Event Details | Rewards`, one row per event, under a section heading. *(Neverness to Everness)* 3. **Image-grid schedules** — a bare `MM/DD`, no year, no end date. **Unsupportable.** - *(Arknights: Endfield)* +4. **Combined cells** — one cell holding label, range and blurb + (`Period: 08/09/26 - 08/30/26 During the event...`). *(Arknights: Endfield)* -Shapes 1 and 2 are handled. Before assuming a new Game8 page will work, dump its heading/table -structure and check which shape it uses. +Shapes 1, 2 and 4 are handled. Before assuming a new Game8 page will work, dump its heading/table +structure and check which shape it uses — and check **every** table, not just the obvious one. +Endfield was written off as undatable on a first pass that only inspected its `Duration` rows; its +two real events were in a table further down. ## Stage 1 — fetch diff --git a/fixtures/endfield/game8-events-2026-08-14.expected.json b/fixtures/endfield/game8-events-2026-08-14.expected.json new file mode 100644 index 0000000..3828bca --- /dev/null +++ b/fixtures/endfield/game8-events-2026-08-14.expected.json @@ -0,0 +1,44 @@ +[ + { + "id": "endfield:bedazzling-dawnstar-sign-in:2026-08-09", + "game": "endfield", + "title": "Bedazzling Dawnstar Sign-In", + "type": "login", + "summary": "Sign-in to get extra pulls for Liino!", + "startsAt": "2026-08-09T00:00:00.000Z", + "startPrecision": "day", + "endsAt": "2026-08-30T00:00:00.000Z", + "endPrecision": "day", + "regionScoped": false, + "regionEnds": null, + "sourceUrl": "https://game8.co/games/Arknights-Endfield/archives/535443", + "sourceId": "endfield-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": "endfield:the-rooted-realm:2026-08-09", + "game": "endfield", + "title": "The Rooted Realm", + "type": "other", + "summary": "During the event, gather Aurylene Fragments and complete Realm Quests to claim generous rewards.", + "startsAt": "2026-08-09T00:00:00.000Z", + "startPrecision": "day", + "endsAt": "2026-08-30T00:00:00.000Z", + "endPrecision": "day", + "regionScoped": false, + "regionEnds": null, + "sourceUrl": "https://game8.co/games/Arknights-Endfield/archives/535443", + "sourceId": "endfield-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/endfield/game8-events-2026-08-14.html b/fixtures/endfield/game8-events-2026-08-14.html index ceaf216..447d771 100644 --- a/fixtures/endfield/game8-events-2026-08-14.html +++ b/fixtures/endfield/game8-events-2026-08-14.html @@ -3,7 +3,7 @@ window.gon={};gon.rails_env="production";gon.url="https://game8.co/games/Arknights-Endfield/archives/535443";gon.cookie_consent=false;gon.device="pc";gon.is_signed_in=false;gon.beacon_track_path="https://tracking.game8.co/track_access";gon.beacon_click_path="https://tracking.game8.co/track_nier";gon.beacon_load_path="https://tracking.game8.co/track_mario";gon.beacon_event_path="https://tracking.game8.co/track_event";gon.beacon_feedback_path="https://tracking.game8.co/track_feedback";gon.game_id=1405;gon.game_name="Arknights: Endfield";gon.category_ids=[1024,1025];gon.comsumer_game=0;gon.is_sales=false;gon.is_focus=false;gon.game8=1;gon.archive_id=535443;gon.title="All Events and Schedule | Arknights: Endfield|Game8";gon.is_bbs=false;gon.ballots=[];gon.prohibited_words=[];gon.archive_category_id=null; //]]> - +