Skip to content

fix(gui): support directory-format tilemaps - #3770

Open
nighca wants to merge 2 commits into
goplus:devfrom
nighca:codex/tilemap-directory-entry
Open

nighca wants to merge 2 commits into
goplus:devfrom
nighca:codex/tilemap-directory-entry

Conversation

@nighca

@nighca nighca commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

Directory-format SPX maps use a directory as tilemapPath (for example, tilemaps/river), but Builder currently looks up that path as a file and rejects the project. Resolve the directory's tilemap.json, load optional decorator.json with directory-relative image paths, and retain the original directory path and map/resource files for export.

Legacy JSON-file maps keep their existing loading behavior. Resource collection enumerates the file set once, preserving all maps under assets/tilemaps/ for runtime loadTilemap calls as well as resources in a selected directory outside that tree. Format selection follows SPX 4.0.1's .json substring rule, documented with a pinned source link. This change adds no tilemap editing UI, course migration, or engine dependency upgrade.

Validation:

  • 24 tests pass across the tilemap and project suites, including legacy maps, directory maps with/without decorators, resource preservation, missing-map errors, and project export/reload.
  • Full GUI type check, lint, format check, and git diff --check pass.

Refs #3747.

@codecov

codecov Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.07%. Comparing base (fce3f1a) to head (b2e2ceb).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #3770      +/-   ##
==========================================
+ Coverage   59.95%   60.07%   +0.12%     
==========================================
  Files         772      772              
  Lines       27728    27732       +4     
  Branches     5231     5235       +4     
==========================================
+ Hits        16625    16661      +36     
+ Misses       9590     9555      -35     
- Partials     1513     1516       +3     
Flag Coverage Δ
gui 59.55% <100.00%> (+0.12%) ⬆️
tools-ai 79.61% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
gui/src/models/spx/project.ts 55.13% <ø> (+1.17%) ⬆️
gui/src/models/spx/tilemap.ts 77.06% <100.00%> (+25.63%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: directory-format tilemap loading

The change to DumbTilemap.load is focused and well-covered by tests (both formats, the no-decorator directory variant, and the missing-file error path). A couple of points in the resource-collection logic are worth a look before merge, plus two minor nits.

Main point — others unconditionally scans assets/tilemaps/. See the inline comment on the others construction. For a directory-format tilemap that lives outside assets/tilemaps/ (the worlds/river case in the new test), every file under assets/tilemaps/ is still pulled into this tilemap's file set — the test's unrelated assets/tilemaps/other/map.json ends up in the exported files, which expect(exported).toEqual(files) happens to accept only because that stray file is in the fixture. If that cross-tree sweep is intended for back-compat, a one-line comment would help; if not, scanning only resourcesPath removes both this and the double enumeration.

Minor nits (not blocking):

  • gui/src/models/spx/tilemap.ts:328 — decoratorFile is cast to RawTilemapConfig, but for directory format it is decorator.json ({ version, decorators }), which has no tilemap/sprites. Only .decorators is read, so this is harmless, but a narrower type (e.g. Pick<RawTilemapConfig, 'decorators'>) would describe the shape honestly and avoid conflating decorator.json with the full tilemap config.
  • The user-facing tilemapPath field (project.ts:73) now accepts a directory, but that isn't documented anywhere outside the tests. A short note on the field (required tilemap.json, optional decorator.json) would prevent future drift.

Comment thread gui/src/models/spx/tilemap.ts Resolved
Comment thread gui/src/models/spx/tilemap.ts Resolved

This branch was successfully deployed

1 active deployment
Preview – builder — b2e2cebc Deployed Nov 13, 2026 by vercel[bot]
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