Releases: DimitroffVodka/shadowdark-extras
Release list
v6.15.0
[6.15.0] — 2026-09-15 — Lit lights change hands properly, Torch Sprite fixes, sprite windows fit the screen
Fixed
- Giving someone a lit light now gives them the light. Transfer to Player moved a lit torch or lantern into the other character's inventory but left the light itself behind. The giver kept a light they could not put out, the receiver's item showed as lit but cast nothing, and the torch sprite stayed on the giver. Now the light, its sprite and the light tracker entry all move with the item. The receiver's own light goes out, since a character carries one, and the item keeps its remaining burn time. Giving away part of a lit stack sends unlit ones. (#138)
- A lit light picked up off the scene shows its torch sprite again. The character got the light back but no sprite.
- The Torch Sprite dialog keeps the flame on the torch. Moving or resizing the prop left the flame where it was; now the flame moves and scales with it. If the flame is near the edge of its own range, the prop slider stops where the flame would have to go past its limit. A torch whose prop was already moved keeps its old flame position until you touch a flame slider or press Reset.
- Sprite settings windows fit on smaller screens. The Equipped Sprite and Torch Sprite windows now scroll and can be resized, and Save and Cancel stay visible even with the weapon image browser open. (#137)
- Momentum no longer explodes a die twice. With world-wide Momentum on, a formula whose first die had a calculated face, like
1d(6+2) + 1d6, skipped the first die and exploded the second one twice, which inflated damage. (#134) - Ctrl in the Dungeons tab reaches Int. Walls. Ctrl now cycles through Rooms, Doors and Int. Walls, as the tab's hint says. Before, it only switched between Rooms and Doors, and holding it down spun through the modes.
v6.14.0
[6.14.0] — 2026-09-14 — Journal Pins hover leak fix, dungeon reskin and floor tools, per-item Torch Sprites, usable gear
Fixed
- Journal Pins no longer slow the canvas down the more pins you hover. Moving the mouse off a pin attached an invisible colour filter to it that was never removed, so every pin hovered during a session kept costing render time until a reload. Pins now shed that filter as soon as their hover animation settles, and the flash ping does the same. Reported on Discord by Panicked Spathi.
Added
- Dungeon reskin and floor tools. The Dungeons tab can reskin an existing map with SDX assets: floors are traced from the scene's walls (one polygon per room, edge-exact at any angle, doors decide what counts as a room), with Show Wall Gaps marking every loose wall end so a failed trace can be repaired. Paint Floor is a bucket that retextures one room per click; Erase Floor is a bucket on click and a freehand brush on drag, both bounded by the walls. Undo and collapsible tile sections round out the tab. Still being refined — feedback welcome.
- Per-item Torch Sprites. Light-source items get a sheet button and dialog to set the prop image, prop scale and offsets, and flame scale, offsets and rotation, with a live preview box showing the token, prop and the actual looping flame. Stored per item, so torches and lanterns can look different.
- Usable gear. Basic items can be given an activation: a use control on the inventory row, an optional charge count, and a chat card shaped like a potion's, so the Activity tab's damage, effects, summoning, item-give and macros all work on a ring or a wand without a roll and without the item being consumed.
- Momentum now reaches every damage die. The Weapon Bonuses tab has a new Exploding damage dice (Momentum) toggle for custom exploding weapons even when the world setting is off. It covers base damage, configured bonuses, and critical extra dice independently of Enable Weapon Bonuses. With world-wide Momentum enabled, SDX fills in the later dice terms missed by stock Shadowdark 4.0.6 and automatically stands down when the system provides the complete transform itself. (#134)
v6.13.0
[6.13.0] — 2026-08-29 — Item-level FX editing, dependable sprite previews, and natural animation timing
Added
- Weapon and Spell sheets now open their own Attack FX editor directly. Each button is tied to the exact item whose sheet opened it, so several Weapon or Spell sheets can remain open without one editor changing another item. The editor preserves master-preset inheritance, shows the installed JB2A colour variants, and offers optional Sequencer tint, contrast, and saturation controls without requiring Automated Animations. Native JB2A colours remain the default.
- Equipped Sprites now have explicit inherited, custom, and disabled states. Opening the editor shows the effective master values instead of an empty form, editing an inherited setup creates an item override, and Use Master Preset removes that override and resumes inheritance. Turning a custom sprite off keeps its image and transform/filter settings so turning it back on restores the same setup.
Changed
- Bundled Spell, Weapon, and NPC Attack FX now use each animation's natural media length.
0means Auto; a positive duration remains an explicit override. A selective, versioned migration updates only entries whose file and duration still match the former bundled defaults, including Generic Melee's shipped 1000 ms value. Custom files and custom durations are left alone. - On-token previews now visibly honour Anchor → Caster or Target. Target uses a targeted or second controlled token when one exists and safely falls back to the caster rather than empty canvas. Projectile and cone effects continue to use their fixed caster-to-target geometry instead of presenting Anchor as though it changed their path.
- Weapon Animation is now labelled Equipped Sprite wherever the persistent token attachment is configured, keeping it distinct from transient Attack FX.
- Equipped Sprites render above scene lighting. They now retain the same colour, contrast, transparency, and line detail shown by the editor instead of being washed out by the active scene ambience.
Fixed
- Unsaved Equipped Sprite previews are responsive, local, and cleanup-safe. Changes are debounced at 75 ms and use a client-local temporary Sequencer effect rather than replacing the canonical persistent sprite. Save, Cancel, Use Master Preset, and the title-bar close button remove the temporary preview, restore the saved scene effect, and do not persist discarded form changes.
- CSS-style Equipped Sprite colour controls now translate correctly to Sequencer/PIXI. In particular, the editor's neutral contrast value of
1maps to Sequencer's neutral value of0, so saved scene sprites match the preview instead of appearing cyan-white or over-contrasted. - Repeated item-sheet rendering no longer risks stacked visual-control handlers. Attack FX, Spell FX, and Equipped Sprite bindings are UUID-scoped and idempotent, while disabled features remain absent from the sheet.
- Attack and Spell FX dialogs now localize their Close button in English and Brazilian Portuguese.
v6.12.2
[6.12.2] — 2026-08-29 — Empty shipped-asset scans self-heal
Fixed
- An empty shipped-asset scan no longer stays empty until the next release. A successful scan that found no files was cached as authoritative, so a partially installed module could leave the hex painter with no tiles and no reason to scan again. The dungeon path was broader: it turns a failed folder browse into an empty array before writing the combined catalogue, so one unavailable floor, wall, door, or background folder could make that partial result sticky too. Empty flat catalogues and dungeon catalogues missing any shipped category are no longer persisted; the next load retries the real folders.
v6.12.0
[6.12.0] — 2026-08-18 — Grouped placeable-note tray, player summon & initiative permissions, the summon lifecycle, and a Foundry 14 baseline
Added
- Placeable Notes now have a grouped tray view. Notes are collected into fixed Tokens, Actors, Tiles, Drawings, Walls, Lights, Sounds, and Regions groups with viewer-safe counts and natural sorting. Token and Actor notes remain separate exact sources, and group/row expansion state lasts for the tray session. Drawing/Region labels use native text or names before coordinate fallbacks, and lifetime-owned transient/rebuild sources remain excluded.
- A summon spell can now ask which creature to conjure. Listing several creatures on a summon spell has always summoned all of them, which is right for a spell that calls a pack — but not for one written as a choice. Shadowdark's Undeath reads "it rises as a zombie or skeleton", and "you can only create one undead creature with this spell at a time"; configured with both, it summoned both. A new option on the summoning panel, When several are listed → Ask which one, prompts the caster and summons only what they pick. The default is unchanged, so spells that mean to summon a group still do. Cancelling the prompt summons nothing, rather than falling back to summoning everything.
- Summoned creatures join the encounter on their summoner's initiative. "The creature acts on your turn" is the usual shape for a summon, but the tokens simply appeared on the canvas and the GM had to add them to the tracker by hand, guessing where in the round they belonged. They are now added as combatants sharing the caster's initiative value — not a fresh roll, which would scatter them across the round. Re-casting will not produce a duplicate that acts twice, and a caster who is not in the encounter adds nothing, since there is no initiative to share. Controlled by Join combat on caster's initiative, on by default; uncheck it for summons that should roll their own.
- Summon durations now run outside combat. A duration written in rounds only means something while rounds are being counted, so a creature summoned outside an encounter was never tracked and stayed forever — and one summoned during a fight that then ended kept waiting on a round counter that would never advance again. Durations now fall back to world time when no encounter is running, at your world's own seconds-per-round, and ending a combat re-bases whatever rounds were still owed onto world time. A spell with two rounds left keeps two rounds' worth of time instead of becoming permanent.
Changed
- Foundry VTT 14 is now the minimum supported version.
- Add Pin and Pin List moved into the Pins tab. The two redundant launchers on the tray handle are gone; Add Pin now lives in the Pins toolbar and Pins remains reachable through its own tab. Persisted feature IDs are unchanged, so nothing you had configured is affected.
- The tray's Scenes tab is now labelled ToM. A label-only rename — every persisted key, view mode, action, CSS class, and setting name is untouched.
Fixed
- Journal Pins: access, opening, and privacy now agree with each other. Players could not open journals they owned from a canvas pin, pins converted from notes were exposed to players by default, the sidebar's double-click opened the wrong entry, and GM-only status overlays (the eye, slash, red tint, and forced dashed ring) leaked pin state into the player view. Opening now routes through one centralized access policy that resolves the exact permitted entry and page; converted pins default to GM-only; the status overlays are removed while configured rings and their enforcement stay; and pin lists sort naturally, so
Room 2precedesRoom 10in both list paths. - The PinStyleEditor's controls now match what they render. An audit of all 69 unique option names across the editor's 70 rendered controls found several places where the live preview and the actual pin renderer disagreed; those divergences are fixed so the preview is trustworthy. The editor can also be resized vertically again — local
80vh/70vhcaps were overriding the window's own sizing, and oversized requests remain clamped to the viewport with content scrolling. - Dungeon tiles no longer persist from a previous generation. The painter's tile cache survived across generations, so a regenerated dungeon could reuse tiles from the map before it.
- Curved Walls now shows its selected state. The option rendered identically whether or not it was active.
- A weapon bonus "vs Undead" never applied. Shadowdark 4.x stores
PlayerSD.ancestryas a document UUID, but the requirement check read.nameoff it, so every ancestry comparison ran against an empty string and silently failed — and the field's placeholder ("e.g., Undead, Humanoid") steered people straight into the dead path. Ancestry now resolves from all three stored shapes: a 4.x UUID, a bare name, or a pre-4.x object. NPCs still resolve to empty, which is correct — they have no ancestry — and the placeholder now reads "e.g., Dwarf, Elf, Human" with the reference panel noting the requirement applies to players only. The separate creature-type requirement is relabelled "Target Creature Type" and takes a dropdown of the configured types instead of free text that had to match exactly; its persisted key is unchanged. - Versatile handedness and equipped indicators were invisible on the enhanced tabs. The inventory and spells tabs painted every icon in the row white with
!important, which outranked the inline colour the system uses to signal state — so the handedness fist and the equipped shield looked identical in both states, even though switching to two-handed did correctly change the damage die. Icons that declare no colour still inherit white; tinted ones keep their tint, re-pointed to the accent colour already used elsewhere on these tabs so they read against the dark background. - Placeable-note actions and lifecycle updates are now exact and resilient. Edit, rename, sharing, delete, and pan actions target the exact source document, enforce GM and active-scene checks, and refresh safely across document lifecycle changes and overlapping asynchronous renders. A failed note enrichment no longer removes sibling rows or exposes rejection details. Drawing and Region lifecycle updates now apply label-aware differential refreshes while preserving live-center pan and explicit player sharing.
- The system's apply-damage buttons stayed live after SDX had already applied the damage. Shadowdark's roll card carries its own pair of apply-damage buttons, and SDX injects its damage card into that same chat message — so once SDX applied the damage, whether automatically or from its own APPLY DAMAGE button, those buttons still read as unused and clicking one applied the same damage a second time. The system does not fade a button on click:
ChatMessageSDsetsflags.shadowdark.damageAppliedand re-adds the faded state from that flag on every later render, so the only way to reproduce the fade is to write the flag the system reads. SDX now sets it alongside its own applied flag, which also hands the double-apply guard back to the system — a stray click raises its reapply confirmation instead of silently landing damage twice. Verified live on Foundry 14.365 / Shadowdark 4.0.6, for both GM- and player-authored attacks. - Players saw no weapon art, and lost the animation controls with it. The weapon-animation picker discovered its art by walking the assets folder with
FilePicker.browse, which needs theFILES_BROWSEpermission — not granted to the Player role by default. Every browse was rejected, the scan came back empty, and the dialog reported "No weapon images found in assets/Weapons folder": a statement about the folder for what was really a permission failure. The folder was never the problem. Worse, the offset, scale, rotation and animation-effect controls sit inside the same conditional, so a player lost the entire General tab, not just the image list. The bundled art now ships as a generated manifest and is read as a static file, which needs no permission — the same 786 images, and the full control panel, are available to every role. Art from Forgotten Adventures Nexus is another module's and still requires browsing, so it remains GM-only in practice. - Chat messages from a deleted player crashed the damage card on every render.
ChatMessage#authorresolves the stored author id against the user list and comes back null once that user no longer exists — routine in a long-running game, where removing a player leaves their messages behind. The damage-card pipeline read.idoff it directly and threw, repeatedly, for every affected message. Five separate authorship checks had the same unguarded read; the first one crashed early enough to hide the other four. The error also never reached the module's own log, because the hook wrapped an async call in a synchronoustry/catch, which cannot observe a rejected promise — the identical hazard was already documented and fixed for the neighbouring weapon-bonus call. An author that cannot be resolved is simply not the current user, so those checks now answer "no" instead of throwing, and the rejection is handled on the promise. - Casting a summon spell did nothing at all. No creature, no card, no error — the spell simply had no effect, however carefully it was configured. The summoning panel stores its creature list as JSON text, but every consumer checked that list with a test that only recognised an array or an object, so the text form read as "no creatures configured" and the whole summoning step was skipped. The code behind that check already understood the text form; the check in front of it just never let anything reach it. The list is now read in one place that accepts every shape it has been stored in, and the same broken check appeared in the NPC-feature summoning p...
v6.11.0
[6.11.0] — 2026-08-10 — Feature Manager, real feature ownership, party tokens, and a chat-card escaping fix
First minor bump of the 6.x line. Every previous 6.10.x release was a patch,
but this one adds a settings UI, changes what "disabled" means for every
feature in the module, and introduces party tokens.
Added
-
Feature Manager. A settings panel that turns every feature in the module on or off individually. Features are presented as grouped choices with preview art rather than one flat list of eighty-odd switches, with the flat view still available under advanced controls.
-
Disabling a feature now genuinely disables it. Previously a disabled feature could still register hooks, open sockets, publish API surface, and ship assets — it was hidden, not off. Ownership gates now run at startup, in the UI layer, on socket registration, and over feature-owned assets and registrations, so a disabled feature costs nothing at runtime.
-
Party tokens. Create a party token from the current selection and recall it later, with the roster carried on the token.
-
Journal Pins: composable icon pin styles, plus a default Highlight hover (orange tint and border) that preserves converted-note sizing.
-
Theater of the Mind: arena grid, inline overlays, and stacked multi-select, with a demo scene and showcase.
-
A reviewable cleanup tool for stale torch Sequencer records left behind under foreign names. (Issue #106)
Fixed
-
Image and name interpolations are escaped in chat cards and sheets. Unescaped interpolation of actor and item names into card markup allowed markup injection through a crafted name. The same class was fixed in carousing chat portraits and effect image/name markup.
-
Marching mode works again on Foundry v14. Sidebar injection had broken against the v14 DOM and the tray rail indicator was dead;
createCombatis now scene-scoped without requiring an active combat. (Issue #104) -
Weapon and torch animations stop when you turn them off. An explicit disable is now terminal instead of falling through to the master list, null resolution terminates a live effect, and the master list is reachable again. Effect names no longer encode token identity in a structurally ambiguous way, the restore chain is serialized and self-heals on failure, and
resolveWeaponSpriteaccepts Armor so shield sprites mirror correctly. (Issues #105, #110, #111) -
Duplicate sway effects no longer accumulate.
-
The tray no longer offers players NPC sheets they cannot open.
-
Journal pin rebuilds no longer destroy the live sprite texture when a stale rebuild lands.
-
The party roster falls back cleanly for actors with no art, instead of raising an empty-src media error.
-
Unidentified magic stays hidden from players, with gem and potion privacy preserved on the sheet.
-
Alignment spell filtering on the character sheet is repaired, and the dungeon generator's tautological
gridSizefallback is replaced with a scene-first chain.
Performance
- Hex coordinate labels are built lazily on first display rather than eagerly for the whole grid.
Internal
- Flag scanning resolves constant scopes and local
constaliases through lexical scope rather than name ranges, and surfaces unresolved scope names instead of assuming them. (Issue #95) - Three classes of
verify.shfalse positive that blocked CI were fixed — SCREAMING_SNAKE object-literal keys and destructured parameters read as unbound identifiers, and line-sensitive flag-snapshot comparison. Four false negatives found by adversarially probing those fixes were closed in turn. Two known gaps are recorded as issues #128 and #129. - Phase 5.3 seam splits across the effect and combat modules,
getTokensForActorlifted into one shared tested module, and an adversarial multi-model debate-review tool. - The regression suite grew to 999 tests.
v6.10.53
[6.10.53] — 2026-08-02 — Phase 5.2 known-defect pass: nine fixes across combat, effects, items, and the character sheet
Fixed
-
Talent advantage now reaches every roll path. The roll-config wrapper died on every actor update, silently killing SDX talent advantage; the dialog hook now owns advantage for all roll types, including shift/alt-click (skip-prompt) rolls, with tooltips and radio state synced to the rendered dialog. (Issue #52)
-
Ammunition hit/damage bonuses work on Shadowdark 4.x attack rolls again. The legacy monkeypatches targeted methods the 4.x flow never calls; bonuses now ride the roll config (
applyAmmoBonuseson therollFromConfigseam that sees the final selected ammunition), including on rerolls without compounding. (Issue #53) -
The NPC item-chat icon posts a card again.
item.displayCarddoes not exist in SD 4.x (unhandled rejection, nothing posted); all eight call sites across the NPC sheet, token toolbar, shapechanger, and party inventory now use the system's ownshadowdark.chat.showItemCardinside try/catch, so the next system change fails loudly instead of silently. (Issue #54) -
requireEquipped-only effects are enforced at item creation. The createItem requirement filter testedsourceRequirementonly, so such effects arrived active on unequipped items; the filter now catches the flag and the deferred check disables them. (Issue #51) -
The itemacro data migration is idempotent and re-runnable. It ran once per world, so items imported later (compendium, drag-in, future packs) kept only the legacy
flags.itemacronamespace forever; the sweep now runs on every ready (GM-only, writes once per item). (Issue #49) -
Unidentified-item masking is consolidated and consistent. Duplicated
getUnidentifiedNamecopies diverged on legacy worlds — one returned the real item name; the single implementation (4.x schema, else the legacyunidentifiedNameflag, else the label) now serves the identify spell, party sheets, containers, and the data-shaped paths. (Issue #50) -
The ToM default scene background 404 is fixed. The promised
assets/default-scene.jpgnow ships with the module (verified live). (Issue #57)
Changed
-
The three vestigial ActiveEffect condition hooks were removed. They looked for toggles inside the actor sheet that have always lived in the BODY modal — a permanent silent no-op; the modal self-updates on click and closes on its own, so the sheet has nothing to refresh. (Issue #56)
-
The unreachable weapon damage-bonus chat display was removed. Its only caller sat behind a flag SD 4.x never sets, and it used jQuery against the v14 DOM; the damage-apply card already renders the breakdown from
weaponBonusResults(with double-add de-duplication), so the dead path was deleted rather than converted. (Issue #55) -
Internal: the export-surface gate gained a reviewed-exceptions registry for deliberate export removals; the regression suite grew to 228 tests (226 node + 2 roller); nine review-gated fix branches, each with a RED-first regression test, a post-merge smoke checklist, and a closed GitHub issue.
v6.10.52
[6.10.52] — 2026-07-31 — Smaller downloads, restored combat automation, and internal reorganization
Changed
-
The Phase 3 source reorganization is intentionally user-invisible. Feature implementations now live in owned modules and
scripts/shadowdark-extras.mjsis a 1,662-line composition root instead of a 21,861-line mixed implementation file. Hook order, settings keys, public API names, and registration totals are pinned by structural gates; this release is meant to behave like 6.10.51 apart from the fixes and asset optimization listed below. -
The shipped image payload is about 99 MB smaller. 1,431 raster assets were converted to WebP, reducing their archive footprint from 140.2 MB to 41.4 MB. A conservative one-time GM migration updates stored Shadowdark Extras image paths in existing world documents, settings, and unlocked world compendiums only when the replacement WebP responds successfully; 14 images for which WebP was larger remain in their original format.
Fixed
-
SDX weapon hit and damage bonuses work in the Shadowdark 4.x roll dialog again. The integration now resolves actors from the UUID Shadowdark actually supplies, including unlinked token actors; optional bonus controls no longer duplicate when toggled, hit bonuses reach the attack roll, and damage bonuses remain single-applied.
-
Weapon hit-bonus details render on attack chat cards again. The result now travels with Shadowdark's roll configuration and the v14 chat renderer uses the native DOM element it receives, eliminating the silent failure and the former
undefinedresult display. -
Wand charge controls render and persist on Shadowdark 4.x item sheets again. The controls are anchored to a field the current Wand sheet still emits, so a GM can enable uses and edit current and maximum charges without writing flags manually.
-
Player-to-GM automation sockets are registered before migrations can suspend startup. Spell and item macros, Holy/Cleansing/Wrath weapon actions, Identify, class-ability macros, party travel mutations, and target synchronization are available as soon as the module reaches
ready, including on worlds where an asset or item-macro migration has real work to do. -
Target synchronization no longer clears targets and throws when socketlib elects a headless GM with no canvas. That client now leaves its target state untouched and reports the unavailable canvas; a normal GM client continues to mirror player targets.
Known issues
- Nine confirmed limitations remain deliberately unfixed in this verification-only release. Item Macro migration is one-shot for content added after it ran; two unidentified-name implementations disagree for legacy Shadowdark 3.x data; an effect configured only with
requireEquippedcan remain active until the next sheet/update check; the quick-condition effect hooks do not refresh an already-open modal; ammunition is selected and consumed but its configured hit and damage bonuses do not reach Shadowdark 4.x rolls; the NPC item chat icon calls a method removed in Shadowdark 4.x; unidentified magic items can still reveal their magic-item marker to players; alignment-based Spellbook filtering patches the Shadowdark 3.x method location and therefore does not run on Shadowdark 4.x; and ToM's empty-background fallback points at an unshipped image. Maintainer evidence and scope decisions are recorded indocs/KNOWN-ISSUES.md.
v6.10.51
[6.10.51] — 2026-07-30 — Background and NPC Attack sheets save reliably on Foundry v14
Fixed
-
Editing a Background item no longer fails with "ItemSD must be constructed with a DataModel or Object." Changing the Source dropdown on a Background — the usual first step when building a homebrew one — threw that error and discarded the change. The sheet handed Foundry a pending promise instead of the edited data, which Foundry 14 rejects outright where Foundry 13 had quietly ignored it. Backgrounds now save every field on the sheet, and advancement entries are no longer disturbed by an unrelated edit elsewhere on the form.
-
NPC Attack items now save fields that previously reverted without warning. The same underlying fault affected this sheet in a quieter way: attack bonus, damage, critical thresholds, and Source appeared to accept an edit, then reverted on reopen. Only the fields with their own dedicated handlers survived. Every field on the sheet now persists, and the attack's configured ranges are left untouched by a form submission.
Changed
- GitHub releases now include real release notes and a direct Wiki link. The release workflow extracts the matching version section from this changelog, fails rather than publishing an empty body when that section is missing, and appends a link to the project Wiki. The module manifest now uses that Wiki as its project URL as well.
v6.10.50
[6.10.50] — 2026-07-26 — Automated camping, applied carousing outcomes, and Item Piles compatibility
Added
-
Camping is now a complete Party rest procedure rather than an informational task list. The GM can choose participating characters, select each character's task and ability from dropdowns, or begin from the existing drag-and-drop travel assignments. A campfire can consume three pooled inactive torches or be earned by a successful Firewood check; without one, every task marked by the camping rules rolls with disadvantage. The procedure consumes pooled rations, optionally advances world time by eight hours, restores qualifying characters to maximum HP, refreshes lost spells, class abilities, limited uses, and wand spells, and removes unconscious after a successful rest. Tangible task outcomes are applied automatically: Cook raises ration-eating campers up to 2 HP above maximum, Craft creates ammunition or a torch or repairs gear, Entertain grants luck, Hunt adds 1d4 rations before meals are allocated, Keep Watch records the protected half of the rest, and Predict grants a weather re-roll. A final chat summary records supplies, recovery, checks, and benefits.
-
Party weather can use a GM-selected RollTable. A new world setting selects any world or compendium RollTable for the Party sheet's Weather button while preserving the built-in Shadowdark weather roll as the fallback. Successful Predict tasks are offered after tomorrow's weather is revealed and can redraw either source.
-
Travel and camping checks now use the cinematic SDX Roller with activity artwork and per-character abilities. Each configured activity can supply a banner image, and characters in the same group check can roll different allowed abilities without splitting the task into separate cards.
-
Apply carousing outcomes to character sheets, and a Carousing Log. Original-mode outcomes were display-only — the GP cost was deducted, but "Gain 4 XP", "a luck token", and "bilked you for 5% of your total wealth" were rendered as prose and never touched the sheet. (A
applyOutcomeEffect()helper for exactly this existed but was dead code, called from nowhere.) Each result card now carries a GM-only Apply button showing a preview of what it will grant; clicking it opens a confirm dialog listing the exact numbers before committing, then writes XP, luck tokens, the percentage wealth loss, and any renown delta. It is idempotent — the session records what was applied, so a second click is a no-op and the card shows an Applied badge instead. Narrative rewards (a priest ally, a debt owed by a noble, being barred from a tavern) have no mechanical target in Shadowdark, so they are deliberately never parsed; instead the full outcome text is appended to the character's Notes, preserving whatever was already there. Expanded mode is excluded, since it already grants its numeric XP column automatically at roll time. Alongside this, a GM-only Carousing Log journal records every session — each character's roll, what happened, the benefit, and exactly what was applied — created create-or-update per session so re-rolling never duplicates a page, and located by flag so renaming it does not orphan the log. -
Carousing coin maths is now copper-precise, and cards show coins vs. total wealth. Wealth percentages were computed and deducted in whole gp, so change was discarded twice over:
getActorTotalGp()flooredsp/10andcp/100(a purse of 9 sp + 99 cp read as 0 GP), and the percentage was floored again. A 5% loss against 41 gp took 2 gp instead of 2 gp 5 cp. All wealth arithmetic now runs in copper and only converts for display — the deduction spends the smallest coins first and breaks a larger denomination only when the remainder demands it, so a purse is never silently normalised (in Shadowdark 100 coins is a gear slot regardless of denomination, so re-minting a purse would change encumbrance). The old hand-rolled change logic indeductCoins, which could leave leftover silver unspent, now routes through the same copper path. Effect summaries read as real coin ("-5% wealth (2 gp 5 cp)"). Participant cards show41 / 162 GP— coins carried over total wealth including gear — with the exact breakdown on hover, and the second figure only appears when the character actually has valued gear. -
The active wealth base is now visible at a glance. A tag beside "Cost per player" reads Wealth base: coins only or Wealth base: coins + gear, so the GM can see which basis a percentage loss will use without opening Settings.
-
New setting: Carousing Wealth Base. Chooses what "N% of your total wealth" is measured against — coins only (
gp + sp/10 + cp/100), or coins plus the value of carried gear so stockpiling equipment cannot dodge the penalty. The deduction always comes out of coins either way and cannot drive the purse negative. If a gear-based loss exceeds the coins available, the unpaid balance becomes an accumulating, zero-slot Carousing Debt item on the character sheet, with an exact coin total and a history of the outcomes that created it. Items with no cost recorded count as nothing rather than being guessed at.
Changed
- Hex Painter map formatting now supports maps up to 200×200 hexes. Both sliders and the runtime clamp were raised from 50 while retaining the same exact-grid sizing formula, which was live-verified beyond the former limit.
Fixed
-
Player camping choices now persist on GM-owned Party actors. Task and ability dropdowns, drag/drop assignment, removal, right-click ability cycling, and Predict consumption now route through the active GM. Every request is validated against Party membership and ownership of the requesting player's character before the Party flags are changed; failures report an error instead of silently reverting.
-
Hidden Expanded Carousing outcomes no longer leak through character Notes. The automatic note writer now honors the same independent benefit/mishap visibility settings as chat. The GM-only log still keeps the complete result, while a player-owned sheet receives only descriptions the GM chose to reveal plus the visible applied XP/Renown summary.
-
Carousing rerolls no longer carry phantom participants into later log pages. Completing either roll mode replaces the stored result collection instead of merging it, and narrative-only Original outcomes now log as Applied even when no numeric summary was produced.
-
Keep Watch and Predict now ship their configured SDX Roller banner art. Both default task image paths resolve to matching black-and-white activity banners instead of silently falling back to the generic image.
-
Different unidentified potions no longer collapse into the first potion placed in an Item Pile. Item Piles similarity matching now includes Shadowdark's hidden identified name, so an unidentified Potion of Healing, Sleep, and Flight remain distinct stacks. Weapons and armor stored in Item Piles are also forced unequipped, and weapon glow/animation effects are suppressed on pile tokens.
-
SDX group rolls now create one recap and cannot strand an awaiting camping procedure. Only the browser that launched a roll creates its recap, eliminating the three-card duplication seen on travel rolls. Replacing or directly closing an overlay now resolves its pending result as canceled, stale overlays cannot clear a newer roll, and the GM close action no longer calls the Foundry close lifecycle twice.
-
Expanded Carousing neither populated the log nor added outcomes to character Notes. Only the Original roll path assigned a log ID, wrote a journal page, and appended its narrative outcome to the sheet after Apply; Expanded mode returned after saving transient results, leaving benefits and mishaps visible only in chat. Expanded rolls now create the same stable per-session log page, with dedicated Outcome, Benefits, and Mishaps columns, and append each participant's player-visible narrative result plus applied XP/renown summary to
system.notes. Opening the log backfills the current completed session, and per-session markers make note recovery idempotent so reopening it cannot duplicate entries. -
Reset Carousing did nothing, and journal-pin flags were never unset. Both passed
foundry.data.operators.ForcedDeletion— the class — where Foundry expects an instance, so the update wrote a meaningless value instead of deleting the flag and every reset silently no-opped. All four call sites now construct the operator. Reset clears the session and character drops as intended while leaving the GM's added-actor roster in place. -
Expanded carousing results showed "No specific outcome recorded" with a blank roll total. Two faults compounded. First, the result card decided which layout to draw with
{{#if this.result.xp}}— a truthiness test on a number that is legitimately0on a low roll, so any 0 XP outcome fell through to the Original layout, which then looked up fields Expanded results do not have (result.rollrather thanresult.outcomeRoll), producing "Roll: 4 + 0 = " and the empty-outcome message. The card now branches on the actual carousing mode. Second, and the reason every roll had 0 XP: a linked RollTable whose format does not match the carousing table silently overwrote the GM's configured values. An Expanded table linked to an Original-format outcome table (rows ofdescription | benefittext) parsed to 0 mishaps / 0 benefits / 0 modifier / 0 XP on every row, and that all-zero result was overlaid on top of 25 correctly configured rows on every refresh. Linked data is now only overlaid when the parse yields something usable, per section — so a mismatched link leaves the stored values intact — and the GM gets a warning naming the offending table instead of silently losing their work. -
**Carousing session edits never actually deleted anything, stranding results and resurrecting cleared sta...