Add death timer to brochure with screenshot
Adds a new feature row (Row 8) describing the dying mechanic — 1d4+CON countdown, recovery saves, and permanent death. Screenshot generated via the Playwright script showing a dying character card with red border in the DM view. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b7b4123f8e
commit
9607462a7c
3 changed files with 57 additions and 0 deletions
BIN
site/assets/screenshots/death-timer.png
Normal file
BIN
site/assets/screenshots/death-timer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 910 KiB |
|
|
@ -145,6 +145,23 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 8: text left, screenshot right -->
|
||||
<div class="feature-row reverse">
|
||||
<div class="feature-image">
|
||||
<img src="assets/screenshots/death-timer.png" alt="Initiative tracker showing a dying character with skull countdown and Roll Recovery button">
|
||||
</div>
|
||||
<div class="feature-text">
|
||||
<div class="feature-label">Death Timer</div>
|
||||
<h2 class="feature-heading">Every round could be the last.</h2>
|
||||
<p class="feature-desc">
|
||||
When a character drops to 0 HP, a countdown begins: 1d4 + CON modifier rounds
|
||||
before permanent death. The DM sees the timer on the card and can roll a d20
|
||||
recovery save from the initiative tracker — an 18 or higher lets the character
|
||||
stand at 1 HP. Run out the clock and they're gone for good.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Torch + Luck callout cards (no screenshot) -->
|
||||
<div class="callout-row">
|
||||
<div class="callout-card">
|
||||
|
|
|
|||
|
|
@ -245,6 +245,45 @@ async function captureInitiativeActive(page) {
|
|||
// Screenshot captures the initiative tracker with party + enemies rolled
|
||||
}
|
||||
|
||||
async function captureDeathTimer(page) {
|
||||
await resetToCleanCampaign(page);
|
||||
|
||||
// Start combat with an enemy so the initiative tracker is visible
|
||||
await page.click('button:has-text("Combat")');
|
||||
await page.waitForTimeout(400);
|
||||
|
||||
const enemyNameInput = page.locator('input[placeholder*="Goblin"], input[placeholder*="enemy" i], input[placeholder*="name" i]').first();
|
||||
if (await enemyNameInput.isVisible().catch(() => false)) {
|
||||
await enemyNameInput.fill('Skeleton');
|
||||
const hpInput = page.locator('input[placeholder*="HP"], input[placeholder*="hp" i], input[type="number"]').first();
|
||||
if (await hpInput.isVisible().catch(() => false)) {
|
||||
await hpInput.fill('8');
|
||||
}
|
||||
}
|
||||
|
||||
// Roll initiative to enter the active phase
|
||||
await page.click('button:has-text("Roll Initiative")');
|
||||
await page.waitForTimeout(1500);
|
||||
|
||||
// Bring the first character to 0 HP via the API — server rolls dying timer automatically
|
||||
await page.evaluate(async () => {
|
||||
const campaignId = Number(location.pathname.match(/\/campaign\/(\d+)/)?.[1]);
|
||||
const res = await fetch(`/api/campaigns/${campaignId}/characters`, { credentials: 'include' });
|
||||
const chars = await res.json();
|
||||
if (chars.length > 0) {
|
||||
await fetch(`/api/characters/${chars[0].id}`, {
|
||||
method: 'PATCH',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ hp_current: 0 }),
|
||||
});
|
||||
}
|
||||
});
|
||||
await page.waitForTimeout(1500); // wait for socket broadcast + React re-render
|
||||
// Screenshot shows initiative tracker with dying character (skull tag + Roll Recovery button)
|
||||
// and DM card with pulsing red border + skull countdown
|
||||
}
|
||||
|
||||
// ── main ───────────────────────────────────────────────────────────────────
|
||||
|
||||
async function run() {
|
||||
|
|
@ -273,6 +312,7 @@ async function run() {
|
|||
await shot(page, 'spellcasting', captureSpellcasting);
|
||||
await shot(page, 'atmosphere', captureAtmosphere);
|
||||
await shot(page, 'initiative-active', captureInitiativeActive);
|
||||
await shot(page, 'death-timer', captureDeathTimer);
|
||||
|
||||
await browser.close();
|
||||
console.log('');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue