10 KiB
10 KiB
Title
Packaged sprimo-tauri sprite rendering breaks after pack switch; default switch errors and
scaling stops applying.
Severity
P1
Environment
- OS: Windows
- App version/build: packaged release (
sprimo-tauri.exe) - Renderer/backend details: Tauri main overlay + settings pop-out
- Evidence screenshots:
issues/screenshots/issue4.pngissues/screenshots/issue4-b.pngissues/screenshots/issue4-c.pngissues/screenshots/issue4-after-fix2-2026-02-14-145819.pngissues/screenshots/issue4-after-fix4-2026-02-14-153233.png
Summary
In packaged runtime, sprite display is incorrectly split/tiled, switching to default can fail,
and scaling becomes ineffective after the error.
Reproduction Steps
- Run packaged
sprimo-tauri.exefrom ZIP extract. - Open settings window.
- Switch character between
ferrisanddefault. - Observe main overlay rendering and debug output.
- Change scale slider.
Expected Result
- Sprite sheet is split into the correct frame grid regardless of image resolution.
- Pack switching works for both
ferrisanddefault. - Scale changes continue to apply after pack changes.
Actual Result
- Main overlay shows incorrectly split/tiled sprite sheet.
- Pack switch can produce runtime error and break subsequent behavior.
- Scale update stops working reliably after the error.
Root Cause Analysis
- Existing splitting logic relied on fixed pixel frame metadata that did not generalize to
packaged
sprite.pngdimension variants. - Pack metadata inconsistency:
assets/sprite-packs/ferris/manifest.jsonused duplicatedid(default), causing pack identity ambiguity.
- Settings/runtime flow then entered an unstable state after pack switch failures.
- Renderer reload lifecycle in tauri UI was unsafe:
PixiPetRenderer::disposeperformed duplicate teardown (ticker.destroy+app.destroy), which could trigger runtimeTypeErrorduring pack reload.- Renderer replacement disposed previous renderer before new renderer creation succeeded, leaving the view in a broken/cropped state on creation failures.
- Chroma-key conversion tolerance removed most
#FF00FFbackground but still left magenta fringe on anti-aliased edges. - Scale fit used repeated position deltas and caused directional drift during repeated resizing.
- API mismatch in tauri window module:
- runtime used
getCurrentWindow().currentMonitor()but this API version exposes monitor lookup as module function (currentMonitor), causingTypeErrorand skipping window fit.
- Scale position math mixed physical window metrics (
outerPosition/innerSize) with logical set operations (LogicalSize/LogicalPosition), reintroducing cumulative drift in some DPI contexts. - Ferris background keying needed adaptive key detection; fixed
#FF00FFassumptions were still too brittle for packaged atlas variants. - Scale-path physical positioning used non-integer coordinates in
setPosition, triggering runtime arg errors (expected i32) and bypassing window fit updates. - Monitor-fit cap remained too optimistic for large frame packs, so max scale could still exceed practical visible bounds and appear clipped.
- Ferris/demogorgon packaged backgrounds are gradient-magenta (not exact
#FF00FF), requiring a border-connected magenta-family mask instead of exact-key assumptions. - Clipping persisted because sprite rendering scale followed snapshot/requested scale directly instead of fitting to the actual post-clamp window size.
Fix Plan
- Introduce generic splitter policy for
sprite.png:
- fixed topology:
8columns x7rows - derive frame size from actual image dimensions
- keep chroma-key background handling (
#FF00FF) in renderer
- Validate animation frame indices against fixed frame count (
56) forsprite.png. - Ensure pack apply path validates atlas geometry before committing
SetSpritePack. - Fix ferris manifest ID uniqueness.
Implementation Notes
Implemented:
crates/sprimo-tauri/src/main.rs
- Added
sprite.png-specific frame derivation (8x7) from PNG dimensions. - Added PNG header dimension decoding utility.
- Added animation frame index validation against fixed
56frames forsprite.png. - Applied validation in both
load_active_sprite_packandset_sprite_pack.
assets/sprite-packs/ferris/manifest.json
- Changed manifest
idfromdefaulttoferris.
docs/SPRITE_PACK_SCHEMA.md
- Documented Tauri
sprite.pngoverride behavior and 8x7 derived frame policy.
frontend/tauri-ui/src/renderer/pixi_pet.ts
- Made renderer disposal idempotent and removed duplicate ticker destruction.
- Delayed DOM canvas replacement until atlas load succeeds.
- Improved chroma-key edge handling with soft alpha + magenta spill suppression.
frontend/tauri-ui/src/main.tsx
- Made pack reload transactional (keep old renderer until new renderer creation succeeds).
- Improved fit-window flow so scale apply continues after reload retries.
- Added targeted diagnostics for reload failures.
frontend/tauri-ui/src/main.tsx
- Changed scaling anchor to window center and clamped resized window position within current monitor bounds.
frontend/tauri-ui/src/renderer/pixi_pet.ts
- Replaced tolerance-only chroma key with border-connected
#FF00FFbackground flood-fill removal and localized edge halo suppression.
crates/sprimo-tauri/capabilities/default.json
- Added
core:window:allow-current-monitorpermission for monitor bounds clamping.
frontend/tauri-ui/src/main.tsx
- switched monitor lookup to module-level
currentMonitor()with safe fallback so window scaling still applies even if monitor introspection is unavailable.
frontend/tauri-ui/src/renderer/pixi_pet.ts
- added fallback global key cleanup when border-connected background detection is too sparse.
frontend/tauri-ui/src/main.tsx
- moved scale resizing and positioning to physical units (
PhysicalSize/PhysicalPosition) and monitor selection at window-center point (monitorFromPoint).
frontend/tauri-ui/src/renderer/pixi_pet.ts
- added adaptive border-derived key color selection with fallback key cleanup pass.
scripts/package_windows.py
- tauri packaging now explicitly rebuilds UI bundle to avoid stale embedded
distoutput.
frontend/tauri-ui/src/main.tsx
- enforced integer physical positioning and monitor work-area size clamping to prevent set-position arg failures and large-scale clipping.
frontend/tauri-ui/src/renderer/pixi_pet.ts
- switched ferris cleanup to hue/saturation/value magenta-band masking with connected background removal and stronger fallback cleanup.
frontend/tauri-ui/src/main.tsx
- added stricter monitor work-area guard (
WINDOW_WORKAREA_MARGIN) in both scale-cap and resize clamp paths to prevent large-pack clipping at high scales.
frontend/tauri-ui/src/renderer/pixi_pet.ts
- added deterministic border-connected strong-magenta flood-fill cleanup pass so non-
#FF00FFgradient backgrounds are removed consistently in packaged ferris/demogorgon atlases.
frontend/tauri-ui/src/main.tsx
- changed scale flow to window-driven fit semantics: scale request resizes/clamps main window and then persists effective scale derived from applied window size.
frontend/tauri-ui/src/renderer/pixi_pet.ts
- renderer sprite scale is now derived from current canvas/window size each layout pass, removing clipping caused by mismatch between requested scale and bounded window dimensions.
Verification
Commands Run
just build-release-taurijust package-win-taurijust smoke-win-tauricargo check -p sprimo-tauri
Visual Checklist
- Before screenshot(s):
issues/screenshots/issue4.png - Before screenshot(s):
issues/screenshots/issue4-b.png - Before screenshot(s):
issues/screenshots/issue4-c.png - After screenshot(s):
issues/screenshots/issue4-after-YYYYMMDD-HHMMSS.png
Result
- Status:
Fix Implemented - Notes: packaged runtime validation and after screenshots for this round are pending.
Status History
2026-02-14 00:00- reporter -Reported- packaged runtime failure screenshots attached.2026-02-14 00:00- codex -Triaged- localized to sprite splitting/pack identity behavior.2026-02-14 00:00- codex -Fix Implemented- applied 8x7 generic splitter policy and pack-ID correction.2026-02-14 00:00- reporter -In Progress- reportedissue4-after-fix1still failing in packaged runtime.2026-02-14 00:00- codex -Fix Implemented- hardened renderer reload/dispose and chroma-key edge cleanup.2026-02-14 00:00- reporter -In Progress- remaining magenta ferris edge + scale drift reported.2026-02-14 00:00- codex -Fix Implemented- switched to border-connected chroma-key removal and center-anchored, monitor-clamped scale fit.2026-02-14 00:00- reporter -In Progress- reportedcurrentMonitorTypeError and ferris magenta background still visible.2026-02-14 00:00- codex -Fix Implemented- corrected monitor API call and added fallback chroma cleanup pass.2026-02-14 00:00- reporter -In Progress- reported ferris magenta background still visible and scale drift recurrence.2026-02-14 00:00- codex -Fix Implemented- switched to physical-unit resize math, adaptive key detection, and packaging UI refresh enforcement.2026-02-14 00:00- reporter -In Progress- reported default clipping, ferris background still present, and set_position float arg error.2026-02-14 00:00- codex -Fix Implemented- added integer-safe physical setPosition and HSV magenta cleanup strategy.2026-02-14 00:00- reporter -In Progress- reported remaining default clipping and ferris magenta background persistence.2026-02-14 00:00- codex -Fix Implemented- tightened work-area scale guard and added border-connected strong-magenta cleanup pass.2026-02-14 00:00- reporter -In Progress- reported clipping still present ondefaultanddemogorgonafter prior fixes.2026-02-14 00:00- codex -Fix Implemented- moved tauri scale to window-driven effective-fit persistence and renderer fit-to-window scaling.
Closure
- Current Status:
Fix Implemented - Close Date:
- Owner:
- Linked PR/commit: