Skip to content

feat(drawing): resolve palettes for legacy archive entries - #9

Merged
Caeldeth merged 1 commit into
mainfrom
feat/palette-resolver
Jul 29, 2026
Merged

Caeldeth merged 1 commit into
mainfrom
feat/palette-resolver

Conversation

@Caeldeth

Copy link
Copy Markdown
Collaborator

Summary

Ports the palette auto-resolution rules from the palette-resolution specification (document repo, docs/architecture/palette-resolution.md) so downstream tools get a correct default palette instead of the first .pal in archive order.

  • PaletteResolver — instance per open archive; caches every palette source (failed builds included); sibling archives (khanpal.dat, legend.dat) come from an ArchiveProvider callback so no filesystem paths are named; resolve() never throws — null means fall back to the manual picker. Reproduces the setoa.dat field000.pal wart and resolves khan bodies to the lowest palm palette and khan pants to dye index 0.
  • matchPaletteRule — the pure rule-match stage (legend, national, roh, setoa, misc, khan letter remaps, hpf, mpf, tilesets), exported so hosts and tests can assert on the stable ruleId strings the planned C# port must copy.
  • PaletteLookup.getResolvedPaletteForId — additive; reports the real palette number and the luminance-blend flag. getPaletteForId is now a wrapper, behavior unchanged.
  • tests/fixtures/palette-resolution.json — frozen cross-port conformance contract (~90 match cases covering every ladder row and all four ordering hazards) plus gated real-client cases.

Version 3.1.0 (additive), changelog entry, README section.

Test plan

  • 702 tests pass, including 15 gated cases against a real 7.41 client install — these confirmed the stcpal/stspal/mptpal/mpspal table naming, the khan archive wiring, and the spec's open question §8.1 (national.dat/misc.dat resolve via the sibling legend.pal).
  • Coverage with client suites skipped (CI parity): 99.2 / 93.8 / 99.75 / 99.55 — all floors hold.
  • tsc --noEmit and tsup build clean; PaletteResolver smoke-tested from the built bundle.

🤖 Generated with Claude Code

Port the palette auto-resolution rules from the palette-resolution
specification. A legacy .epf/.hpf/.mpf/tileset frame is a grid of
palette indices; these rules find the palette for it.

- PaletteResolver: one instance per open archive. It caches each
  palette source, takes sibling archives from an ArchiveProvider
  callback, and never throws — null sends the host to a manual picker.
  Reproduces the setoa field000.pal wart and the khan body/pants rules.
- matchPaletteRule: the pure rule-match stage over (archive, entry)
  names. It emits stable ruleId strings for the planned C# port.
- PaletteLookup.getResolvedPaletteForId: reports the real palette
  number and the luminance-blend flag; getPaletteForId now wraps it.
- tests/fixtures/palette-resolution.json: the frozen cross-port
  conformance contract, plus gated suites that verified every rule
  family against a real 7.41 client install.

Release chores: version 3.1.0, changelog entry, README section.

Co-Authored-By: Fintan (Claude Opus) <noreply@anthropic.com>
@Caeldeth
Caeldeth merged commit 22cbe99 into main Jul 29, 2026
1 check passed
@Caeldeth
Caeldeth deleted the feat/palette-resolver branch July 29, 2026 03:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant