Skip to content

feat(tools): sync SVG masters into TextureStudio for live 3D preview - #209

Merged
BharathASL merged 3 commits into
mainfrom
feat/texture-studio-master-sync
Sep 2, 2026
Merged

feat(tools): sync SVG masters into TextureStudio for live 3D preview#209
BharathASL merged 3 commits into
mainfrom
feat/texture-studio-master-sync

Conversation

@BharathASL

@BharathASL BharathASL commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Description

Adds tools/sync-studio.mjs, which pushes this repository's SVG masters into a local TextureStudio checkout so its WebGL viewport previews what Keyframe actually ships. One-shot by default, --watch to keep going.

#59's acceptance criteria were written against the wrong artifact, and I corrected the issue before implementing. It asked for a watcher "syncing compiled raster textures to TextureStudio assets directory". TextureStudio does not consume rasters there: its textures/ holds SVG masters, src/app.js loadTexture() loads /textures/<name>.svg straight into an Image and draws it to a canvas, and its own compiler tools/build-pack.mjs rasterizes those same SVGs with the same @resvg/resvg-js and the same five tiers as our build.mjs. The Studio's only PNG path is external comparison packs under cache/packs/, fed by dropping a built .zip in — a different feature. Syncing rasters would have handed a compiler its own output and left the real problem untouched. Full evidence, with the running-server output, is in this comment on #59; the criteria in the issue body are rewritten to match.

The drift was real and invisible to both repositories. TextureStudio's dirt.svg still carried the pre-#37 palette, #d98827 / #fcae52, against main's #c77d38 / #deae70 from #198. A dry run measured the whole gap: of 30 masters, 21 were missing from the Studio, 5 had drifted, 4 matched. Neither repo could see it, because the Studio's textures/ is gitignored on its side ("Creative Vector Master Assets (Authored locally)") — which is also why writing into it from here is safe.

Design decisions

  • Flatten by basename. Keyframe namespaces masters (textures/block/dirt.svg); the Studio's discoverActivePack() does one non-recursive readdirSync and expects them flat (textures/dirt.svg). A basename is the Minecraft texture id, so the mapping is lossless — and if two namespaces ever share one, the sync aborts naming both rather than picking a winner. Documented in CONTRIBUTING.md and in the tool's header and --help.
  • The target is validated before any write. --studio <path> beats $KEYFRAME_STUDIO_DIR beats the sibling ../TextureStudio. A path that does not exist, is a file, or lacks tools/server.mjs / tools/build-pack.mjs is a hard error naming the path, where it came from, and the flag that would fix it. The Studio's own textures/ is created if absent — it is gitignored there, so a fresh clone legitimately has none — but only inside a checkout that already passed the marker check.
  • Extras are reported, not deleted. A Studio-only SVG is somebody's local work; --prune opts into removing it.
  • --dry-run reports the plan and writes nothing, so the sync can be inspected before it runs.

Verification, run for real

  • Synced into D:/Projects/Ninja6-MC/TextureStudio: 21 new, 5 updated, 4 unchanged. A second run reports 30 unchanged, so it is idempotent. The Studio's dirt.svg now carries #c77d38.
  • Started the Studio against the synced copy and hit its API: /api/pack returns 24 discovered blocks (was "blocks":[]), and /textures/dirt.svg serves the shipped palette over HTTP.
  • Watch mode: edited a master, watcher reported ~ clay.svg within the debounce window; reverted, it reported the revert.
  • npm run build:512 succeeds — the fatal shared-base gate in tools/build.mjs is untouched and still runs.
  • New suite: 64/64. test:animation, test:palette, test:base-sync all still exit 0.

Nothing is committed to TextureStudio. Only its gitignored textures/ is written, at runtime, when someone runs the tool. git status there shows no change attributable to this PR.

Two findings that need a TextureStudio-side change, and are therefore not fixed here

  1. The Studio's live preview of Keyframe currently shows nothing. tools/server.mjs auto-discovers a sibling ../Keyframe/textures ahead of its own textures/, and scans it non-recursively — our masters are one level deeper, so it finds zero SVGs and the active pack comes back empty. Verified: curl localhost:3000/api/pack"blocks":[]. Until that is fixed, CONTRIBUTING.md documents launching with npm start -- --textures textures.
  2. There is no push channel for a self-refreshing viewport. No websocket, no SSE, no poll; refresh is the 🔄 Reload Textures button. What this PR delivers is that a save reaches the Studio within one watch cycle and the next reload shows it with no restart — the server sends Cache-Control: no-cache and re-reads from disk per request. A viewport that refreshes itself needs code inside TextureStudio. #59's second criterion is rewritten to say that plainly rather than claim it.

Both are reported, not acted on: this session works in Keyframe.

Affected Assets

  • tools/sync-studio.mjs (new), tools/test/sync-studio.test.mjs (new), package.json, .github/workflows/ci.yml, CONTRIBUTING.md. No texture master is modified.

Closes #59


Type of Change

  • feat: New vector texture master, blockstate, or compiler capability
  • fix: Tiling fix, palette correction, or bugfix
  • docs: Documentation improvement
  • chore / refactor: Maintenance, dependencies, or codebase cleanup

Contributor Checklist

Vector Texture Standards (if adding/modifying SVGs)

  • N/A — no SVG master is added or modified by this PR.

Build & Verification

  • Ran npm run build locally and verified that the pack compiles successfully.
  • Verified textures in-game or inspected the rasterized PNG outputs in dist/ — here, verified the masters end to end through TextureStudio's own HTTP API and 3D block discovery.

Git Hygiene & Standards

  • Commit message(s) follow Conventional Commits.
  • Every commit is signed off with the Developer Certificate of Origin (git commit -s).
  • Branch is rebased cleanly onto latest main with no merge commits.
  • Formatting complies with .editorconfig (2-space indent, LF endings, trailing newline).

Note on CI

npm run test:tiling fails for 15 of 30 masters and is advisory (continue-on-error: true) — that is pre-existing debt on main, owned by #206, and no file it reads is touched here. npm test chains it, so npm test exits 1 on main today as well; the four non-tiling suites, including the new one, all exit 0.

The Studio consumes SVG masters, not compiled rasters, so the sync carries
masters and flattens textures/block/ into the flat shape it discovers.

Signed-off-by: Bharath <bharathasl74185@gmail.com>
fs.watch({recursive:true}) is unsupported there and package.json declares
engines.node >= 18, so --watch would have thrown rather than watched.

Signed-off-by: Bharath <bharathasl74185@gmail.com>
@BharathASL
BharathASL force-pushed the feat/texture-studio-master-sync branch from 2cad247 to 3188029 Compare September 2, 2026 04:10
The Node 18 fallback ran on no platform the suite or CI uses. Adds a
watchFn seam, remounts on late directories, and closes on mount failure.

Signed-off-by: Bharath <bharathasl74185@gmail.com>
@BharathASL
BharathASL merged commit 81472f3 into main Sep 2, 2026
4 of 5 checks passed
@BharathASL
BharathASL deleted the feat/texture-studio-master-sync branch September 2, 2026 08:31
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.

Task 1.1.6: TextureStudio Live 3D Preview Integration & Master Sync

1 participant