Bug: timeSinceStart only updated when an envelope event fired (combatStart, attack-roll, etc.). If the combat was idle — a player thinking about their turn, between turns — the timer froze. Fix: 1Hz self-rescheduling setTimeout in the constructor that bumps timeSinceStart and triggers a throttled render while _state.isActive is true. Stopped on unwireHooks (combat end). TDD: Section O (5 assertions) added BEFORE the fix. - O.1 initial timeSinceStart reflects _combatStartedAt - O.2 advances without an envelope event - O.3 tick interval is ~1s - O.4 timer does not tick when combat is inactive - O.5 timer resumes when combat becomes active again Tests: 65/65 passing in ~2s. Playwright 31/31.
4.9 KiB
4.9 KiB
Changelog
All notable changes to Combat HUD Hub are documented here.
[0.2.5] — 2026-06-22 (timer auto-tick)
- 1Hz tick keeps the timer counting. The HUD's
timeSinceStartfield only updated when an envelope event fired (combatStart, attack-roll, etc.). If the combat was idle — a player thinking about their turn, between turns — the timer froze. Added a 1Hz self-reschedulingsetTimeoutin the constructor that bumpstimeSinceStartand triggers a throttled render while_state.isActiveis true. Stopped onunwireHooks(combat end). - Tests: 65/65 passing in ~2s. Section O covers initial value, no-event advance, tick interval, idle pause, and resume.
[0.2.4] — 2026-06-22 (current-turn updates on combatTurn + session-open auto-open)
- Current-turn updates instantly on combatant switch. The event-translation layer now resolves the new combatant from
combat.turns[newTurn](because Foundry firescombatTurnBEFORE the new state is committed, sogame.combat.combatantis still the OLD combatant at that moment). The HUD stashes the new turn info on_state._latestTurnand uses it as a tiebreaker when the encounter'scombatantIdis stale. - Session-open auto-opens HUD with active encounter. At ready, if
battle-focus.api.getActiveEncounter()returns a live (not endedAt) encounter, the HUD opens and populates from the encounter. This handles browser-refresh mid-combat and "pending combat" (combat tracker exists butStart Combatnot yet clicked) — the HUD no longer stays invisible until the next event fires. - Encounter combatantId key resolution. The encounter's
combatantIdis the Foundry combatant document id, but the combatants map may be keyed by tokenId, actorId, or combatantId. The currentTurn resolver now tries all three. - Tests: 60/60 passing in <1s. Sections M (turn event) + N (session-open) added.
[0.2.3] — 2026-06-22 (isReady() + 3-place version fix)
- New
api.isReady()returnstrueafter the ready hook has fired (and core sections have been registered). Lets consumers and tests gate on "ready" instead of polling the section list. - 3-place version rule enforced. v0.2.2's source MODULE_VERSION was missed on the previous bump; corrected and now bumped to v0.2.3 across module.json + package.json + main.js.
- Tests: 50/50 passing in <1s.
[0.2.2] — 2026-06-22 (getFeed + clearFeed)
- New
api.getFeed(sectionId)— read accessor that returns a shallow copy of the section's feed entries. Useful for consumers (and tests) that need to inspect feed state. - New
api.clearFeed(sectionId)— empties a section's feed. - Tests: 50/50 passing in <1s. Section C extended with getFeed/clearFeed assertions.
[0.2.1] — 2026-06-22 (current-turn indicator)
- Current-turn indicator. The combatants row whose
tokenIdmatches the encounter's current combatant getsdata-chh-current-turn="true", a.chh-section-combatants-row--currentclass, an accent-color left border + subtle background tint, an outlined portrait, and a "▶" marker before the name. The header section also prepends "▶" before the turn name. - Encounter-as-source-of-truth for currentTurn.
buildRenderContextnow resolves the current turn from the encounter singleton (encounter.currentTurnorencounter.combatantId → encounter.combatants.get(...)) instead of readinggame.combatdirectly. battle-focus owns the encounter; the hub reads it. - Tests: 46/46 passing in <1s covering sections A-L.
[0.2.0] — 2026-06-20 (port HUD from its-achievable)
- Ported
scripts/hud.js,scripts/event-translation.js,templates/hud.html,styles/hud.cssfrom its-achievable v0.2.0. - Renamed
bf-hud-*CSS class prefix tochh-*(function-over-branding). - Refactored HUD to render via
addSection({ id, label, render })API. The HUD itself no longer owns apinnedAchievementsfeed — that becomes a section registered by its-achievable (v0.3.0). - Built-in core sections now:
core-header(round + current turn + portrait),core-combatants(per-PC rows),core-dice-streak. - New
hudPositionsetting (top/bottom/left/right, per-user) replaces the previous its-achievable-owned setting. - Throttled render (1Hz, same as its-achievable v0.2.0).
- ApplicationV2 surface:
open,close,isOpen,getState,getView({ isGM, character }),forceRender,wireHooks,unwireHooks. - Smoke tests: 42/42 passing in <1s covering sections A-K of
tests/PLAN.md.
[0.1.0] — 2026-06-20 (initial scaffolding)
- New module extracted from its-achievable v0.2.0.
- Public API:
addSection,removeSection,pushFeedEntry,listSections,getHud,openHud,closeHud. - Soft-dep wiring for
foundry-hooks-lib(envelope subscription) andbattle-focus(encounter seam). - Built-in core sections register only when both soft-deps are present at
ready. - Smoke test: 22/22 passing in <1s.
- HUD instance is a stub; real
ApplicationV2mounting deferred.