Add GET /trace which fetches an image, traces it into a vector shape, and returns the result BSON-encoded. Tracing is configurable via mode (alpha, bw, color) and format (shape, svg). The shape format parses the vtracer SVG into an outline/holes polygon matching @tts/mesh's Shape interface.
Replace the per-shape tile geometries with @tts/mesh extrusion, honoring
the tile type and stretch aspect ratio. Add extrudeShapeParts so the
caps carry the texture while the walls are solid white, matching TTS
tinting. Fix bottom-face UVs to mirror horizontally and make wall UVs
inherit the front mapping independent of z.
Detect the model format from file contents instead of the URL extension,
since TTS model URLs are often extension-less. Move the diffuse texture
hook into a child component so the hook count stays consistent across
renders.
Move useTexture calls in the tile, token, and card viewers into child
components rendered inside the Canvas. R3F hooks must run within the
Canvas store, so calling them at the viewer's top level threw a runtime
error.
Wrap the resolved viewer in an error boundary so a render failure (e.g.
WebGL context loss or a model/texture load error) is contained to the
inspector pane instead of crashing the page. The fallback shows the
error message and stack trace.
Add per-class 3D viewers for tiles, tokens, cards, and custom models
using React Three Fiber, drei, and postprocessing. Viewers are
lazy-loaded and registered through the existing viewer registry, with a
shared scene wrapper for lighting, orbit controls, and subtle effects.
Add a CORS-safe /asset proxy route so three.js loaders can fetch
Workshop-hosted textures and models, and extend TTSObject with the
CustomMesh and CustomTile/CustomToken fields the viewers read.
Replace the text class tag in the tree and inspector with one or more
MDI icons (hover shows the class name). Bundle only the used icons via
a generator script instead of the full set.
Key tree nodes by their index path instead of GUID, since TTS saves can
contain duplicate GUIDs. Skip the Parent back-reference in the default
viewer and stringify with a circular-reference guard.
Add a containment-tree sidebar with class tags and display labels, plus
an inspector pane backed by a viewer registry with a default viewer.
Custom per-class viewers can be registered later.
Add fetchModFromUrl/fetchModFileFromUrl and accept a fileUrl query param on /items routes so the frontend can download saves directly from a search result's file_url, with no key required.
Add apps/web (Vite + React Router + Tailwind v4 + Zustand) with a search page and a mod page that analyzes saves via @tts/extract. Document the frontend in the README and docs.