Add player character management feature
Persistent player character templates (name, AC, HP, color, icon) with full CRUD, bestiary-style search to add PCs to encounters with pre-filled stats, and color/icon visual distinction in combatant rows. Also stops the stat block panel from auto-opening when adding a creature. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
262
specs/005-player-characters/spec.md
Normal file
262
specs/005-player-characters/spec.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# Feature Specification: Player Character Management
|
||||
|
||||
**Feature Branch**: `005-player-characters`
|
||||
**Created**: 2026-03-12
|
||||
**Status**: Draft
|
||||
**Input**: User description: "Allow users to create and manage Player characters via the bottom bar. Each player character has a name, AC, max HP, a chosen color, and a preset icon. Player characters persist across sessions and are searchable when adding combatants to an encounter. A dedicated management view lets users edit and delete existing player characters."
|
||||
|
||||
## User Scenarios & Testing *(mandatory)*
|
||||
|
||||
### Creating Player Characters
|
||||
|
||||
**Story PC-1 — Create a new player character (Priority: P1)**
|
||||
|
||||
A game master opens a "Create Player" modal from the bottom bar and fills in the character's name, AC, max HP, selects a color from a palette, and picks an icon from a preset grid. On saving, the player character is persisted and available for future encounters.
|
||||
|
||||
**Why this priority**: Creating player characters is the foundational action — nothing else in this feature works without it.
|
||||
|
||||
**Independent Test**: Can be fully tested by creating a player character and verifying it appears in the saved player list.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** the bottom bar is visible, **When** the user clicks the "Create Player" icon button, **Then** a modal opens with fields for Name, AC, Max HP, a color palette, and an icon selection grid.
|
||||
|
||||
2. **Given** the create player modal is open, **When** the user fills in Name "Aragorn", AC 16, Max HP 120, selects the color green, and selects the shield icon, **Then** clicking save creates a player character with those attributes and closes the modal.
|
||||
|
||||
3. **Given** no player characters exist, **When** the user creates their first player character, **Then** it is persisted and appears in the player character list.
|
||||
|
||||
4. **Given** the create player modal is open, **When** the user submits with an empty name, **Then** a validation error is shown and the player character is not created.
|
||||
|
||||
5. **Given** the create player modal is open, **When** the user submits with a whitespace-only name, **Then** a validation error is shown and the player character is not created.
|
||||
|
||||
6. **Given** the create player modal is open, **When** the user clicks cancel or closes the modal, **Then** no player character is created and any entered data is discarded.
|
||||
|
||||
---
|
||||
|
||||
### Player Character Persistence
|
||||
|
||||
**Story PC-2 — Player characters survive page reload (Priority: P1)**
|
||||
|
||||
Player characters are long-lived entities that persist across browser sessions. Unlike encounter combatants which belong to a single encounter, player characters represent recurring party members that the GM reuses across many encounters.
|
||||
|
||||
**Why this priority**: Without persistence, users would need to recreate their party every session, defeating the purpose.
|
||||
|
||||
**Independent Test**: Can be tested by creating a player character, reloading the page, and verifying it still exists.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** the user has created player characters, **When** the page is reloaded, **Then** all player characters are restored with their name, AC, max HP, color, and icon intact.
|
||||
|
||||
2. **Given** saved player character data is corrupt or malformed, **When** the page loads, **Then** the application starts with an empty player character list without crashing.
|
||||
|
||||
3. **Given** no saved player character data exists, **When** the page loads, **Then** the application starts with an empty player character list.
|
||||
|
||||
---
|
||||
|
||||
### Adding Player Characters to Encounters
|
||||
|
||||
**Story PC-3 — Search and add player characters as combatants (Priority: P1)**
|
||||
|
||||
When adding combatants to an encounter, the GM can search for their saved player characters by name. Selecting a player character adds it as a combatant with its saved stats (AC, max HP) pre-filled, along with its color and icon for visual identification.
|
||||
|
||||
**Why this priority**: This is the core value proposition — reusing pre-configured characters instead of re-entering stats every encounter.
|
||||
|
||||
**Independent Test**: Can be tested by creating a player character, then adding it to an encounter via the combatant search.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** player characters "Aragorn" and "Legolas" exist, **When** the user types "Ara" in the combatant search field, **Then** "Aragorn" appears in the search results alongside bestiary creatures.
|
||||
|
||||
2. **Given** player character "Aragorn" (AC 16, Max HP 120) exists, **When** the user selects "Aragorn" from search results, **Then** a combatant is added to the encounter with name "Aragorn", AC 16, max HP 120, current HP 120, and the player character's color and icon.
|
||||
|
||||
3. **Given** player character "Gandalf" exists, **When** the user adds "Gandalf" to two separate encounters (or the same encounter twice), **Then** each combatant is an independent copy — modifying one combatant's HP does not affect the other or the saved player character.
|
||||
|
||||
4. **Given** no player characters exist, **When** the user searches in the combatant search field, **Then** only bestiary creatures appear in results (no empty "Players" section is shown).
|
||||
|
||||
---
|
||||
|
||||
### Displaying Player Characters in Encounters
|
||||
|
||||
**Story PC-4 — Visual distinction for player character combatants (Priority: P2)**
|
||||
|
||||
Combatants originating from player characters display their chosen color and icon next to their name in the combatant row, making it easy to visually distinguish PCs from monsters at a glance.
|
||||
|
||||
**Why this priority**: Color and icon display enhances usability but the feature is functional without it.
|
||||
|
||||
**Independent Test**: Can be tested by adding a player character to an encounter and verifying the color and icon render in the combatant row.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a combatant was added from a player character with color green and the shield icon, **When** the combatant row is rendered, **Then** the player character's icon is displayed next to the name and the color is applied as a visual accent (e.g., colored border, background tint, or icon tint).
|
||||
|
||||
2. **Given** a combatant was added from the bestiary (not a player character), **When** the combatant row is rendered, **Then** no player character icon or color accent is shown.
|
||||
|
||||
---
|
||||
|
||||
### Managing Player Characters
|
||||
|
||||
**Story PC-5 — View all saved player characters (Priority: P2)**
|
||||
|
||||
The GM can access a dedicated management view to see all their saved player characters at a glance, with each character's name, AC, max HP, color, and icon displayed.
|
||||
|
||||
**Why this priority**: Management view is needed for editing and deleting, but basic create/add flow works without it.
|
||||
|
||||
**Independent Test**: Can be tested by creating several player characters and opening the management view to verify all are listed.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** player characters exist, **When** the user opens the player character management view, **Then** all saved player characters are listed showing their name, AC, max HP, color, and icon.
|
||||
|
||||
2. **Given** no player characters exist, **When** the user opens the management view, **Then** an empty state message is shown encouraging the user to create their first player character.
|
||||
|
||||
---
|
||||
|
||||
**Story PC-6 — Edit an existing player character (Priority: P2)**
|
||||
|
||||
The GM realizes a player character's stats have changed (e.g., level up) or wants to fix a typo. They open the management view and edit the character's attributes.
|
||||
|
||||
**Why this priority**: Editing is important for ongoing campaigns but the feature delivers value without it initially.
|
||||
|
||||
**Independent Test**: Can be tested by editing a player character's name and stats and verifying the changes persist.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** player character "Aragorn" exists, **When** the user edits "Aragorn" to change the name to "Strider" and AC to 18, **Then** the changes are saved and reflected in the player character list.
|
||||
|
||||
2. **Given** a player character is being edited, **When** the user submits with an empty name, **Then** a validation error is shown and the changes are not saved.
|
||||
|
||||
3. **Given** a player character is being edited, **When** the user cancels the edit, **Then** the original values are preserved.
|
||||
|
||||
4. **Given** a player character was previously added to an encounter as a combatant, **When** the player character is edited, **Then** existing combatants in the current encounter are not affected (they are independent copies).
|
||||
|
||||
---
|
||||
|
||||
**Story PC-7 — Delete a player character (Priority: P2)**
|
||||
|
||||
The GM no longer needs a player character and wants to remove it from their saved list.
|
||||
|
||||
**Why this priority**: Deletion keeps the list manageable but is not needed for core functionality.
|
||||
|
||||
**Independent Test**: Can be tested by deleting a player character and verifying it no longer appears in the list or search results.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** player character "Boromir" exists, **When** the user deletes "Boromir" with confirmation, **Then** the player character is removed from the saved list.
|
||||
|
||||
2. **Given** player character "Boromir" was previously added to the current encounter as a combatant, **When** the player character is deleted, **Then** the combatant in the encounter is not affected (it is an independent copy).
|
||||
|
||||
3. **Given** the delete action is initiated, **When** the user is asked to confirm, **Then** the confirmation follows the existing ConfirmButton two-step pattern (as defined in spec 001).
|
||||
|
||||
---
|
||||
|
||||
### Edge Cases
|
||||
|
||||
- **Duplicate player character names**: Permitted. Player characters are identified by a unique internal ID, not by name.
|
||||
- **Adding the same player character to an encounter multiple times**: Each addition creates an independent combatant copy. Multiple copies of the same PC in one encounter are allowed.
|
||||
- **Editing a player character while it is also a combatant in the active encounter**: The active combatant is not affected; only future additions use the updated stats.
|
||||
- **Deleting a player character while it is a combatant in the active encounter**: The combatant remains in the encounter unchanged.
|
||||
- **Very long player character names**: The UI should truncate or ellipsize names that exceed the available space.
|
||||
- **Browser storage quota exceeded**: Player character persistence silently fails; the current in-memory session continues.
|
||||
- **Corrupt player character data on load**: The application discards corrupt data and starts with an empty player character list.
|
||||
- **Color/icon rendering on different screen sizes**: Color and icon must remain visible and distinguishable at all supported viewport sizes.
|
||||
- **Search ranking**: When searching, player characters should appear in a distinct group (e.g., "Players" section) above or alongside bestiary results to make them easy to find.
|
||||
|
||||
---
|
||||
|
||||
## Requirements *(mandatory)*
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
#### FR-001 — Create: Modal via bottom bar
|
||||
The system MUST provide an icon button in the bottom bar that opens a "Create Player" modal.
|
||||
|
||||
#### FR-002 — Create: Required fields
|
||||
The create modal MUST include fields for Name (text), AC (number), and Max HP (number).
|
||||
|
||||
#### FR-003 — Create: Color selection
|
||||
The create modal MUST include a color palette allowing the user to select one color from a predefined set of distinguishable colors.
|
||||
|
||||
#### FR-004 — Create: Icon selection
|
||||
The create modal MUST include a grid of ~10-20 preset icons (e.g., sword, shield, skull, heart, wand) from which the user selects one.
|
||||
|
||||
#### FR-005 — Create: Name validation
|
||||
Creating a player character MUST reject empty or whitespace-only names, showing a validation error.
|
||||
|
||||
#### FR-006 — Create: Unique identity
|
||||
Each player character MUST be assigned a unique internal identifier on creation.
|
||||
|
||||
#### FR-007 — Persistence: Cross-session storage
|
||||
Player characters MUST be persisted to browser storage and restored on page load.
|
||||
|
||||
#### FR-008 — Persistence: Independent from encounter storage
|
||||
Player character storage MUST be separate from encounter storage — clearing an encounter does not affect saved player characters.
|
||||
|
||||
#### FR-009 — Persistence: Graceful degradation
|
||||
The system MUST NOT crash when player character data is missing, corrupt, or storage is unavailable. It MUST fall back to an empty player character list.
|
||||
|
||||
#### FR-010 — Search: Player characters in combatant search
|
||||
Player characters MUST appear in the combatant search results when the user searches for combatants to add to an encounter. Matching is by name substring.
|
||||
|
||||
#### FR-011 — Search: Distinct grouping
|
||||
Player character results MUST be visually distinguishable from bestiary creature results in the search dropdown.
|
||||
|
||||
#### FR-012 — Add to encounter: Pre-filled stats
|
||||
When a player character is added to an encounter as a combatant, the combatant MUST be created with the player character's name, AC, max HP, and current HP set to max HP.
|
||||
|
||||
#### FR-013 — Add to encounter: Color and icon association
|
||||
When a combatant is created from a player character, the combatant MUST carry the player character's color and icon for display purposes.
|
||||
|
||||
#### FR-014 — Add to encounter: Independent copy
|
||||
Combatants created from player characters MUST be independent copies. Changes to the combatant's stats during an encounter do not modify the saved player character, and vice versa.
|
||||
|
||||
#### FR-015 — Display: Color and icon in combatant row
|
||||
Combatant rows for player-character-originating combatants MUST display the chosen icon and color accent.
|
||||
|
||||
#### FR-016 — Management: View all player characters
|
||||
The system MUST provide a view listing all saved player characters with their name, AC, max HP, color, and icon.
|
||||
|
||||
#### FR-017 — Management: Edit player character
|
||||
The system MUST allow editing a player character's name, AC, max HP, color, and icon. Edits MUST be persisted.
|
||||
|
||||
#### FR-018 — Management: Delete player character
|
||||
The system MUST allow deleting a player character with two-step confirmation (ConfirmButton pattern from spec 001).
|
||||
|
||||
#### FR-019 — Management: Delete does not affect active combatants
|
||||
Deleting a player character MUST NOT remove or modify any combatants currently in an encounter.
|
||||
|
||||
### Key Entities
|
||||
|
||||
- **PlayerCharacter**: A persistent, reusable character template with a unique `PlayerCharacterId` (branded string), required `name`, `ac` (number), `maxHp` (number), `color` (string from predefined set), and `icon` (string identifier from preset icon set).
|
||||
- **PlayerCharacterStore** (port): Interface for loading, saving, and deleting player characters. Implemented as a browser storage adapter.
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria *(mandatory)*
|
||||
|
||||
### Measurable Outcomes
|
||||
|
||||
- **SC-001**: Users can create a player character with name, AC, max HP, color, and icon in under 30 seconds.
|
||||
- **SC-002**: Player characters persist across page reloads with all attributes intact.
|
||||
- **SC-003**: Player characters appear in combatant search results and can be added to an encounter in a single selection.
|
||||
- **SC-004**: Combatants created from player characters display their color and icon in the initiative tracker.
|
||||
- **SC-005**: Users can edit any attribute of a saved player character and see the change persisted immediately.
|
||||
- **SC-006**: Deleting a player character requires two deliberate user interactions (ConfirmButton pattern) and does not affect active encounter combatants.
|
||||
- **SC-007**: All player character domain operations (create, edit, delete) are pure functions with no I/O, consistent with the project's deterministic domain core.
|
||||
- **SC-008**: The player character domain module has zero imports from application, adapter, or UI layers.
|
||||
- **SC-009**: Corrupt or missing player character data never causes a crash — the application gracefully falls back to an empty player character list.
|
||||
|
||||
---
|
||||
|
||||
## Assumptions
|
||||
|
||||
- Player character IDs are generated by the caller (application layer), keeping domain functions pure.
|
||||
- The predefined color palette contains 8-12 visually distinct colors suitable for both light and dark backgrounds.
|
||||
- The preset icon set uses Lucide React icons already available in the project, requiring no additional icon dependencies.
|
||||
- Player characters are stored in a separate `localStorage` key from encounter data.
|
||||
- Name validation trims whitespace; a name that is empty after trimming is invalid.
|
||||
- Duplicate player character names are permitted — characters are distinguished by their unique ID.
|
||||
- MVP baseline does not include importing/exporting player characters.
|
||||
- MVP baseline does not include player-character-specific fields beyond name, AC, max HP, color, and icon (e.g., no class, level, or ability scores).
|
||||
- MVP baseline does not include reordering player characters in the management view.
|
||||
- The management view is accessible from the bottom bar or a dedicated UI affordance, separate from the encounter view.
|
||||
- When a player character is added to an encounter, a snapshot of its current stats is copied — future edits to the player character do not retroactively update existing combatants.
|
||||
Reference in New Issue
Block a user