Add rolemaster situational roll modifier backend

This commit is contained in:
2026-04-14 23:42:25 +02:00
parent 9e91fb2719
commit 368a9a4960
14 changed files with 185 additions and 33 deletions

View File

@@ -13,18 +13,18 @@ The important user-visible rule is that this temporary modifier must be applied
## Progress
- [x] (2026-04-14 21:27:50Z) Created the initial ExecPlan in `TASKS.md`, grounded in the current workspace play flow, API contract, and Rolemaster retry implementation.
- [ ] Add transient situational modifier support to the skill-roll API and service pipeline without persisting anything on `Skill` or in the database schema.
- [x] (2026-04-14 21:39:42Z) Added transient `SituationalModifier` support to the skill-roll request, API endpoint, service facade, and roll pipeline without adding persistence or schema changes.
- [ ] Add a Rolemaster-only pre-roll modal on the play screen with autofocus, Escape dismissal, Enter submit, outside-click dismissal, and inline validation for signed integer input.
- [ ] Update Rolemaster roll execution and breakdown formatting so the situational modifier is shown explicitly and participates in retry-band evaluation and retry attempts.
- [ ] Add service, API, and Playwright coverage for the new behavior; update `README.md`; run `jb cleanupcode --build=False ...`; run `pwsh ./scripts/ci-local.ps1`; commit the iteration.
- [x] (2026-04-14 21:39:42Z) Updated Rolemaster roll execution and breakdown formatting so temporary modifiers are shown explicitly and feed retry-band evaluation plus retry attempts.
- [ ] Add service, API, and Playwright coverage for the new behavior; update `README.md`; run `jb cleanupcode --build=False ...`; run `pwsh ./scripts/ci-local.ps1`; commit the iteration (completed: service and API coverage plus `README.md`; remaining: Playwright coverage, cleanup, full CI, commit).
## Surprises & Discoveries
- Observation: `TASKS.md` was empty before this plan was written, so this ExecPlan now defines the full intended work from scratch.
Evidence: `Get-Item D:\Code\RpgRoller\TASKS.md | Format-List Length` reported `Length : 0`.
- Observation: the current skill-roll request only carries visibility, so there is no existing place to send a one-shot situational modifier from the client to the server.
Evidence: `RpgRoller/Contracts/ApiContracts.cs` currently defines `public sealed record RollSkillRequest(string Visibility);`.
- Observation: the situational modifier fit cleanly as transient request data. No `Skill`, `RollLogEntry`, migration, or EF model change was needed for the first implementation slice.
Evidence: the change only touched `RollSkillRequest`, the roll endpoint/service path, and Rolemaster roll formatting/execution files.
- Observation: the current Rolemaster retry rule is already based on the fully computed first attempt total, not just the raw die result, which matches the new requirement once the temporary modifier is included in that total.
Evidence: `RpgRoller/Services/RolemasterRollEngine.cs` resolves retry bands from `firstAttempt.Total`.
@@ -32,6 +32,9 @@ The important user-visible rule is that this temporary modifier must be applied
- Observation: the repository already uses Blazor modal patterns with overlays and `ElementReference.FocusAsync()` for autofocus, so the new modal can follow an existing local pattern instead of inventing a second approach.
Evidence: `RpgRoller/Components/Pages/HomeControls/SkillFormModal.razor(.cs)` renders a modal and focuses the name input in `OnAfterRenderAsync`.
- Observation: compact Rolemaster retry summaries still preview the trigger die, not the fully modified first-attempt arithmetic. The authoritative arithmetic belongs in the breakdown string.
Evidence: with a situational modifier, the new service test now expects `8 | open-ended | retry +5` in the compact summary while the detailed breakdown is `8+50+20=78; retry(+5): 42+50+20=112; final=117`.
## Decision Log
- Decision: the situational modifier will be transient request data only and will not be stored on `Skill`, `RollLogEntry`, or in a migration.
@@ -60,7 +63,7 @@ The important user-visible rule is that this temporary modifier must be applied
## Outcomes & Retrospective
No implementation has started yet. The current outcome is a concrete, repository-specific execution plan that resolves the major design choices up front: the modifier is transient, Rolemaster-only, included in retry-band evaluation, and exposed through a dedicated modal in the workspace play flow. The feature will be complete when a novice can follow this plan, roll a Rolemaster skill with `+20`, and observe the same `+20` in both the first attempt and the retry attempt breakdown.
The first implementation slice is complete on the backend. Rolemaster skill-roll requests can now carry a transient situational modifier through the API and service pipeline, Rolemaster breakdowns show that modifier explicitly, and automatic retry math reuses the same modifier on both attempts. Service and API tests now prove standard-roll arithmetic, retry-trigger arithmetic, and the Rolemaster-only server guard. The browser play flow is still pending because the dedicated pre-roll modal has not been added yet.
## Context and Orientation
@@ -188,3 +191,4 @@ In `RpgRoller/Components/Pages/HomeControls/SkillGroupBlock.razor.cs` and `Chara
Create a new modal component at `RpgRoller/Components/Pages/HomeControls/RolemasterSkillRollModal.razor` and `.razor.cs` that accepts at least the visibility flag, skill label, expression label, raw modifier text, submit state, and confirm/cancel callbacks. The component should use only existing Blazor and repository dependencies; no third-party modal library is required or desired.
Plan revision note (2026-04-14 / Codex): created the initial ExecPlan for the new Rolemaster one-shot situational modifier modal because `TASKS.md` was empty and the feature needs a self-contained implementation guide before coding begins.
Plan revision note (2026-04-14 / Codex): updated the living plan after the first backend slice landed so progress, discoveries, and retrospective match the new transient request path, explicit breakdown formatting, and added service/API coverage.