v0.27.0
2026-05-20
Module API
- [x]
ArtworkSourceProps.layerId— Forwarded the active map layer ID (e.g.'background','objects','tokens') fromTokenArtworkEditorthrough to module-provided artwork source components. Lets modules adapt behaviour per layer without re-deriving context. Specifically requested by genai v0.5.0 Map Mode, which defaults its "top-down orthographic battlemap" prompt prefix to on for the Background layer. Backwards-compatible: existing sources that don't read the prop are unaffected.
Misc
- [x] On a map with an invalid drawing, multiple issues exist:
- 1: some sort of error boundary should catch the error and simply not render the broken drawing, instead of crashing the whole map — already implemented in
WebGLDrawingLayerviaDrawingErrorBoundary - 2: TokenDebugModal caught the error. But this modal wasn't open, so it shouldn't be rendering. Fixed: added early return in
TokenDebugModalwhenopened=falseto skip row computation entirely (Mantine portals render children even for closed modals).
- 1: some sort of error boundary should catch the error and simply not render the broken drawing, instead of crashing the whole map — already implemented in
- [x] Sort the options in the right-click context menu on the map alphabetically
- [x] In the right-click context menu on the map, add an option to "Add Background". This works the same way as the same option in the + menu in the palette.
- [x] When you press cmd-A on the map (not focused on any text fields), select all tokens on the current layer.
- [x] Bug: in targeting mode, the first time you hover over a token that could potentially be a target, the whole map turns black for a moment. If you hover off then on again, it doesn't recur. Fixed: wrapped TargetingOverlay in React.Suspense — DreiText suspends on first font load, and without a Suspense boundary the suspension bubbled up to the canvas boundary causing the black flash.
- [x] Increase the width of the Source Image Editor by 100%; as it's too cramped currently.
- [x] Bug: if user drags and drops a large image (say 4000x4000) onto the background layer, the background token looks as expected, with LOD generated and high-resolution when zoomed. If they use 'Add Background' or 'Add Token' (then switch to Background layer), then provide the same image (upload, google, doesn't seem to make a difference), the token is created without LOD and is low resolution. Fixed: ImageDropZone in TokenArtworkEditor was hardcoded to category="token" (512px max), so any image dropped there was downscaled before upload. Changed to derive category from layerId: 'token' for the tokens layer, 'mapObject' (4096px max) for all other layers.
- [x] Bug: in the Character Edit page (/characters/:id), in the Artwork editor, the tokenized image thumbnail is never tokenized, regardless of whether the user chose 'tokenize' or 'unchanged'. It always shows the unchanged image. When importing that character into a map, the token on the map and the thumbnail in the character edit page are correct. Fixed:
CharacterDetailnow generates client-side canvas previews viaapplyTransformToCanvasfor artworks withmapAppearance: 'tokenized'and passes them asprocessedUrltoCharacterSheet/CharacterArtworkPanel. The preview is also stored immediately when auto-tokenization runs (onhandleSetTokenArtworkId). - [x] In the Admin / Systems page, the Reload button doesn't refresh the feat/power/equipment lists in the Character Sheet. It should fetch the latest JSON from the server and update the Character Sheet's dropdowns accordingly. Fixed: after a successful reload,
AdminSystemscallsclearSystemCache()(new export fromuseCharacters) andclearFeatCache()(existing export from@purple-cat/shared), then dispatches avtt-system-reloadedwindow event.CharacterDetaillistens for this event and increments asystemRefreshKeythat causes the load-data and load-feats effects to re-run with fresh data. - [x] Left align the text in the Changelog (in Help/About)
Possibly Inter-related Bugs
- [x] Bug: Add Background > genAI > prompt to make a map > image is created > close Source Artwork Editor.
- Expected: source art has been created and assigned as token art, using 'unchanged' instead of 'tokenized'
- Observed: source art has been created, no token art assigned.
- Fixed in v0.27.0:
handleArtworksChangeinTokenModalonly auto-settokenArtworkIdfor thetokenslayer, leaving background-layer art orphaned. Extended the auto-assign branch to background/objects layers (without portrait duplication) and persisttokenArtworkIdimmediately viapatchTokenso it survives modal close/reopen. Background-layer artwork is also coerced toartworkType: 'token-art'withmapAppearance: 'original'.
- [x] Bug: User drags image of a map onto the background layer. As expected, the Edit Token modal appears with that source art. However, the token image is set to 'tokenized'. Background tokens should always default to 'unchanged'.
- Fixed in v0.27.0:
migrateTokenToArtworksnow accepts an optionallayerIdand defaultsmapAppearanceto'original'whenlayerId === 'background'.TokenArtworkEditor.updateArtworkInArray(newArtwork branch) applies the same layer-aware default. Drag-dropped maps now arrive in the modal as Unchanged.
- Fixed in v0.27.0:
- [x] Bug: User creates a background token (any means of providing the image, it's all the same), closes the token modal, and observes the background token is now rendered. They immediately click 'edit token' to reopened the Edit Token modal, whereupon they observe the source art thumbnail and token thumbnail are blank white squares. Source art thumbnail has a ? in it, token thumbnail does not.
- Further actions: click the pencil icon to open the Source Image Editor again. It says "no source image yet".
- Further actions: click the pencil icon to open the Token Artwork Editor. It says "no artwork selected".
- Fixed in v0.27.0: same root cause as Bug 1 — when
tokenArtworkIdwas never set, on reopen the modal could not find the primary art (the artwork persisted withartworkType: 'other'rather than'token-art'), sogetPrimaryTokenArtreturned undefined and thumbnails went blank. Fixing the auto-assign + artworkType coercion inhandleArtworksChangeresolves this downstream. - Re-fixed in v0.27.0 (second pass — first attempt was insufficient): the artwork's
artworkTypeandtokenArtworkIdround-tripped correctly to the server, but the artwork'simageUrlwas being persisted as an empty string. Root cause was inTokenModal.handleSubmit: whenuseOriginalImage === true(always for background tokens), the upload step uploads the original-source URL to S3 and setsfinalImageUrl, butfinalOriginalImageUrlwas never updated from its blob:/data: source. The active-artwork stamping at line ~869 then wroteimageUrl: finalOriginalImageUrl(still blob:), and the strip step at line ~1013 nuked all blob:/data: URLs to''. Fix: whenuseOriginalImageis true, mirror the just-uploadedfinalImageUrlontofinalOriginalImageUrl.
Map and Character Lists
- [x] Add more Sort options to the existing Sort dropdown in the Map and Character lists. Specifically:
- Name A-Z
- Name Z-A
- Recently Created
- Oldest Created
- Recently Updated
- Oldest Updated
- (if we aren't tracking last updated time, add that to the schema and track it)
- [x] Remove "Campaign" sort option on /campaigns/:id as every map on that page belongs to the same campaign.
- [x] When you make a new map from the campaign page, it should automatically open that map in the /play route. With lots of maps, it gets hard to find the new map, and there are sort options that make the new map invisible after creation. This should fix that.
Top-Level Nav
- [x] Partial rollback of recent redesign. To wit:
- Narrow (label-free) top-level nav is once again always visible. Adjust left position of sidebars in map accordingly.
- Mousing over any part of the top nav auto-expands the full width nav. Moving the mouse away collapses it back to the narrow version.
- Fix bug where the purple cat icon wobbles on mouseover. It should never move in any case.