Seven hack notes had filenames whose UTF-8 bytes had been decoded as cp437 and
re-encoded, e.g. "Anil.md" stored as "A" + U+251C + U+2592 + "il.md". Only the
filenames were affected; each note's frontmatter title was already correct.
Repaired by reversing the corruption (name.encode('cp437').decode('utf-8')) and
cross-checking every result against that note's own title field. PokeRogue was
left alone - its U+00E9 cannot be cp437-encoded, proving it is genuine UTF-8 and
not mojibake.
This matters because build-wiki-data.py derives each catalog stem from the
filename and the site derives its URL slug from that. Four published URLs were
wrong and are now fixed:
/hack/a-il/ -> /hack/anil/
/hack/fused-adimensions/ -> /hack/fused-dimensions/
/hack/yu-gi-oh-pok-duel/ -> /hack/yu-gi-oh-pokeduel/
/hack/recharged-yellow-previously-known-as-pok-mon-yellow-cross/
-> ...-as-pokemon-yellow-cross/
The other three were already served correctly, because slugifyStem in the site
repo carries a replaceAll for the mojibake apostrophe. Those URLs are unchanged.
Fallout handled: of 19 vault references, 18 live in files build-vault-mocs.py
regenerates and were fixed by rerunning it. The one hand-written reference, in
Nuzlocke-Friendly (Vanilla+).md, was updated directly. annotate-engines.py also
keyed its ENGINE_MAP on the corrupted stem, so a future run would have silently
skipped Recharged Yellow; that key is corrected here.
Verified: zero mojibake sequences remain anywhere in the vault or this repo, all
seven notes resolve under their new names, catalog steady at 411, and the site
builds 486 pages with banners regenerated under the new slugs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Final 17 summaries from the original list, plus a follow-up sweep of 13 more.
The follow-up covers two variants the first scan's patterns missed but which
break identically on a plain-text <p>: summaries opening with a literal markdown
heading (Blazing Emerald, Ephemerald, Inverse Emerald, Keishou all rendered
"## Details:" on the page) and summaries carrying bare pasted URLs rather than
[label](url) markdown (Solar Platinum's entire summary was "Rom link : <url>").
Also folded in three entries whose summaries used [[wikilinks]] but no bold or
markdown links, so the original query did not surface them: Myth 2, Spaceless
Pearl and Timeless Diamond.
87 summaries rewritten in total. A scan of all 411 for markdown links, bold,
wikilinks, callouts, bullets, headings, bare URLs and raw HTML now returns zero,
and a scan of the 411 built pages' rendered Summary paragraphs is likewise clean.
No links were lost: every URL in a rewritten summary was verified present in
that note's ## Links section first. The check caught one real edge case, a URL
written as [Download Here](<url>) whose trailing ">" made it look absent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
19 more summaries rewritten as plain prose.
This batch includes the curated summaries written in earlier sessions, which
were affected too: Soulgold, Soulstones, Soulstones 2, Recharged Emerald and
Recharged Emerald Rebalanced all used `**bold**` and `[[wikilinks]]` that the
site printed literally. Soulstones and Soulstones 2 additionally carried an
Obsidian `> [!warning]` callout inside Summary; the content warning is kept as
a closing sentence of prose instead.
No links were lost: every URL in a rewritten summary was verified present in
that note's ## Links section first.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
19 more summaries rewritten as plain prose for the same reason as batch 1.
This batch was heavy on scrape artefacts: bare source-website links (Hyper
Emerald, Explorers of Fortune, Nebula 3, Radiant Topaz), `**Creator:**` metadata
headers (MasterSilver WoofGold), and feature-list dumps pasted in place of a
description (Insurgence, Nebula 1, Pefect Emerald). Each was replaced with a
real description drawn from the note's own Features/Story sections.
No links were lost: every URL in a rewritten summary was verified present in
that note's ## Links section first.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The site renders `summary` as plain text in a single <p> (ContentSection.astro,
HackCard.astro), so markdown emphasis, [label](url) links, [[wikilinks]] and
Obsidian callouts all render literally. Rewrites 19 summaries as clean prose.
Several were not descriptions at all but scrape artefacts - bare
`[Source Website](url)` links, `**Creator:** X **Type:** Y **Last Updated:** Z`
metadata headers, or a Spanish-language listing dump (Delta Fusion). Those were
rewritten into real one-or-two sentence descriptions sourced from each note's
own Features/Story sections. Warnings preserved as prose rather than dropped
(Clover's save-deletion note, Eternal X's Lumiose save glitch).
No links were lost: every URL appearing in a rewritten summary was verified to
already exist in that note's ## Links section before the summary was replaced.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Rutile Ruby entry's version was `](https://1fichier.com/?04mmg2` - a
fragment of a markdown download link. Root cause: an enrichment pass grabbed
the 30 characters following the word "version" in the scraped description,
regardless of context, so `[build Legit version](url)` and prose like "the
randomized version of the original Moon Emerald" both landed in the field.
Ten more entries were hit the same way; all were found by scanning for version
values containing URLs, brackets, leading punctuation, or >28 chars.
Recovered from evidence (official page, download filenames, or the original
untruncated scrape description in .scrape/<dir>/metadata.json):
Rutile Ruby & Star Sapphire -> 2.2 (site "Current Version: v2.2"; all
three builds ship as ...v2d2...)
Clover -> 1.3.3 (library file Clover v1.3.3.gba)
Legends - Kingdom Hearts -> 3.5 (scrape: "Latest update is Version 3.5")
Space World Crystal -> 4.2 (download ...Crystal+v4.2.zip)
TCG Neo -> 1.33 (all six downloads ...version+v1.33.zip)
Techno Emerald -> 2.0.6 (download ...Techno+Emerald+(v2.0.6)
Set to the schema's unknown marker "-" where no version is stated anywhere and
the captured text was describing the BASE game, not the hack: Moon Emerald
Extreme Randomizer, Photonic Sun & Prismatic Moon, Quetzal, Supernova Sun &
Penumbra Moon, X & Y Disruption.
Rutile Ruby's three 1fichier links (all verified live) were relabelled to the
official build names - 679 Build / Legit Build / Leveled Build - replacing the
garbled scrape labels that caused the corruption, and a stray affiliate
parameter was dropped. Labels avoid parentheses, which the exporter's
`[\w /]+` label regex would silently turn into an empty label.
Edits were surgical (frontmatter line + the `version **X**` callout token)
rather than via enrich_web.py, which regenerates the callout from a template
and would have stripped the engine/roster/Fakemon tokens other passes added.
Catalog stays at 411 with identical platform/type/status counts, so Playwright
fixtures are unchanged. Verified: astro check 0 errors, vitest 9/9, build 486
pages, CI=1 test:ui 8/8, deployed; live 200 with "Version 2.2" on
/hack/rutile-ruby-star-sapphire/ and a clean re-run of the corruption scan.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both entries updated in place; catalog stays at 411 (no fixture changes).
- Soulgold - v1.0.3 -> v1.0.4.2 (released 2026-08-13). Adds the v1.0.1-v1.0.4
patch notes to the note, extends the QoL bullet (rename traded Pokemon, swap
a Pokemon's Poke Ball), and links the project page, docs, and expansion port.
- Z - was catalogued as v2.17 while the library actually held the Spanish v2.16
build. Now tracks the English v2.13 build, the newest playable-in-English
release (ES v2.18 / EN v2.13 / FR v2.12+P1 as of today). Scrape-dump summary
replaced with prose plus a per-language version matrix.
Both ROMs placed on valhalla and rehashed in RomM (13359 gba, 13296 windows,
files=1, not missing). Superseded builds archived under
/storage1/igir/romhacks/incoming/_done/_superseded-2026-08-14/.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Catalog 407 -> 411.
- Soulgold (rahtak) - GBA/Emerald on pokeemerald-expansion, Complete v1.0.3,
Johto-focused expansion built on an unofficial expansion port of Heart and Soul.
- Unchosen (Aldrine) - PC tactical RPG on RPG Maker MV + LeTBS, Complete v1.5.8,
ENG/FRA with local co-op. Introduces a new `RPG Maker MV` base value.
- Soulstones (Jos_Louis) - PC/Essentials v17.2, Complete v2.0.5, Gen I-VII plus
200+ custom regional variants.
- Soulstones 2: Time Wardens (Jos_Louis + team) - PC/Essentials v20.1,
Complete v2.05, 1100+ regional variants and no canon forms.
All four placed in RomM (gba 13359; windows 13360-13362, each files=1).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Soulstones 1 ships `Game-z.exe` rather than `Game.exe`. Find-GameExe preferred
`Game.exe` and otherwise fell back to the shallowest non-ignored .exe, which for
that build resolved to `extendtext.exe` — a dev tool that was missing from the
ignore list — instead of the real launcher.
Add extendtext.exe to $ignore and replace the single-name preference with a
$launcherNames list (Game.exe, then Game-z.exe) before the shallowest-exe
fallback.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Catalog 404 -> 405. Vesly's completed FE8 tactical reimagining of Kanto/Gen 1,
placed in RomM as roms/gba/Pokemblem [Hack].gba. First non-Pokémon-engine base
in the catalog; tagged New Experience + Crossover.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Catalog 399 -> 404. New: Pokémon Hidden Place (Essentials PC, MexaJ) and
Crippling Medical Debt Edition (Emerald/GBA, GMars) placed in RomM; plus
watchlist pages for Grimm, Conviction, and Miragea's Traveler (no download).
Crystal Inheritance restored to its shipped v1.0.3 Complete entry.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ingested from Downloads: catalog now 399 hacks (PC 79). Nova placed in
RomM as roms/windows/Pokemon - Nova [Hack].zip (rom id 13345).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment out a broken here-string fragment in the PC hack setup instructions, and refresh wiki/catalog.json with Pokémon Omniversal Emerald plus updated facet counts.
Adds standardize-vault-pages pipeline, exports intentional empty generations, and refreshes the 396-hack catalog with full banner coverage, status classification, and Fakemon generation tags.
Catalog cleanup pass across gb/gbc/gba/nds/3ds:
- Standardize nonstandard hack filenames to `Pokemon - <Name> [Hack].<ext>`;
remove verified byte-identical duplicates (conform-rom-names.sh).
- Resolve 9 version-conflicts via side-by-side emulator comparison
(resolve-version-conflicts.sh): promote newer builds, keep genuine
distinct hacks, fix a mislabeled Dark Rising slot (was the Digimon
crossover "Worlds Collide"), and rebuild Mega Power 5.77 + HeartGold
Generations v2.0 fresh from their patches.
- Resync 286 vault notes' `library_path` to the real on-disk [Hack] files
and fix 15 stale platform fields (resync-vault-library-paths.py).
- Regenerate MOC tables + wiki/catalog.json (396 notes).
Also includes pending Playnite PC-hack setup/repair scripts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Switch the library naming convention from "Pokemon - <Name> (Hack)" to
"Pokemon - <Name> [Hack][version][tags]", and place hacks in the platform
root (roms/<plat>/) instead of a Hacks/ subfolder. Applied across the live
valhalla library (272 hack/fan-game files) via scripts/standardize-names.py.
- romhack-import.py / romhack-fetch.py: emit [Hack], write to roms/<plat>/
- romhack-pc-migrate.py: emit [Hack]
- build-romhack-vault.py (archived): update documented library_path
- standardize-names.py: new one-shot, self-fetching standardizer (idempotent;
pipes \n-only bytes over SSH to avoid Windows CRLF corrupting filenames)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds list-import tooling, expands romhack-import for PC variants and patch batches, and syncs catalog with 2026-06-23 valhalla placements (Vanguard, Xenoverse, GBA patches, Infinity 3.3.1).
Add engine annotation + MOC/wiki export support, a PC import staging helper, and refresh catalog.json after placing gated fan-games and new hack notes.
Enrich the Obsidian ROM-hack vault from the valhalla Discord scrape
(/storage1/labdata/romhacks/metadata) plus web research, growing the catalog
from 285 to 368 notes and preparing a data export for a wiki site.
Tooling (all dry-run by default, --apply to write; .scrape/ is gitignored):
- scrape_match.py reconcile scrape entries vs notes (43 overlap / 211 match / 83 new)
- enrich_vault.py backfill frontmatter, merge scrape into curated notes,
create 83 new notes, rebuild import bodies to one layout
- enrich_web.py apply hand/web-verified facts from .scrape/web_facts*.json
- build-wiki-data.py export wiki/catalog.json (the site data source)
Results: 368 notes, 327 with served banner art, 332 rich summaries, 200 with
feature lists; new frontmatter developer/release_date/banner/homepage/scrape_dir;
12 flagship hacks web-verified. wiki/SPEC.md describes the site build.
build-vault-mocs.py Index callout updated for the new counts.
Reads Pokémon ROM Hacks/Hacks/*.md as source of truth and rewrites the
static mirror tables + header counts in Index.md, Platforms/*.md, and
Bases/*.md. Dataview blocks, prose intros, and footers are preserved;
the notes themselves are never edited (curated type/rating/version safe).
Covers all 285 hacks; creates Platforms/{3DS,PC,Patch,Unknown}.md.
Supersedes the archived build-romhack-vault.py (a hardcoded 75-hack
bootstrap that would regress the live vault).
Per the standing rule that Obsidian notes belong in the self-hosted vault, not
in project folders:
- rm pokemon-romhack-vault/ (redundant generated snapshot; the canonical,
richer catalog lives in the vault under Pokémon ROM Hacks/)
- pokemon-romhacks-wanted.md -> moved into the vault as Pokémon ROM Hacks/Wanted.md
- .gitignore: ignore pokemon-romhack-vault/ (build script output) so a poorer
regenerated copy can never be committed back
- build-romhack-vault.py: marked ARCHIVED; vault is now hand-maintained via MCP
- README: rewritten to point at the vault for the catalog
Curated knowledge base + pipeline for the valhalla Pokémon ROM-hack
collection, moved out of the homelabstack infra repo on 2026-06-06 so that
repo stays focused on the homelab.
- pokemon-romhack-vault/ Obsidian vault: 75 hack notes + Index/Types/Platform MOCs (generated by build-romhack-vault.py)
- scripts/ build-romhack-vault, romhack-import/fetch/apply
- pokemon-romhacks-wanted.md manual-acquisition list (gated hacks)
- drop/ gitignored ~1.3GB binary staging area
The ROMs live on valhalla (/storage1/Emulation) served by the RomM stack,
which stays in homelabstack (stacks/roms).