feat(server): layout-aware room.create + resolved layout echoes (Phase C)
Extends the WebSocket protocol so clients can request a specific
starting layout when creating a room, and receive the resolved
layout echoed back on room.created / room.joined.
Protocol additions (Zod):
- room.create.payload.layout: optional discriminated union of
{ kind: "premade", id } | { kind: "fen", fen, name? }
| { kind: "custom", pieces, name? }
- room.created / room.joined: new optional 'layout' field with
resolved { id, name, pieces } — present on new servers, absent
on legacy ones (backward compat).
- LAYOUT_INVALID error code for validation failures.
- PiecePlacement + ResolvedLayout schemas.
Server implementation:
- New layouts.ts: resolveLayoutRequest() handles premade lookup,
FEN parse, custom pieces. Chess960 picks a random seed server-
side (the ultimate authority on 'which position'). Always runs
validateLayout — invalid input returns LAYOUT_INVALID, never
mutates room state.
- rooms.ts: Room.layout field + RoomRegistry.createRoom/joinRoom
accept/return resolved layouts. Default is CLASSIC_LAYOUT.
- game-session.ts: GameSession + GameSessionRegistry.create
accept StartingLayout; constructs ChessEngine({ layout }).
- broadcast.ts: handleRoomCreate resolves+validates first, rejects
with LAYOUT_INVALID toast, otherwise threads layout into the
room + session + response. handleRoomJoin echoes the room's
stored layout to the joiner.
Chess package:
- packages/chess/src/index.ts exports LAYOUT_REGISTRY, all premade
layouts, buildChess960Layout, toFen/fromFen, validateLayout,
and the related types — so server can pull them without
importing internal module paths.
Tests: 20 new tests (11 in protocol.test.ts for the layout union,
12 in layouts.test.ts for server-side resolution).
1011 tests passing; bun run check clean.
PROTOCOL.md updated with examples of all three layout kinds.
This commit is contained in:
parent
f7099d754d
commit
174cad6ae7
9 changed files with 595 additions and 13 deletions
|
|
@ -38,3 +38,25 @@ export {
|
|||
type PresetActivation,
|
||||
type PresetScope,
|
||||
} from "./presets/active-set.js";
|
||||
|
||||
// Starting Layouts — piece-placement abstractions orthogonal to
|
||||
// preset rules. Consumed by the server for room.create layout
|
||||
// resolution and by the client Lobby for premade selection.
|
||||
export {
|
||||
LAYOUT_REGISTRY,
|
||||
CLASSIC_LAYOUT,
|
||||
EMPTY_LAYOUT,
|
||||
DUNSANY_LAYOUT,
|
||||
MONSTER_LAYOUT,
|
||||
PAWNS_ONLY_LAYOUT,
|
||||
HORDE_LAYOUT,
|
||||
KNIGHTMATE_LAYOUT,
|
||||
CHESS960_SHIM,
|
||||
buildChess960Layout,
|
||||
toFen,
|
||||
fromFen,
|
||||
type PiecePlacement,
|
||||
type StartingLayout,
|
||||
type LayoutValidationResult,
|
||||
} from "./layouts/index.js";
|
||||
export { validateLayout } from "./layouts/validate.js";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue