Commit Graph

86 Commits

Author SHA1 Message Date
44b2e283bd Add ammo and combat profiles to simulations 2026-06-30 10:08:10 +02:00
c54fd6c8fd Gate player skill conditions in missions 2026-06-30 09:07:55 +02:00
e7ef9ae2df Test mission skill modifiers 2026-06-30 08:53:44 +02:00
647869cba9 Add skill check modifiers to mission roller 2026-06-30 08:33:44 +02:00
a08afbaf0f Show skill target modifiers in mission roller 2026-06-30 08:18:09 +02:00
b6cff53b8e Add rules-based squad tactics checks 2026-06-29 14:00:19 +02:00
3aebcf8f0e Add examples to rules reference 2026-06-29 13:45:32 +02:00
fe884ac543 Prepare Deathwatch session tools 2026-06-29 13:37:02 +02:00
4630272171 feat: Error reports create GitHub Issues (alexpolo1/dwroller) 2026-06-25 18:56:30 +02:00
c0fc0d1aab fix: ErrorReports build errors - fix confirm/window.confirm and App.js JSX syntax 2026-06-25 18:45:20 +02:00
5c4c65abd7 Add error reporting system - logged-in users can submit bug reports, GM can resolve 2026-06-25 18:29:49 +02:00
e1bcf61498 fix: combat reveal toggle + eliminate poll flickering
Add 👁/🔒 toggle to combat row in Scene Secrets — players see
combat panel only when GM reveals it (scene.reveal.combat).

Stop flickering: background polls now run silent (no setLoading),
and state updates are skipped when JSON content is unchanged,
preventing unnecessary re-renders every 4s.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 15:06:37 +02:00
b3818bd727 feat: next game date banner + demo mission "Blodprøve"
Add amber banner at top of Mission Tab showing next session date
(Lørdag 28. juni 2026). Create 3-scene Danish demo mission
"Blodprøve: Deathwatch-protokol" (id 10) — Social briefing →
Investigation aboard a dark station → Combat vs Genestealer Patriarch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 15:01:58 +02:00
5d98ebec13 feat: granular per-element reveal system + GM manual dice entry
Replace single scene reveal toggle with individual unlock buttons for
title, mood, description, objectives, complications, and each check —
GM controls exactly what players see and when.

Add GM manual roll entry (🎲 button per check): select player, type
the physical dice result, submit records it to the mission roll feed
under that player's name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 14:57:29 +02:00
d6f2f0e5c7 feat: mood text per scene + Danish translation of Fabius Bile mission
- Mood text field on scenes shown as amber italic read-aloud block
  above scene description (gated by revealed flag for players)
- Scene editor includes Mood / Read-aloud textarea
- Scene editor moved full-width below two-column grid
- Mission "The Hunt for Fabius Bile" fully translated to Danish
  ("Jagten på Fabius Bile") with Danish names, descriptions,
  objectives, complications, checks and mood text for all 10 scenes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 14:48:31 +02:00
7873f450da feat: rules midgame priority system, mission enhancements, and requisition shop improvements
- Add midgame priority ranking for rules (midgamePriority field)
- Enhance rules search to support midgame filtering and sorting
- Improve mission simulation and midgame tracking
- Fix RequisitionShop player name handling
- Add rules midplay simulation tests
- Update MissionTab with midgame scene tracking
- Add backend logging for rules updates
2026-06-24 12:09:25 +02:00
7d038dd942 feat: GM mid-play scene editor in Mission Tab
Edit Scene button in Scene Secrets header opens an inline editor card
below Table State. Lets the GM edit scene title, type, description,
checks (name/skill/char/target/modifier/reward, add/remove), enemies
(name/wounds/BS/WS/damage/AP, add/remove), objectives, and
complications — all saved live via the existing patchScene path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:08:48 +02:00
2a63e43120 feat: simulation difficulty control (Recruit → Legendary)
5 tiers selectable in Sim Lab config panel. Each tier scales enemy
wounds/BS/AP, adds check penalties, adjusts max combat rounds,
inter-scene healing chance, fear bonus, and adds a 3rd Elite Guard
enemy at Brutal+. Difficulty stored in DB (difficulty_level column)
and shown as a badge in the sidebar and report header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:04:17 +02:00
a666b8b4b4 feat: Simulation Lab — GM tab to run and review mission simulations
Backend:
- Add `simulations` table to MariaDB (mission, players, result, XP,
  roll feed, player cards, scene log, findings — all persisted as JSON)
- simulationHelpers: save / getAll / getById / delete
- simulationRoutes.js: POST /api/simulations (run engine + save),
  GET /api/simulations (list), GET /:id (full report), DELETE /:id
- Simulation engine: d100 dice, fear tests, combat rounds with
  initiative, conditions, damage, fate re-rolls, skill checks,
  auto-assign checks to best-stat player, enemy pools from scene data,
  per-player report cards with grade A-D, hero moments, shame list

Frontend:
- SimulationTab.jsx: GM-only tab with sidebar list of past runs,
  "Run New Simulation" config panel (pick mission + players),
  collapsible scene log, player report cards, filterable roll feed,
  findings panel
- App.js: import SimulationTab, add "⚙ Sim Lab" nav button (GM only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 10:31:27 +02:00
a7721006ef test: add playthrough simulation #2 script (playthroughRun2.js)
Full standalone Node.js simulation of 'The Hunt for Fabius Bile'.
Real d100 rolls vs actual player stats, wound tracking, fear tests,
initiative, conditions, fate spends, and per-player report cards.
Run: node src/tests/playthroughRun2.js

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:55:42 +02:00
02ddc2686b fix: RequisitionShop — RP tracking, spending, and GM management panel
- Fetch player RP/renown/gear from GET /api/players/:name (public full data)
  instead of the name-only player list, so RP is never 0
- Player status bar: RP (amber), renown badge, collapsible gear inventory
- Purchase flow posts to /api/shop/purchase and reads newRp from response
- Affordable filter, renown filter, item cards show affordability state
- GM panel: all-player RP/renown/gear table, Set RP, Set Renown forms

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:48:53 +02:00
8febe583ee feat: Dice Roller — player sheet auto-load, weapon filtering, condition modifiers
On load, each player's character sheet is fetched from /api/players/{name}:
- BS and WS set from tabInfo.characteristics
- Weapon dropdown replaced with only their personal weapons (normalised
  from tabInfo.weapons: type→class, ap→pen, default modes by type)
- First weapon pre-selected with all its damage/pen/rof/mode defaults applied
- maxWounds set from tabInfo.wounds; curWounds preserved from localStorage
  if the player was already tracking mid-session

Active scene conditions (synced from MissionTab via dw:combat-state) now
apply automatic attack modifiers:
- Pinned: –20 BS
- Stunned: –20 BS/WS
- Knocked Down: –20 BS/WS
- Fatigued: –10 BS/WS
- Grappled: –20 WS, ranged/heavy weapons hidden from weapon dropdown
- Bleeding: banner only (no roll modifier)

Condition banner appears above the roller when any condition is active,
showing each condition label and the net modifier to the attack target.
The status bar target display also shows the condition delta inline.

MissionTab: conditions map now included in dw:combat-state localStorage
write and CustomEvent payload so the Dice Roller receives per-player
condition state in real time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:38:32 +02:00
cdfd147f02 feat: Mission Tab — 11 playthrough fixes + 4 follow-up findings
All 11 issues from 4-player simulation of The Hunt for Fabius Bile:
1. Roll feed visible to all players (no GM auth guard)
2. Scene text gated by revealed flag; GM explicit reveal per scene
3. GM can add NPC/enemy entries to initiative tracker
4. Round counter synced to Dice Roller via localStorage + custom event
5. Check reward text hidden until player has rolled
6. Checks assignable to specific player via Scene Secrets ⚙ options
7. Fear test quick-roll panel with WP input appears when fearRating > 0
8. Decision checks show textarea/Declare instead of d100 roll button
9. Fate point re-roll: one per check per scene, resets on scene advance
10. Player poll reduced from 8s to 4s, combined mission + roll feed poll
11. Mission complete banner with scene stats and GM outcome notes field

4 follow-up findings from second simulation run:
- Finding #1: Activate mission now initialises revealed:false on all scenes
  so players never see scene text before the GM narrates
- Finding #2: Fear penalty auto-applied to WP display; button shows
  effective (penalised) target rather than raw WP input
- Finding #3: RollFeedRow moved outside component to avoid re-mount on
  every render; onDelete passed as prop
- Finding #4: Removed duplicate "Open for Players" quick-button from
  Scene Checks left panel — Scene Secrets is the sole entry point

New files:
- src/tests/missionPlaythrough.test.js — full GM+4-player simulation
  test suite covering all 11 issues and 4 findings (39 test cases)
- src/tests/missionTab.test.js — player/GM view isolation tests
- src/utils/diceRoller.js — shared d100/degrees/clampTarget utilities
- tests/missionRoutes.test.js — backend mission route unit tests
- tests/playerRoutesLogin.test.js — player login route tests
- tests/sessionRoutes.test.js — session validation tests

Note: React unit tests require jsdom; segfaults on ARM64 (Raspberry Pi)
due to a known jsdom/Node 20 incompatibility on aarch64. Tests pass on
x86 CI. Backend integration tests (tests/) run normally.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 00:25:51 +02:00
cd180aad5b fix: CI tests - switch login to text input, fix session validation regex, fix playerManagement test 2026-06-23 15:33:36 +02:00
d610fa08fb fix: GM login - include GM in dropdown, auto-fill password, fix session validation regex 2026-06-23 15:18:33 +02:00
5b022a6426 Save mission 'The Hunt for Fabius Bile' to DB
- 10 scenes, 59 enemies, High threat, 4 players
- Includes all combat encounters, social, investigation, puzzle, epilogue
2026-06-23 14:52:34 +02:00
bfe3489060 Update player sheets with proper Deathwatch data
- All players: Adept renown (1 RP), 15 wounds, fate=1, full characteristics
- anders: Blood Angels Devastator, Heavy Bolter + Bolt Pistol
- christoffer: Ultramarines Chaplain (Hero, 3 RP), Crozius Arcanum + Bolt Pistol
- claes: Ultramarines Sergeant, Bolter + Chainsword + Power Fist + Bolt Pistol
- phillip: Ultramarines Space Marine, Bolter + Chainsword + Bolt Pistol
2026-06-23 14:48:26 +02:00
254ba5bd1d Fix login UI: add user dropdown selector, fix build syntax error
- Replace username text input with dropdown selector for player login
- Fix unescaped apostrophe in MissionSimTab.jsx (Emperor's -> double quotes)
- Fix em-dash encoding issues in MissionSimTab.jsx
- Update player password to 1234 in .env
2026-06-23 14:43:51 +02:00
182afab282 Add mobile responsiveness to App.js
- Tab navigation wraps on small screens (flex-wrap)
- Smaller padding and font on mobile (px-4, text-xl)
- Responsive main content padding (px-4 sm:px-6)
- Tighter spacing on login row (gap-3, mb-3)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 14:27:58 +02:00
fb019057bb Restructure Mission tab: Mission for all, Mission Sim for GM only
- Rename MissionTab to MissionSimTab (combat simulation, GM only)
- New MissionTab shows mission history (all users)
- Mission Sim tab added to GM-only navigation
- MissionSimTab.jsx moved to src/components/

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 10:16:35 +02:00
fe1b77ec68 Add mission persistence: missions table, API routes, and history UI
- MariaDB missions table with scenes JSON
- /api/missions CRUD routes
- MissionTab saves completed missions to DB
- Mission history panel in UI

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 10:07:46 +02:00
dbb79c2537 Remove unused hitsFromDoS from MissionTab
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 08:52:16 +02:00
a054293ef9 Clean up MissionTab: remove unused imports and state variables
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 08:51:00 +02:00
ca4c8068f8 Add Mission Tab: combat simulation for GM mission planning
- New MissionTab component with scene-based combat simulation
- Enemy roster from DeathwatchRoller (12 enemy types)
- Scene progression (4-6 scenes) with threat levels
- Combat log and results tracking
- Added to App.js navigation

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 08:47:40 +02:00
42dd4cfb53 Fix App.js: guard list.find against non-array response
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 22:58:19 +02:00
3248180617 Fix PlayerManagement tests: wrap async state updates in waitFor
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 19:40:29 +02:00
f01eef297f Fix XPBar test: enable automatic JSX transform in babel
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 19:23:58 +02:00
a4cabbd2b8 Clean rules database and add documentation
- Remove OCR noise, credits, and duplicates from rules-database.json (288→255 rules)
- Add clean_rules.py script for rule cleanup
- Add CLAUDE.md, docs/, and update README with documentation links

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 17:35:36 +02:00
e511bff882 Add weapon images, full rule scraping, and expanded quick reference
- scripts/generate-weapon-images.js: AI image generation for weapon cards
  supporting HuggingFace FLUX.1-schnell, OpenAI DALL-E 3, and Gemini Imagen;
  images served from public/weapon-images/ via new static route in server.js
- public/cards.html: load manifest.json and show AI art on weapon cards
- scripts/scrape-rules-from-pdfs.py: PyMuPDF scraper extracting full rule
  text from all five rulebook PDFs with bold-span heading detection
- scripts/tag-and-dedup-rules.js: standalone dedup helper (JS-side grouping)
- database/routes/rulesRoutes.js: remove content truncation in search/random,
  add admin dedup endpoint (JS-side, fast), fix RulesTab to fetch full content
- src/components/RulesTab.jsx: fetch full rule content on modal open
- public/print.html: expanded quick reference with pre-gen character stat
  blocks (Sepheran + Lucian), Astartes traits sheet with correct derived SBs
  and TBs, full Critical Hit Tables for all 4 locations × 4 damage types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 22:50:50 +01:00
dc1c13620f Add Kort and Print links to main navigation
Both open in a new tab (target=_blank) since they are standalone
HTML pages outside the React app.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 21:25:19 +01:00
83a1aeaebe Refine card layout: smaller art box, bigger stats text, footer bar
- Art box reduced from 32mm to 26mm height, icon enlarged to 22pt
- Stats font increased from 6pt to 7pt with more line spacing
- Replaced floating source pip with proper footer bar showing
  renown requirement (left) and source book (right)
- Footer bar colour-coded by weapon category to match title bar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 21:22:32 +01:00
373b7f5333 Add printable weapon card sheets at /cards.html
Poker-card sized (63×88mm) cards matching the physical Deathwatch card format:
- Req cost badge top-left
- Title bar with weapon name
- Dark art box with category icon and class label
- Type line (Weapon – Melee, Weapon – Ranged, Equipment, etc.)
- Stats block (Dmg, Pen, Range, RoF, Clip, Rld, Special, Renown)
- Source abbreviation bottom-right

9 cards per A4 sheet, cut-ready.
Filter by category (Melee/Ranged/Grenade/Armour/Other).
Data loaded live from /api/weapons.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 21:08:03 +01:00
f94095b22f Add printable quick reference page at /print.html
5 printable sheets for the Deathwatch RPG:
- Sheet 1: Core Mechanics (tests, DoS/DoF, damage formula, hit locations)
- Sheet 2: Combat Actions (half/full actions, ranged/melee modifiers)
- Sheet 3: Weapons (melee, ranged, grenades - loaded live from /api/weapons)
- Sheet 4: Squad Mode & Cohesion rules
- Sheet 5: Weapon Special Qualities (Tearing, Power Field, Blast, etc.)

Print-optimised CSS with page-break-after per sheet.
Weapons table fetches live from the API for up-to-date data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 20:58:13 +01:00
7d41ec8205 Fix public/index.html template - remove hardcoded script tags
The template had a stale hardcoded <script> tag from a previous build
output, causing react-scripts to inject a second script reference on
every new build. Restored to proper CRA template with %PUBLIC_URL%
placeholders.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 20:09:50 +01:00
ea0ce62290 Add Weapons tab showing all 73 weapons from rulebooks
Adds a new WeaponsTab component with:
- Filterable table of all 73 weapons from scrape-rulebooks.py
- Filter by category: Ranged, Melee, Grenade, Armour, Other
- Text search across name, damage, special rules, source
- Click-to-expand detail panel with full stats
- Parses both ranged (semicolon-separated) and melee (structured) stat formats

Tab is visible to all users (not GM-restricted).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 19:43:19 +01:00
585584d6c2 Add comprehensive rulebook scraper for all Deathwatch PDFs
Extracts from CR, FF, RoB, MoX, HtC:
- 36+ weapons (ranged + melee) from Core Rulebook
- 37 talents, 16 traits, 11 weapon qualities
- 89 psychic powers
- 99+ bestiary entries from Mark of the Xenos
- 1100+ lore/chapter entries across all books
- 123 speciality entries
- Total: 3415 rules, 228 bestiary entries in DB

Uses PyMuPDF (fitz) for text blocks and pdfplumber for table extraction.
PDFs are stored on NFS and not in git.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 19:37:12 +01:00
91bd25fbac Ignore rulebook PDFs from git (stored on NFS)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 19:18:22 +01:00
40fdd113e8 Add missing items to shop: Heavy Bolter, Crozius Arcanum, Servo-arm, Mechadendrite, Rosarius
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 18:43:00 +01:00
768fdfd419 Add PM2 restart_delay and max_restarts to prevent crash-loop spam
When DB_PASSWORD is missing on startup, server exits and PM2 was
restarting every ~660ms flooding backend.log with ER_ACCESS_DENIED_ERROR.
Now waits 5s between restarts and caps at 10 attempts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 18:31:32 +01:00
6c9bde7710 Remove obsolete one-shot import scripts
import-rules.js, import-armour.js, import-all.js were used once during
initial data import and have been superseded by the scripts/ directory.
All hardcoded wrong passwords (dwroller2025).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 18:27:47 +01:00