Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ea75ece
fix: gitignore the root .env file
Jul 12, 2026
ff5f0f9
feat: character sheets Phase 1 - engine, CP:R template, player window
Jul 12, 2026
757f879
feat: sheet window matches the agreed style baseline
Jul 13, 2026
116f47e
feat: standalone full-tab character sheet + responsive grids
Jul 13, 2026
c4858ad
fix: sheet tab button visibility + admin identity for standalone tab
Jul 13, 2026
6be6fd9
feat: sheet window is resizable (native handle, 520px max width)
Jul 13, 2026
f6b590e
fix: sheet content fills the window height; tab-open button matches X…
Jul 13, 2026
723a79f
feat: sheet HP and cash are live linked fields (token HP + bank balance)
Jul 13, 2026
53973de
feat: number fields on the sheet default to 0 instead of blank
Jul 13, 2026
cee55e7
feat: sheet rolls - server-authoritative roll engine (Phase 2 core)
Jul 13, 2026
952bfd8
feat: rolling from the sheet opens the dice tray; standalone tab show…
Jul 13, 2026
e595513
feat: helper text on sheet fields; CUR/MAX labels on paired boxes
Jul 13, 2026
12b9c08
feat: token defense translates per game system (AC -> SP/DV for CP:R)
Jul 13, 2026
39ad834
feat: Phase 3 character sheet features
Jul 13, 2026
5952a8b
feat: Cyberpunk RED character sheets v1.4.0 - complete CP:R system
Jul 13, 2026
ae18fbb
fix: align NPC tier dropdown with GENERATE_SHEET button
Jul 14, 2026
2e49494
fix: import dialog portals to body, window z-index stacking, NPC libr…
Jul 14, 2026
8b4f3dc
fix: close sheet/NPC windows before logout and on terminate session
Jul 14, 2026
d80ed5a
fix: wound banners column layout, pulsing animations, centered death …
Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ backend/data/

# Backend environment and dev config
backend/.env
.env
backend/nodemon.json

# Large archives
Expand Down
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,45 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

---

## [1.4.0] - 2026-07-13

Cyberpunk RED character sheets: the full Phase 3-5 sheet system, making CP:R the first feature-complete game system.

### Added
- **Character sheet system** — template-driven sheets (one renderer, per-system templates); player window, admin view of any player/NPC sheet, standalone browser tab (`?sheet=true`), quick-sheet card, portrait upload with TV-glitch effect, segmented HP bar (green/yellow/red)
- **Server-authoritative rolls** — stat/skill rolls resolve against the stored sheet (exploding CP:R check die); results land in the dice tray and history
- **CP:R combat flow** — single ATTACK button; weapon picker from structured sheet weapon rows (name/DMG/skill/ROF); to-hit vs token DV; aimed shots (−8, head, ×2 damage through armor); damage auto-rolled, soaked by defender SP, armor ablation on penetration; damage writes through to token HP; attack animation follows the weapon type (melee/ranged)
- **SP SHIELD** — defender's shield intercepts damage first and breaks down point-for-point; overflow soaks against location SP
- **Critical injuries** — two+ max-face damage dice trigger +5 direct damage (ignores armor/shield) and prompt the GM to roll the book's injury table (table not embedded)
- **Death saves** — MORTALLY WOUNDED banner at 0 HP with DEATH SAVE button; 1d10 + escalating penalty vs BODY (natural 10 always fails); penalty resets on healing above 0
- **Seriously Wounded** — banner at ≤ threshold HP; −2 to all checks applied server-side (−4 while mortally wounded)
- **Armor penalty** — heavy-armor stat penalty applied to all REF/DEX-keyed checks and attacks
- **LUCK on rolls** — arm pips on the sheet (declared before the roll, per RAW) for a flat bonus on the next roll; spend is capped/decremented server-side; attack panel has its own LUCK selector
- **House rules panel** (ADMIN → TTRPG_SYSTEM, staged APPLY/REVERT) — `MELEE_DV TAKE-10` (10 + DEX + Evasion instead of 6 +) and `LUCK BONUS ALSO NEGATES NAT-1` (also unlocks a dedicated 1-LUCK fumble shield); rules apply live via settingsUpdated
- **LUCK pips + admin reset** — hexagonal pips on the sheet header; RESET_ALL_LUCK in the admin panel restores every player to max
- **Humanity → EMP** — editing Humanity recomputes current EMP (= Humanity ÷ 10) on every write path (template-declared derived fields)
- **NPC library** — create/delete NPC sheets, folders with MOVE control, ATTACH sheet to a token, OPEN full sheet editor; NPC sheets mirror their linked token's HP live
- **Leveled NPC generation** — GENERATE_SHEET takes a per-system tier (CP:R: MOOK/SKILLED/PRO/ELITE) seeding stats, skills, armor, weapons, token HP and DVs; melee DV computed from the sheet (6/10 + DEX + Evasion), GM can override via EDIT_DV
- **Sheet import** — IMPORT on every sheet window: fillable-PDF form extraction, JSON paste, or stat-block text; per-system alias mapping with preview before apply; linked fields (HP/cash) refused with explanation
- **Token defense per system** — MELEE_AC/RANGED_AC labels become MELEE_DV/RANGED_DV under CP:R; CP:R hides the two-button melee/ranged flow behind one ATTACK button
- **OPEN_SHEET on token windows** — players open their own sheet from their token; admins open any player's or NPC's sheet from any token
- **`npm run dev` (backend)** — nodemon auto-restart so backend code changes apply without manual restarts

### Changed
- **TTRPG_SYSTEM panel** moved above CURRENCY_ICON in the admin panel; SHEETS list removed
- **Sheet UX polish** — placeholders (ghost example text) on all free-form fields, upload hint bar attached under the portrait, weapon rows replace the free-text weapons area (notes field retained), CUR ≤ MAX clamping on paired fields (frontend + server)
- **CHECK_HEALTH window** — now resolves NPC tokens and tracks live HP by token id (was frozen at open and player-only)

### Fixed
- **NPC armor ignored in attacks** — defender sheet lookup branched on token owner instead of token type, so enemy tokens (which carry an owner) never found their linked NPC sheet; SP always read 0
- **DV edits not reflected** — EDIT_DV saved correctly but the token window showed the stale snapshot until reopen
- **Death save / FIRE appearing dead** — stale backend process; mitigated permanently by the new `npm run dev` watcher

### Tests
- 377 backend / 574 frontend — new suites: `cpr_attack` (to-hit, armor, shield, crits, LUCK, death saves), `sockets.deathsave` (socket integration: death saves, NPC SP, import apply, tiered generation, fumble-shield gating), `sheet_import` (PDF/JSON/text extraction + mapping), `npc_tiers`, plus renderer/library/import-dialog coverage

---

## [1.3.1] - 2026-07-08

### Added
Expand Down
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,15 @@ CITY_NET/
│ │ ├── overpasses.js # Overpass CRUD (GET all / POST one / DELETE :id)
│ │ ├── signs.js # Custom sign CRUD (GET all / POST / PATCH :id / DELETE :id); text optional when image_url set
│ │ ├── fonts.js # Font file upload/list/delete (.ttf .otf .woff .woff2); served as static under /uploads/fonts/
│ │ └── player.js # Player auth (register, login, forgot, reset, registration status poll)
│ │ ├── player.js # Player auth (register, login, forgot, reset, registration status poll)
│ │ └── sheets.js # Character sheets — admin sheet access, NPC library, portraits, LUCK reset, import preview
│ ├── sheets/
│ │ ├── templates.js # Server-side template metadata (public/combat/linked fields, max pairs, derived fields)
│ │ ├── rolls.js # Per-system roll map (fieldId → formula); server-authoritative
│ │ ├── rollEngine.js # Formula parse/resolve/execute (explode10, deterministic RNG for tests)
│ │ ├── attack.js # CP:R combat resolution — to-hit, damage, SP soak/ablation, shield, crits, death saves
│ │ ├── importers.js # Modular sheet import — PDF form extraction + per-system field mappers
│ │ └── npcTiers.js # Per-system NPC power tiers for GENERATE_SHEET (CP:R: Mook→Elite)
│ ├── sockets/
│ │ └── index.js # All Socket.IO event handlers
│ ├── startup/
Expand All @@ -351,6 +359,13 @@ CITY_NET/
│ ├── player.test.js # Player auth (register, login, forgot/reset, registration flow)
│ ├── roads.test.js # Road API (GET / POST / DELETE / DELETE :id)
│ ├── signs.test.js # Sign API (GET / POST / PATCH / DELETE, auth, image-only, filter_intensity clamping, XSS)
│ ├── sheets.test.js # Sheet routes (system switch, admin access, portraits, derived fields)
│ ├── npc_sheets.test.js # NPC library routes (CRUD, links, folders, LUCK reset, HP overlay)
│ ├── cpr_attack.test.js # CP:R attack module (to-hit, armor, shield, crits, death saves)
│ ├── npc_tiers.test.js # NPC tier packages (escalation, weapon validity)
│ ├── sheet_import.test.js # Import pipeline (PDF form extraction, alias mapping, preview route)
│ ├── rollEngine.test.js # Roll formula engine
│ ├── sockets.deathsave.test.js # Socket integration: death saves, sheetAttack vs NPC SP, import apply, tiered generation
│ ├── sockets.editing.test.js # Socket editing access flow; regression for stale elevatedUsers bug
│ └── undo.test.js # Undo endpoint (all action types, auth, ordering)
Expand Down Expand Up @@ -387,6 +402,12 @@ CITY_NET/
│ │ │ ├── Streamer.tsx # Camera broadcaster/rig pairs for streamer mode
│ │ │ ├── StreamerOverlay.tsx # HUD overlay rendered on the spectator window
│ │ │ ├── StreamerDirectorPanel.tsx # Admin director controls (camera mode, visibility flags)
│ │ │ ├── CharacterSheetWindow.tsx # Player's own character sheet (socket-based, self-only)
│ │ │ ├── NpcSheetWindow.tsx # Admin view/edit of NPC or player sheets (REST-based)
│ │ │ ├── NpcLibrary.tsx # NPC sheet library (folders, attach-to-token, move, open)
│ │ │ ├── SheetRenderer.tsx # Template-driven sheet renderer (any game system)
│ │ │ ├── ImportSheetDialog.tsx # Sheet import — fillable PDF / JSON / stat-block paste with preview
│ │ │ ├── QuickSheetCard.tsx # Public sheet card shown to other players
│ │ │ ├── UpdateModal.tsx # Draggable update notification modal (shown on admin login when update available; Update Now / Remind Me Later / Skip Version; docker-aware)
│ │ │ └── __tests__/ # Component unit tests (Vitest + Testing Library)
│ │ │ ├── AdminPanel.test.tsx
Expand All @@ -406,6 +427,10 @@ CITY_NET/
│ │ │ ├── RadioPlayer.test.tsx
│ │ │ ├── Rhombuses.test.tsx
│ │ │ ├── SecureLogin.test.tsx # Login, register, approval polling, password reset, deny flows
│ │ │ ├── CharacterSheet.test.tsx # Template registry, renderer, sheet window, weapon rows, death saves
│ │ │ ├── NpcLibrary.test.tsx
│ │ │ ├── ImportSheetDialog.test.tsx
│ │ │ ├── QuickSheetCard.test.tsx
│ │ │ ├── Sidebar.test.tsx
│ │ │ └── UpdateModal.test.tsx # Rendering, docker/non-docker branching, button callbacks, update flow
│ │ ├── context/
Expand All @@ -417,6 +442,13 @@ CITY_NET/
│ │ │ └── __tests__/
│ │ │ ├── useApi.test.ts # Fetch helper unit tests
│ │ │ └── useSocket.pendingRequests.test.ts # Pending edit-request state; regression for stale requests on newly-promoted temp admins
│ │ ├── sheets/
│ │ │ ├── types.ts # Sheet template type system (fields, sections, header, death saves, NPC tiers)
│ │ │ ├── index.ts # Template registry + getMaxPairs helper
│ │ │ ├── SheetPage entry # (src/SheetPage.tsx) standalone browser-tab sheet (?sheet=true)
│ │ │ └── templates/
│ │ │ ├── generic.ts # Minimal fallback template
│ │ │ └── cyberpunk_red.ts # Cyberpunk RED — stats, skills, weapons, armor, tiers (labels + dice math only, no book content)
│ │ ├── streamerMode.ts # IS_SPECTATOR constant — detects ?streamer=true URL param
│ │ └── utils/
│ │ ├── locationHelpers.ts # Location geometry utilities; exports ZONE_TYPE_NAMES and isUserDefinedName
Expand Down
Loading
Loading