Skip to content

feat(web): interactive character screen — clickable rolls, telemetry rail, vitals bars#37

Merged
StreamDemon merged 3 commits into
mainfrom
feat/interactive-sheet
Jul 4, 2026
Merged

feat(web): interactive character screen — clickable rolls, telemetry rail, vitals bars#37
StreamDemon merged 3 commits into
mainfrom
feat/interactive-sheet

Conversation

@StreamDemon

@StreamDemon StreamDemon commented Jul 4, 2026

Copy link
Copy Markdown
Owner

PR C of #10closes #10. The dossier becomes the DESIGN.md character screen, and the sheet becomes playable.

What''s here

  • Field telemetry rail (right-hand band per the design): a role="log" feed that follows new entries, toned to the signal system (amber machine voice, cyan magic, green/red verdicts), with the blinking phosphor cursor. Roll Vitals moves here as a quick action.
  • Clickable rolls, client-side through the isomorphic engine (rollSave / rollSkillCheck / rollD20 from Dice rolling for the live sheet #7): every save (except percentile coma/death), skill, spell, and strike/parry/dodge row rolls on click and prints — > SKILL :: WILDERNESS SURVIVAL d%[69] vs 40% ✗, > SAVE VS MAGIC :: d20[14]+0 = 14, > CAST :: ENERGY BOLT — 5 P.P.E.. Ephemeral by design: gameplay rolls are moments at the table, not records; only rollVitals persists (existing mutation), and it logs its locked results.
  • Vitals as resource bars: H.P. (blood gradient), S.D.C. (amber), P.P.E. (ley gradient with the pulsating cyan glow from DESIGN.md), filled by rolled value against the range maximum, empty until rolled. Ranges + rolled values still shown numerically.
  • Motion: scanline reveal on sheet load; a dot-matrix strike flash when a vital lands. The sheet''s <Match> is deliberately non-keyed now, so subscription pushes flow through SolidJS fine-grained reactivity (updating text nodes) instead of remounting the sheet — which is both the SolidJS-on-Convex story from Scaffold the web app (apps/web) #8 and what lets the flash observe value changes. Everything collapses under prefers-reduced-motion. Implemented in CSS keyframes; solid-motionone deferred until something needs actual choreography.
  • The wizard''s review preview renders the same SheetView read-only (no actions wired).

Verification

Drove the full loop in a real browser against the local deployment: rolled a save vs magic (informational — no fixed target, correct per the rules), a skill check with a failure verdict in blood red, a strike, cast a spell, and rolled vitals — the mutation persisted, the log printed H.P. 19 · S.D.C. 17 · P.P.E. 124 — LOCKED, the P.P.E. bar pulses, and the rail auto-followed. Zero console errors. Screenshot in session.

158 tests; per-package vp check and the production build are clean.

Deferred (future issues): damage tracking (bars show rolled = full), percentile-save rolls, P.P.E. spend-on-cast, portrait upload, weapons/attacks (#16).


Summary by cubic

Make the character sheet playable with clickable rolls and a right‑hand telemetry rail. Adds animated vitals bars and client‑side roll logic, and resets the telemetry feed when switching characters; closes #10.

  • New Features

    • Clickable rolls for saves (non‑percentile), skills, strike/parry/dodge, and spell casts; runs client‑side via @riftforge/rules (rollSave, rollSkillCheck, rollD20) and logs toned results to the telemetry rail.
    • Field telemetry rail (role="log") with auto‑follow and blinking cursor; moves Roll Vitals here and logs locked results.
    • Vitals as animated bars: H.P. (blood), S.D.C. (amber), P.P.E. (ley with pulse); fill by rolled value and keep numeric values.
    • Subtle motion: scanline reveal and strike flash; respects prefers-reduced-motion. Wizard review shows the same SheetView read‑only.
  • Bug Fixes

    • Drop in‑flight Roll Vitals results after a character switch to prevent logging to the wrong dossier.

Written for commit 2a8005b. Summary will update on new commits.

Review in cubic

…rail, vitals bars

PR C of #10, closing the issue: the dossier becomes the DESIGN.md
character screen and the sheet becomes playable.

- lib/telemetry.ts: the field-telemetry log store (capped, toned
  entries) + machineName/d20Line formatters
- components/telemetry-rail.tsx: the right-hand rail — role=log feed
  that follows new entries, blinking phosphor cursor, quick actions
  slot (Roll Vitals moves here per the design)
- SheetView: optional SheetActions make saves (non-percentile),
  skills, spells, and strike/parry/dodge rows clickable with amber
  hover + CLICK TO ROLL affordances; vitals render as resource bars
  (H.P. blood, S.D.C. amber, P.P.E. ley gradient with the pulsating
  glow) filled by rolled value vs range max; review preview stays
  read-only (no actions wired)
- gameplay rolls run CLIENT-SIDE through the isomorphic engine
  (rollSave/rollSkillCheck/rollD20 from #7) and print to the log —
  ephemeral by design; only rollVitals persists, and it logs its
  locked results
- motion: scanline reveal on sheet load; dot-matrix strike flash when
  a vital lands (fine-grained update — the sheet Match is non-keyed
  now, so subscription pushes update text nodes instead of remounting,
  which also lets the flash observe value changes); all effects
  collapse under prefers-reduced-motion; implemented in CSS keyframes
  (solid-motionone deferred until something needs real choreography)

Browser-verified: rolled a save, a skill check, a strike, cast a
spell, and rolled vitals — all printed to the rail with correct
verdict tones, the P.P.E. bar pulses, zero console errors.
158 tests, per-package checks and prod build clean.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/web/src/pages/character-sheet.tsx
The log store was created once per mounted page, so navigating between
/characters/:id routes carried one character''s roll history onto the
next dossier. createTelemetry gains reset(); the page resets to the
boot lines (and clears roll errors) on route-id change.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/web/src/pages/character-sheet.tsx
An async rollVitals resolving after navigation could log the previous
character''s result (or error) onto the new dossier. The handler
captures the id it rolled for and drops the outcome if the route moved.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Auto-approved: Adds clickable rolls, telemetry rail, and animated vitals bars to the character sheet. All changes are frontend-only, additive, and well-contained; no database, API, or core business logic changes.

Re-trigger cubic

@StreamDemon StreamDemon merged commit 24f98eb into main Jul 4, 2026
2 checks passed
@StreamDemon StreamDemon deleted the feat/interactive-sheet branch July 4, 2026 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Interactive character sheet UI

1 participant