# Quickstart: Player Character Management **Branch**: `005-player-characters` | **Date**: 2026-03-12 ## Overview This feature adds persistent player character templates that can be reused across encounters. Player characters have a name, AC, max HP, a chosen color, and a preset icon. ## Implementation Layers ### Domain (`packages/domain/src/`) New files: - `player-character-types.ts` — `PlayerCharacterId`, `PlayerCharacter`, `PlayerColor`, `PlayerIcon`, validation sets - `create-player-character.ts` — Pure create function - `edit-player-character.ts` — Pure edit function - `delete-player-character.ts` — Pure delete function Modified files: - `types.ts` — Add `color?`, `icon?`, `playerCharacterId?` to `Combatant` - `events.ts` — Add `PlayerCharacterCreated`, `PlayerCharacterUpdated`, `PlayerCharacterDeleted` to union - `index.ts` — Re-export new types and functions ### Application (`packages/application/src/`) Modified files: - `ports.ts` — Add `PlayerCharacterStore` port interface New files: - `create-player-character-use-case.ts` - `edit-player-character-use-case.ts` - `delete-player-character-use-case.ts` ### Web (`apps/web/`) New files: - `src/persistence/player-character-storage.ts` — localStorage adapter - `src/hooks/use-player-characters.ts` — React state + persistence hook - `src/components/create-player-modal.tsx` — Create/edit modal - `src/components/player-management.tsx` — List/edit/delete view - `src/components/color-palette.tsx` — Color selection grid - `src/components/icon-grid.tsx` — Icon selection grid Modified files: - `src/components/action-bar.tsx` — Add "Players" section to search dropdown - `src/components/combatant-row.tsx` — Render color/icon for PC combatants - `src/App.tsx` — Wire up `usePlayerCharacters` hook, pass to components - `src/persistence/encounter-storage.ts` — Handle new optional Combatant fields in rehydration ## Testing Strategy - **Domain**: Pure function unit tests for create/edit/delete (validation, error cases, events) - **Persistence**: Rehydration tests (corrupt data, missing fields, invalid color/icon) - **Integration**: Layer boundary check already runs in CI — verify new domain files have no outer-layer imports ## Key Patterns to Follow 1. **Branded types**: See `CombatantId` in `types.ts` for pattern 2. **Domain operations**: See `add-combatant.ts` for `{result, events} | DomainError` pattern 3. **Persistence**: See `encounter-storage.ts` for localStorage + rehydration pattern 4. **Hook**: See `use-encounter.ts` for `useState` + `useEffect` persistence pattern 5. **Ports**: See `EncounterStore` in `ports.ts` for interface pattern