Phase 1: builder/UX quick wins (5e wording, no-campaign, details, ability UI)

- 5e skill/save proficiency shows 'Not proficient/Proficient/Expertise' instead of the
  PF2e rank names (Untrained/Trained/Expert); PF2e keeps its ranks. (shared rankLabel)
- Characters can be created without a campaign: campaignId is optional ('' = unassigned),
  CharactersPage no longer requires an active campaign, the wizard's campaign prop is
  optional, and the sheet has a Campaign selector to attach/move later.
- New character details: appearance, personality/behaviour, alignment, and a real
  background field (promoted out of notes); a Details wizard step + a Details sheet card.
- Ability step shows a clearer total + 'base · +race' breakdown.
- Point-buy verified correct (8:0..15:9 / 27, clamped 8-15, Next gated on budget).

All schema additions default-safe (characterDefaults updated). 329 tests green, build OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 00:56:26 +02:00
parent f1e15d4011
commit 11a9e87100
9 changed files with 124 additions and 29 deletions
+1 -2
View File
@@ -129,8 +129,7 @@ describe('RoomHub', () => {
});
it('survives a player reconnect: the seat is reclaimed with the same stable playerId', () => {
let t = 0;
const hub = new RoomHub(() => t);
const hub = new RoomHub(() => 0);
const gm = fake(); hub.host(gm);
const hosted = lastOf(gm, 'hosted') as Extract<ServerMessage, { t: 'hosted' }>;
const PID = 'stable-player-1';