si-wiki-fetch — Deterministic Spirit Island Wiki parser
Why this exists
Previous attempts to fetch Wiki data via WebFetch (which runs an LLM summarizer over the page) produced hallucinated specifics — wrong costs, wrong speeds, wrong effect text, wrong elements. That data is unreliable.
This skill uses scripts/wiki-fetch.py to hit the MediaWiki API directly, get raw wikitext, and parse the {{PowerCardArticle|...}} / {{Spirit|...}} template fields deterministically. No LLM in the pipeline. No hallucination.
Hard Rules
- Before citing any mechanical detail (card cost, speed, range, target, elements, effect text, innate thresholds, special rules): run this skill.
- Never paraphrase card text in a way that invents mechanics. The parser output is the canonical form; copy it verbatim into chapters.
- If the Wiki page is missing or the template fields are absent: say so explicitly. Flag
[VERIFY physical copy] rather than inventing.
- Cache respected: the script caches under
.wiki-cache/ — re-runs are free. Only use --no-cache if a Wiki page has been updated recently.
- Rate-limiting respected: default 1.5s between requests; exponential backoff on 429/5xx. Don't override
--delay below 1s unless you have a reason.
How to invoke
# Single card
python3 scripts/wiki-fetch.py card "Crops Wither and Fade"
# Single spirit (spirit panel only — innates, special rules, unique-card names)
python3 scripts/wiki-fetch.py spirit "Shadows Flicker Like Flame"
# Spirit + all its Unique cards (most useful for authoring)
python3 scripts/wiki-fetch.py batch-spirit "Shadows Flicker Like Flame" --output-dir data/references/wiki/
# Every spirit in data/spirits.json (takes a while due to rate-limiting)
python3 scripts/wiki-fetch.py batch-all --output-dir data/references/wiki/
Output shape
spirit / batch-spirit output
{
"type": "spirit",
"name": "Shadows Flicker Like Flame",
"expansion": "Base Game",
"complexity": "low",
"special_rules": "SHADOWS OF THE DAHAN ...",
"innates": [
{
"name": "DARKNESS SWALLOWS THE UNWARY",
"speed": "fast",
"range": "1",
"target": "any",
"option": "sacred",
"thresholds": [
{"moon": "2", "fire": "1", "effect": "Gather 1 Explorer."},
...
]
}
],
"unique_cards": ["Concealing Shadows", "Crops Wither and Fade", ...],
"unique_card_details": [ ... ] // only if batch-spirit
}
card output
{
"type": "power_card",
"name": "Crops Wither and Fade",
"spirit": "Shadows Flicker Like Flame",
"card_type": "Unique",
"cost": "1",
"speed": "Slow",
"range": "0",
"target": "Any Land",
"elements": ["moon", "fire", "plant"],
"text": "2 Fear. Replace 1 Town with 1 Explorer. **OR** Replace 1 City with 1 Town.",
"threshold": "No Threshold"
}
Canonical workflow when writing a spirit chapter
- Run:
python3 scripts/wiki-fetch.py batch-spirit "Name" --output-dir data/references/wiki/
- Open the resulting JSON. Copy-paste into the chapter:
- Special Rules section: use
spirit.special_rules.
- Innate Powers section: list each innate with
name, speed, range, target, and each threshold's elements + effect.
- Unique Cards section: for each card in
unique_card_details, write a block with cost, speed, range, target, elements, text.
- Brett's At-a-Glance table: expansion =
spirit.expansion; complexity = spirit.complexity; aspects still need physical-copy verification (the Wiki doesn't surface aspect lists cleanly).
- Strategic-framing prose should be built from the mechanical facts, not in advance of them.
Known limitations
- Aspects list: not yet scraped. Wiki stores aspects on separate pages; the spirit-page template doesn't list them cleanly. Flag aspects with
[VERIFY] until scripted.
- Cost/speed/target when card page lacks a field: the parser reports whatever the Wiki has; missing fields come through as
null / unset.
- Element icons in text: the parser replaces
{{fear}} → "Fear", {{explorer}} → "Explorer", etc. See TOKEN_MAP in the script for the full list.
- Adversaries, scenarios, event cards, fear cards, blight cards: not yet supported — the script currently has parsers for
{{Spirit}} and {{PowerCardArticle}} templates only. Extensions welcome.
When to pull fresh data
- A spirit/card recently had errata → use
--no-cache on that specific page.
- You're writing a chapter for the first time → batch-spirit will cache everything, safe to rerun.
Never use WebFetch for mechanical data
If you find yourself reaching for WebFetch("https://spiritislandwiki.com/..."): stop and use this skill instead. WebFetch runs LLM summarization; that's how the original hallucinations happened.
1---2name: si-wiki-fetch3description: Use when you need authoritative Spirit Island mechanical data (spirits, unique cards, innates, special rules) — NEVER write mechanics from memory or from LLM-summarized WebFetch. This skill invokes `scripts/wiki-fetch.py`, a deterministic MediaWiki-API-based parser that returns exact card text, costs, speeds, elements, and thresholds. Use before authoring or revising any spirit chapter, card reference, or fact-checking a mechanical claim.4---56# si-wiki-fetch — Deterministic Spirit Island Wiki parser78## Why this exists910Previous attempts to fetch Wiki data via WebFetch (which runs an LLM summarizer over the page) produced **hallucinated specifics** — wrong costs, wrong speeds, wrong effect text, wrong elements. That data is unreliable.1112This skill uses `scripts/wiki-fetch.py` to hit the MediaWiki API directly, get raw wikitext, and parse the `{{PowerCardArticle|...}}` / `{{Spirit|...}}` template fields deterministically. No LLM in the pipeline. No hallucination.1314## Hard Rules15161. **Before citing any mechanical detail** (card cost, speed, range, target, elements, effect text, innate thresholds, special rules): run this skill.172. **Never paraphrase card text in a way that invents mechanics.** The parser output is the canonical form; copy it verbatim into chapters.183. **If the Wiki page is missing or the template fields are absent**: say so explicitly. Flag `[VERIFY physical copy]` rather than inventing.194. **Cache respected**: the script caches under `.wiki-cache/` — re-runs are free. Only use `--no-cache` if a Wiki page has been updated recently.205. **Rate-limiting respected**: default 1.5s between requests; exponential backoff on 429/5xx. Don't override `--delay` below 1s unless you have a reason.2122## How to invoke2324```bash25# Single card26python3 scripts/wiki-fetch.py card "Crops Wither and Fade"2728# Single spirit (spirit panel only — innates, special rules, unique-card names)29python3 scripts/wiki-fetch.py spirit "Shadows Flicker Like Flame"3031# Spirit + all its Unique cards (most useful for authoring)32python3 scripts/wiki-fetch.py batch-spirit "Shadows Flicker Like Flame" --output-dir data/references/wiki/3334# Every spirit in data/spirits.json (takes a while due to rate-limiting)35python3 scripts/wiki-fetch.py batch-all --output-dir data/references/wiki/36```3738## Output shape3940### `spirit` / `batch-spirit` output4142```json43{44 "type": "spirit",45 "name": "Shadows Flicker Like Flame",46 "expansion": "Base Game",47 "complexity": "low",48 "special_rules": "SHADOWS OF THE DAHAN ...",49 "innates": [50 {51 "name": "DARKNESS SWALLOWS THE UNWARY",52 "speed": "fast",53 "range": "1",54 "target": "any",55 "option": "sacred",56 "thresholds": [57 {"moon": "2", "fire": "1", "effect": "Gather 1 Explorer."},58 ...59 ]60 }61 ],62 "unique_cards": ["Concealing Shadows", "Crops Wither and Fade", ...],63 "unique_card_details": [ ... ] // only if batch-spirit64}65```6667### `card` output6869```json70{71 "type": "power_card",72 "name": "Crops Wither and Fade",73 "spirit": "Shadows Flicker Like Flame",74 "card_type": "Unique",75 "cost": "1",76 "speed": "Slow",77 "range": "0",78 "target": "Any Land",79 "elements": ["moon", "fire", "plant"],80 "text": "2 Fear. Replace 1 Town with 1 Explorer. **OR** Replace 1 City with 1 Town.",81 "threshold": "No Threshold"82}83```8485## Canonical workflow when writing a spirit chapter86871. Run: `python3 scripts/wiki-fetch.py batch-spirit "Name" --output-dir data/references/wiki/`882. Open the resulting JSON. Copy-paste into the chapter:89 - **Special Rules** section: use `spirit.special_rules`.90 - **Innate Powers** section: list each innate with `name`, `speed`, `range`, `target`, and each threshold's elements + effect.91 - **Unique Cards** section: for each card in `unique_card_details`, write a block with cost, speed, range, target, elements, text.923. Brett's At-a-Glance table: expansion = `spirit.expansion`; complexity = `spirit.complexity`; aspects **still need physical-copy verification** (the Wiki doesn't surface aspect lists cleanly).934. Strategic-framing prose should be built *from* the mechanical facts, not in advance of them.9495## Known limitations9697- **Aspects list**: not yet scraped. Wiki stores aspects on separate pages; the spirit-page template doesn't list them cleanly. Flag aspects with `[VERIFY]` until scripted.98- **Cost/speed/target when card page lacks a field**: the parser reports whatever the Wiki has; missing fields come through as `null` / unset.99- **Element icons in text**: the parser replaces `{{fear}}` → "Fear", `{{explorer}}` → "Explorer", etc. See `TOKEN_MAP` in the script for the full list.100- **Adversaries, scenarios, event cards, fear cards, blight cards**: not yet supported — the script currently has parsers for `{{Spirit}}` and `{{PowerCardArticle}}` templates only. Extensions welcome.101102## When to pull fresh data103104- A spirit/card recently had errata → use `--no-cache` on that specific page.105- You're writing a chapter for the first time → batch-spirit will cache everything, safe to rerun.106107## Never use WebFetch for mechanical data108109If you find yourself reaching for `WebFetch("https://spiritislandwiki.com/...")`: stop and use this skill instead. WebFetch runs LLM summarization; that's how the original hallucinations happened.