v0.7.0 — four game types, a lobby you can read and leave, and a multiplayer game that makes a sound
The multiplayer set-up, the lobby, the start of a game, and four signals a remote client had never been sent. Reasoning, the preset table and what was verified how: CHANGELOG.md. - Co-op, Competitive, Cutthroat, Solitaire and Custom, on both screens, from one shared block — they had drifted, and each was missing a question the other asked. - A player reads the whole rule set before taking a seat, may leave a lobby or a running game, and keeps a seat across a reload. The host may clear a chair. The browser remembers every game it is in, not just the last one. - The start of a game is drawn: a handoff beat, an announcement, the code and type in the header. - Sound, the timetable flash, announcements and the just-drawn badge now reach a remote client; justDrawn goes to the seat that drew it and nobody else. - Played on StartOS, which found the rest: an Extra belongs to the player who played it, the board never named the Superintendent, bot seats were reported as absent players, and rule section numbers are out of every string a player reads. Also carries the previous session's Heavy Grade documentation work — asked again, answer unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016JczK5i33ZNSf2PtzZqdhS
This commit is contained in:
co-authored by
Claude Opus 5
parent
42adfda390
commit
06db36e5b5
+5
-3
@@ -79,7 +79,7 @@ function candidates(s: GameState, player: PlayerIndex): Intent[] {
|
||||
out.push(...localOpsCandidates(s, player));
|
||||
break;
|
||||
case 'newTrain':
|
||||
out.push(...newTrainCandidates(s));
|
||||
out.push(...newTrainCandidates(s, player));
|
||||
break;
|
||||
case 'loadUnload':
|
||||
out.push(...loadUnloadCandidates(s, player));
|
||||
@@ -257,7 +257,7 @@ function localOpsCandidates(s: GameState, player: PlayerIndex): Intent[] {
|
||||
return out;
|
||||
}
|
||||
|
||||
function newTrainCandidates(s: GameState): Intent[] {
|
||||
function newTrainCandidates(s: GameState, player: PlayerIndex): Intent[] {
|
||||
const out: Intent[] = [];
|
||||
for (const [trayId] of s.trays) {
|
||||
for (const carType of CAR_TYPES) {
|
||||
@@ -279,7 +279,9 @@ function newTrainCandidates(s: GameState): Intent[] {
|
||||
* is placed. In the middle of the railroad — an Interchange, a Control Point — both ways are real
|
||||
* runs, so those are offered twice, once per direction.
|
||||
*/
|
||||
for (const trainNumber of s.pendingExtras) {
|
||||
// Only the player who played it is offered anywhere to put it (§7) — `check` refuses anyone else
|
||||
// with NOT_YOUR_EXTRA, and offering options that are certain to be refused is how a menu lies.
|
||||
for (const { trainNumber } of s.pendingExtras.filter((x) => x.player === player)) {
|
||||
for (const side of ['west', 'east'] as const) {
|
||||
out.push({ type: 'newTrain.startExtra', trainNumber, start: { kind: 'divisionPoint', side } });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user