Remove completed task tracker
This commit is contained in:
386
TASKS.md
386
TASKS.md
@@ -1,386 +0,0 @@
|
|||||||
# Rolemaster Support Plan
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
Extend the app with a new `rolemaster` ruleset that supports generic standard Rolemaster expressions plus the special open-ended percentile case:
|
|
||||||
|
|
||||||
1. Standard expressions: `NdS + x`, with an implicit dice count of `1` when no digit appears before `d`
|
|
||||||
2. Open-ended percentile: `d100! + x` with Rolemaster low-end and high-end behavior
|
|
||||||
|
|
||||||
The initial scope is only roll definition, validation, execution, logging, and UI support for generic standard Rolemaster rolls and open-ended percentile rolls. This does not include Rolemaster attack tables, critical tables, resistance rolls, maneuver tables, or character sheet math beyond the explicit roll modifier entered for a skill.
|
|
||||||
|
|
||||||
## Scope Assumptions
|
|
||||||
|
|
||||||
- A Rolemaster campaign chooses the new `rolemaster` ruleset at campaign creation time.
|
|
||||||
- Rolemaster skills are ruleset-specific and should not reuse D6-only options such as `WildDice` and `AllowFumble`.
|
|
||||||
- Open-ended percentile behavior is defined as:
|
|
||||||
- Roll the first `d100`.
|
|
||||||
- If the first roll is `96` or higher, roll another high-ended `d100` recursively and add it.
|
|
||||||
- If the first roll is less than or equal to the skill's configured fumble range, roll another high-ended `d100` recursively and subtract it.
|
|
||||||
- Recursive follow-up rolls are high-ended only.
|
|
||||||
- Standard Rolemaster rolls do not open-end and do not use a fumble range.
|
|
||||||
- The modifier `x` should be an integer.
|
|
||||||
- Negative modifiers are supported for Rolemaster only.
|
|
||||||
- D6 and D&D 5e keep their current non-negative modifier rules unless separately re-scoped in a future change.
|
|
||||||
- Existing D6 and D&D 5e behavior must remain unchanged.
|
|
||||||
- The migration must be validated against a copied temp-file instance of `RpgRoller/App_Data/rpgroller.development.db`, which currently contains a D6 campaign.
|
|
||||||
|
|
||||||
## Clarifications
|
|
||||||
|
|
||||||
- The Rolemaster modifier should allow negative values only for Rolemaster.
|
|
||||||
- The standard fumble range for open-ended percentile skills is `0-5`, but can be configured individually for each skill.
|
|
||||||
- The fumble range has to be guaranteed to be less than 96.
|
|
||||||
- Roll breakdown text format for low-ended subtraction: `12 (03) -97 -44 +15 = -114`
|
|
||||||
- Skill groups need to support Rolemaster defaults for all of these fields, to stay consistent with current prototype behavior
|
|
||||||
- Rolemaster uses expression parsing with canonical syntax:
|
|
||||||
- standard roll with implicit count: `d10`
|
|
||||||
- standard roll with explicit count: `15d10`
|
|
||||||
- standard percentile: `d100+4`
|
|
||||||
- open-ended percentile: `d100!+85`
|
|
||||||
- negative modifiers are valid only for Rolemaster, for example `d100-15`
|
|
||||||
- open-ended syntax is only valid for `d100!`
|
|
||||||
|
|
||||||
## Architecture Guardrails
|
|
||||||
|
|
||||||
- Keep minimal API endpoint handlers thin and continue to place gameplay validation and roll execution in services.
|
|
||||||
- Keep Blazor components focused on form state, rendering, and API orchestration; do not duplicate Rolemaster rules in component code.
|
|
||||||
- Keep request/response DTOs separate from domain/persistence models.
|
|
||||||
- Preserve the current lazy log-detail loading flow so Rolemaster detail stays out of hot list payloads.
|
|
||||||
- Prefer additive changes to contracts and storage over replacing current D6 / D&D shapes outright.
|
|
||||||
|
|
||||||
## Backward Compatibility
|
|
||||||
|
|
||||||
- Existing D6 and D&D 5e API request and response fields must remain valid throughout the Rolemaster rollout.
|
|
||||||
- Existing persisted skills, skill groups, and roll log rows must continue to load without migration-time data loss.
|
|
||||||
- Startup migration against the existing development SQLite database shape must succeed without data loss or post-migration behavior regressions for legacy D6 data.
|
|
||||||
- Any richer die metadata must deserialize safely for old rows that only contain the current `RollDieResult` shape.
|
|
||||||
- Payload budgets for roster, log page, roll mutation responses, and lazy-loaded roll detail must remain explicitly guarded by tests.
|
|
||||||
|
|
||||||
## Design Direction
|
|
||||||
|
|
||||||
### 1. Add a new ruleset
|
|
||||||
|
|
||||||
Introduce `RulesetKind.Rolemaster` and expose it through `DiceRules` and campaign ruleset APIs.
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Add `Rolemaster` to `RulesetKind`.
|
|
||||||
- Update `DiceRules.TryParseRulesetId`.
|
|
||||||
- Update `DiceRules.ToRulesetId`.
|
|
||||||
- Add `rolemaster` to `DiceRules.SupportedRulesets`.
|
|
||||||
- Update tests that enumerate supported rulesets and campaign creation behavior.
|
|
||||||
|
|
||||||
Affected areas:
|
|
||||||
- `RpgRoller/Domain/GameModels.cs`
|
|
||||||
- `RpgRoller/Services/DiceRules.cs`
|
|
||||||
- `RpgRoller/Contracts/ApiContracts.cs`
|
|
||||||
- related service and API tests
|
|
||||||
|
|
||||||
### 2. Refactor skill definition from "expression + D6 options" to "ruleset-aware roll definition"
|
|
||||||
|
|
||||||
The current model is D6-shaped:
|
|
||||||
- `DiceRollDefinition`
|
|
||||||
- `WildDice`
|
|
||||||
- `AllowFumble`
|
|
||||||
|
|
||||||
That shape is not a clean fit for Rolemaster. The Rolemaster extension should still preserve expression parsing, but it needs a ruleset-aware internal definition so the app can validate, execute, and display Rolemaster rolls safely.
|
|
||||||
|
|
||||||
Recommended model additions:
|
|
||||||
- Keep existing fields working for D6 and D&D 5e.
|
|
||||||
- Preserve `DiceRollDefinition` as the authoritative user-facing input for D6, D&D 5e, and Rolemaster.
|
|
||||||
- Add only the extra Rolemaster fields that cannot be encoded cleanly in the expression itself, specifically the fumble range.
|
|
||||||
- Centralize parsing and validation into a single ruleset-aware validator that returns a canonical internal representation.
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Define a ruleset-aware skill definition model in domain/contracts.
|
|
||||||
- Keep `DiceRollDefinition` as persisted state and define canonical formatting rules for Rolemaster expressions.
|
|
||||||
- Add mapping helpers so UI and API get a stable, ruleset-aware DTO.
|
|
||||||
- Ensure skill groups can store the same Rolemaster defaults as skills.
|
|
||||||
|
|
||||||
Affected areas:
|
|
||||||
- `RpgRoller/Domain/GameModels.cs`
|
|
||||||
- `RpgRoller/Contracts/ApiContracts.cs`
|
|
||||||
- `RpgRoller/Services/GameService.cs`
|
|
||||||
- `RpgRoller/Components/Pages/Home.Models.cs`
|
|
||||||
|
|
||||||
### 3. Add Rolemaster-specific validation
|
|
||||||
|
|
||||||
Current validation is split between generic expression parsing and D6 option validation. Rolemaster needs its own validation layer.
|
|
||||||
|
|
||||||
Validation rules to add:
|
|
||||||
- standard Rolemaster expressions
|
|
||||||
- supports generic `NdS` syntax with any supported side count
|
|
||||||
- assumes a dice count of `1` when the count is omitted before `d`
|
|
||||||
- integer modifier required
|
|
||||||
- no fumble range
|
|
||||||
- `RolemasterOpenEndedPercentile`
|
|
||||||
- fixed base roll `1d100`
|
|
||||||
- integer modifier required
|
|
||||||
- fumble range required and validated
|
|
||||||
- fumble range must be below `96`
|
|
||||||
- reject D6-only options for Rolemaster skills
|
|
||||||
- reject Rolemaster-only fields for D6 / D&D 5e skills
|
|
||||||
- reject negative modifiers for D6 / D&D 5e expressions
|
|
||||||
- accept negative modifiers for Rolemaster expressions only
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Replace or extend `ValidateSkillDefinition`.
|
|
||||||
- Extend `DiceRules.ParseExpression` with a Rolemaster-focused parser/validator path.
|
|
||||||
- Add canonical Rolemaster expression parsing rules:
|
|
||||||
- `d10`, `2d10+48`, and `15d10-15` for generic standard rolls
|
|
||||||
- `d100+4` and `d100-20` for standard percentile
|
|
||||||
- `d100!+85` and `d100!-15` for open-ended percentile
|
|
||||||
- reject open-ended syntax for non-percentile or multi-die expressions such as `2d10!+1`
|
|
||||||
- Keep Rolemaster fumble range validation separate from the expression because it is configured independently.
|
|
||||||
- Add canonical display formatting for Rolemaster skills, for example:
|
|
||||||
- `Rolemaster: d10`
|
|
||||||
- `Rolemaster: 15d10+15`
|
|
||||||
- `Open-ended percentile: OE 1d100+48, fumble <= 5`
|
|
||||||
- Add explicit regression tests that D6 / D&D still reject negative modifiers after Rolemaster support lands.
|
|
||||||
|
|
||||||
Affected areas:
|
|
||||||
- `RpgRoller/Services/DiceRules.cs`
|
|
||||||
- `RpgRoller/Services/GameService.cs`
|
|
||||||
- `RpgRoller.Tests/Services/DiceRulesTests.cs`
|
|
||||||
- `RpgRoller.Tests/Services/ServiceSkillGroupAndOwnershipTests.cs`
|
|
||||||
- `RpgRoller.Tests/Services/ServiceSkillRollTests.cs`
|
|
||||||
|
|
||||||
### 4. Implement Rolemaster roll execution
|
|
||||||
|
|
||||||
Add a new Rolemaster execution path alongside the existing D6 and standard roll logic.
|
|
||||||
|
|
||||||
Recommended internal shape:
|
|
||||||
- `ComputeRoll` dispatches by ruleset and roll kind.
|
|
||||||
- Add dedicated methods:
|
|
||||||
- `ComputeRolemasterStandardRoll`
|
|
||||||
- `ComputeRolemasterOpenEndedRoll`
|
|
||||||
- helper `RollRolemasterHighOpenEndedChain`
|
|
||||||
|
|
||||||
Open-ended algorithm:
|
|
||||||
- Roll first `d100`.
|
|
||||||
- Start total with first roll.
|
|
||||||
- If first roll `>= 96`:
|
|
||||||
- roll one or more high-ended follow-up `d100`s
|
|
||||||
- add all follow-up rolls
|
|
||||||
- Else if first roll `<= fumble range`:
|
|
||||||
- roll one or more high-ended follow-up `d100`s
|
|
||||||
- subtract the follow-up total
|
|
||||||
- Apply modifier after base/follow-up math.
|
|
||||||
- Produce a full breakdown string.
|
|
||||||
- Persist enough die detail to reconstruct the event in log detail and UI.
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Extend `ComputeRoll` dispatch.
|
|
||||||
- Add Rolemaster-specific roll methods.
|
|
||||||
- Parse Rolemaster expressions into an internal roll definition before execution rather than branching on raw strings in multiple places.
|
|
||||||
- Decide whether the current `RollDieResult` DTO is sufficient.
|
|
||||||
- likely not sufficient, because it only has `Crit`, `Fumble`, `Wild`, `Removed`, `Added`
|
|
||||||
- Recommended DTO extension:
|
|
||||||
- `Sequence` or `Order`
|
|
||||||
- `Phase` / `Kind` such as `initial`, `open-ended-high`, `open-ended-low-subtract`
|
|
||||||
- `SignedContribution` or equivalent metadata for subtraction
|
|
||||||
- Update log summary generation so Rolemaster rolls remain understandable in compact log entries without bloating list payloads.
|
|
||||||
- Keep lazy detail expansion as the place where the full Rolemaster breakdown and rich die metadata are loaded.
|
|
||||||
|
|
||||||
Affected areas:
|
|
||||||
- `RpgRoller/Services/GameService.cs`
|
|
||||||
- `RpgRoller/Contracts/ApiContracts.cs`
|
|
||||||
- `RpgRoller/Contracts/RpgRollerJsonSerializerContext.cs`
|
|
||||||
- `RpgRoller/Components/Pages/HomeControls/RollDiceStrip.razor.cs`
|
|
||||||
|
|
||||||
### 5. Update persistence and migrations
|
|
||||||
|
|
||||||
Rolemaster support needs persisted structured fields for skills and skill groups, and possibly richer serialized roll-die details.
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Update `Skill` and `SkillGroup` EF models.
|
|
||||||
- Update `RpgRollerDbContext` configuration.
|
|
||||||
- Add EF Core migration for new Rolemaster fields.
|
|
||||||
- Preserve existing data for D6 / D&D 5e campaigns.
|
|
||||||
- Decide migration defaults for legacy rows.
|
|
||||||
- Update `SqliteSchemaUpgrader` coverage expectations if schema assumptions change.
|
|
||||||
- Verify serialized roll log payloads remain readable for old entries after DTO extension.
|
|
||||||
- Ensure additive schema changes allow mixed old/new data during migration and startup upgrade.
|
|
||||||
- Validate the real startup migration path against a copied temp-file instance of `RpgRoller/App_Data/rpgroller.development.db`.
|
|
||||||
- Verify that the migrated copy still loads the existing D6 campaign data and that legacy D6 skills remain rollable after startup migration.
|
|
||||||
|
|
||||||
Data migration recommendations:
|
|
||||||
- Legacy D6 / D&D 5e skills should retain current behavior with deterministic defaults.
|
|
||||||
- New Rolemaster fields should be nullable or have safe defaults during migration.
|
|
||||||
- Avoid destructive migration patterns; favor additive schema evolution.
|
|
||||||
- Never run destructive migration verification against the source development DB file; always copy it first and test the copy.
|
|
||||||
|
|
||||||
Affected areas:
|
|
||||||
- `RpgRoller/Data/RpgRollerDbContext.cs`
|
|
||||||
- `RpgRoller/Migrations/*`
|
|
||||||
- `RpgRoller/Hosting/SqliteSchemaUpgrader.cs`
|
|
||||||
- `RpgRoller.Tests/HostingCoverageTests.cs`
|
|
||||||
|
|
||||||
### 6. Expose Rolemaster in APIs and frontend models
|
|
||||||
|
|
||||||
The UI currently assumes only `IsD6` versus "not D6". That binary split will not scale to Rolemaster.
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Replace `IsD6` branching with a ruleset-aware UI model.
|
|
||||||
- Extend skill and skill-group request/response contracts with Rolemaster fields.
|
|
||||||
- Ensure campaign creation UI includes `Rolemaster` in the ruleset picker.
|
|
||||||
- Update workspace models and display helpers so Rolemaster skill summaries render correctly.
|
|
||||||
|
|
||||||
Recommended frontend model changes:
|
|
||||||
- Introduce ruleset-aware form state rather than raw D6 toggles.
|
|
||||||
- Keep "Expression" as the primary input, and provide Rolemaster-specific help text, examples, and validation when the selected campaign ruleset is `rolemaster`.
|
|
||||||
- Show fumble range input only when the current Rolemaster expression is an open-ended percentile roll.
|
|
||||||
- Use progressive disclosure so only the fields relevant to the current Rolemaster expression are shown.
|
|
||||||
- Add inline validation on blur and submit, visible required indicators, and `aria-live` / alert semantics for validation errors.
|
|
||||||
- Preserve the existing app visual language instead of introducing a separate Rolemaster-specific theme.
|
|
||||||
|
|
||||||
Affected areas:
|
|
||||||
- `RpgRoller/Contracts/ApiContracts.cs`
|
|
||||||
- `RpgRoller/Components/Pages/Home.Models.cs`
|
|
||||||
- `RpgRoller/Components/Pages/HomeControls/SkillFormModal.razor`
|
|
||||||
- `RpgRoller/Components/Pages/HomeControls/SkillFormModal.razor.cs`
|
|
||||||
- `RpgRoller/Components/Pages/HomeControls/CharacterPanel.razor`
|
|
||||||
- `RpgRoller/Components/Pages/HomeControls/CharacterPanel.razor.cs`
|
|
||||||
- `RpgRoller/Components/Pages/Workspace.razor.cs`
|
|
||||||
|
|
||||||
### 7. Update roll visualization and log readability
|
|
||||||
|
|
||||||
Rolemaster open-ended rolls will be hard to interpret if they reuse the current D6-oriented chip styling without extra context.
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Extend `RollDiceStrip` to distinguish:
|
|
||||||
- initial percentile roll
|
|
||||||
- added high-open-ended rolls
|
|
||||||
- subtracted low-end follow-up rolls
|
|
||||||
- Add tooltip or title text that explains each die's role in the chain.
|
|
||||||
- Update compact log summaries so they surface open-ended behavior.
|
|
||||||
- Ensure private/public visibility behavior remains unchanged.
|
|
||||||
- Keep roll list rows dense and readable; reserve multi-line breakdown detail for expanded rows or detail fetches.
|
|
||||||
|
|
||||||
Recommended display goals:
|
|
||||||
- A normal percentile roll should read as simple and uncluttered.
|
|
||||||
- A high-open-ended roll should clearly show chained additions.
|
|
||||||
- A low-ended roll should clearly show subtraction, not just a list of numbers.
|
|
||||||
|
|
||||||
Affected areas:
|
|
||||||
- `RpgRoller/Components/Pages/HomeControls/RollDiceStrip.razor`
|
|
||||||
- `RpgRoller/Components/Pages/HomeControls/RollDiceStrip.razor.cs`
|
|
||||||
- `RpgRoller/Components/Pages/Workspace.razor.cs`
|
|
||||||
- `RpgRoller/Services/GameService.cs`
|
|
||||||
|
|
||||||
### 8. Expand tests to preserve behavior and coverage
|
|
||||||
|
|
||||||
This repo expects very high coverage and already has strong service/API regression tests. Rolemaster support should land with exhaustive tests, not just happy paths.
|
|
||||||
|
|
||||||
Service-level tests to add:
|
|
||||||
- parse and ruleset mapping for `rolemaster`
|
|
||||||
- skill creation validation for each Rolemaster roll type
|
|
||||||
- rejection of invalid fumble ranges
|
|
||||||
- rejection of D6-only options on Rolemaster skills
|
|
||||||
- rejection of negative modifiers on D6 / D&D skills
|
|
||||||
- acceptance of negative modifiers on Rolemaster expressions
|
|
||||||
- generic standard Rolemaster roll math
|
|
||||||
- standard percentile roll math
|
|
||||||
- open-ended high roll with one extra roll
|
|
||||||
- open-ended high roll with recursive extra rolls
|
|
||||||
- open-ended low roll with subtraction
|
|
||||||
- open-ended low roll where the subtract chain itself recursively high-opens
|
|
||||||
- breakdown formatting and die metadata correctness
|
|
||||||
|
|
||||||
API tests to add:
|
|
||||||
- create Rolemaster campaign
|
|
||||||
- create/update skill groups with Rolemaster defaults
|
|
||||||
- create/update Rolemaster skills
|
|
||||||
- roll each Rolemaster skill type via API
|
|
||||||
- verify log page and detail endpoints for Rolemaster rolls
|
|
||||||
- verify old D6 / D&D contracts still round-trip without requiring Rolemaster-only fields
|
|
||||||
- verify that a migrated copy of `RpgRoller/App_Data/rpgroller.development.db` still supports legacy D6 API flows after startup migration
|
|
||||||
|
|
||||||
Frontend/regression checks:
|
|
||||||
- Rolemaster ruleset appears in campaign creation UI
|
|
||||||
- Rolemaster skill form shows correct conditional fields
|
|
||||||
- roll results render correctly for open-ended cases
|
|
||||||
- validation errors are announced and visible for invalid Rolemaster expressions / fumble ranges
|
|
||||||
- the compact log remains readable and detail expansion shows the full Rolemaster breakdown
|
|
||||||
|
|
||||||
Coverage-sensitive files likely needing tests:
|
|
||||||
- `RpgRoller.Tests/Services/DiceRulesTests.cs`
|
|
||||||
- `RpgRoller.Tests/Services/ServiceSkillRollTests.cs`
|
|
||||||
- new dedicated `Rolemaster` service tests
|
|
||||||
- `RpgRoller.Tests/Api/CampaignApiTests.cs`
|
|
||||||
- `RpgRoller.Tests/HostingCoverageTests.cs`
|
|
||||||
- `RpgRoller.Tests/PayloadBudgetTests.cs`
|
|
||||||
|
|
||||||
### 9. Documentation updates
|
|
||||||
|
|
||||||
The repository instructions require related docs to be updated whenever behavior changes.
|
|
||||||
|
|
||||||
Tasks:
|
|
||||||
- Update `README.md` to list `Rolemaster` as a supported ruleset.
|
|
||||||
- Document the three supported Rolemaster roll types.
|
|
||||||
- Document the open-ended percentile algorithm, including:
|
|
||||||
- `96+` recursive addition
|
|
||||||
- `<= fumble range` recursive subtraction
|
|
||||||
- Document any limits on modifier and fumble range values.
|
|
||||||
- If API contracts change materially, update `openapi/RpgRoller.json`.
|
|
||||||
|
|
||||||
### 10. Delivery plan in small iterations
|
|
||||||
|
|
||||||
Recommended implementation order:
|
|
||||||
|
|
||||||
#### Iteration 1: ruleset plumbing
|
|
||||||
- Add `Rolemaster` ruleset enum/id/display support.
|
|
||||||
- Add campaign creation support.
|
|
||||||
- Add parser/validator scaffolding for Rolemaster expressions and Rolemaster-only negative modifier support.
|
|
||||||
- Add baseline tests for ruleset mapping and validation.
|
|
||||||
|
|
||||||
#### Iteration 2: structured skill model
|
|
||||||
- Preserve `DiceRollDefinition` as the canonical persisted expression and add only the extra persisted Rolemaster fields the expression cannot represent.
|
|
||||||
- Add migration and schema tests.
|
|
||||||
- Add startup-migration validation against a copied temp-file instance of `RpgRoller/App_Data/rpgroller.development.db`.
|
|
||||||
- Update API contracts and service mapping.
|
|
||||||
- Keep existing D6 / D&D behavior green.
|
|
||||||
|
|
||||||
#### Iteration 3: roll engine
|
|
||||||
- Implement generic standard and standard percentile execution.
|
|
||||||
- Implement open-ended percentile execution with recursive high-end chaining and low-end subtraction.
|
|
||||||
- Extend die-result metadata and breakdown formatting.
|
|
||||||
- Add focused service tests for roll math and payload/detail serialization compatibility.
|
|
||||||
|
|
||||||
#### Iteration 4: frontend editing
|
|
||||||
- Update campaign ruleset selection UI.
|
|
||||||
- Replace D6-only form branching with ruleset-aware skill editing.
|
|
||||||
- Support Rolemaster skill groups and skills in create/edit flows.
|
|
||||||
- Add accessible inline validation and progressive disclosure to the Rolemaster editor.
|
|
||||||
- Verify with ephemeral Playwright.
|
|
||||||
|
|
||||||
#### Iteration 5: log/detail polish and docs
|
|
||||||
- Improve roll chip rendering and compact summaries for Rolemaster.
|
|
||||||
- Re-run payload-budget checks and confirm lazy detail loading still holds.
|
|
||||||
- Update README/OpenAPI/docs.
|
|
||||||
- Run full local CI and coverage checks.
|
|
||||||
|
|
||||||
## Risks
|
|
||||||
|
|
||||||
- The current skill contract is tightly coupled to D6-era fields, so a shallow patch will create long-term complexity.
|
|
||||||
- The current `RollDieResult` type is too generic for clear Rolemaster open-ended auditing.
|
|
||||||
- Allowing negative Rolemaster modifiers requires carefully scoping validation changes so D6/D&D rules do not loosen unintentionally.
|
|
||||||
- Migration design needs care to avoid breaking legacy SQLite databases.
|
|
||||||
- A migration that works on an empty test database but fails on the existing D6 production-shaped database would be a release blocker.
|
|
||||||
- UI complexity will grow if ruleset-specific fields are bolted onto the current `IsD6` logic instead of replacing it with a ruleset-aware form model.
|
|
||||||
- Richer Rolemaster die metadata could regress payload sizes or list readability if detail is not kept behind the existing lazy-load flow.
|
|
||||||
|
|
||||||
## Recommended Acceptance Criteria
|
|
||||||
|
|
||||||
- A campaign can be created with ruleset id `rolemaster`.
|
|
||||||
- Rolemaster skill groups and skills can be created and edited through API and UI.
|
|
||||||
- Supported Rolemaster roll types are:
|
|
||||||
- generic standard rolls `NdS + x`, with implicit dice count `1` for `dS`
|
|
||||||
- open-ended percentile `d100! + x` with fumble range
|
|
||||||
- Open-ended percentile rolls correctly:
|
|
||||||
- add recursively on first-roll `96+`
|
|
||||||
- subtract a recursive high-end chain on first-roll `<= fumble range`
|
|
||||||
- Roll logs and detail views clearly show how a Rolemaster result was produced.
|
|
||||||
- Existing D6 and D&D 5e flows remain unchanged.
|
|
||||||
- App startup successfully migrates a copied temp-file instance of `RpgRoller/App_Data/rpgroller.development.db`.
|
|
||||||
- The migrated copy preserves the existing D6 campaign data and passes legacy D6 read/roll regression checks after startup migration.
|
|
||||||
- Local CI, coverage checks, and frontend verification all pass.
|
|
||||||
Reference in New Issue
Block a user