The camera always wears the turn-taker's eyes, and knows whose turn zero is
Eric's rule, applied everywhere: every reel — moment, catch-up, whole tale — follows the wizard whose turn it is, the pov switching at each handover as boundaries scroll past. And the J8LL mystery dies with it: turn zero's opening boundary lives in the DEAL, before any command, so scanning a moment's steps found the NEXT turn's start instead and put the camera in the wrong wizard's head. momentSteps now names the owner from the very boundary that opened the turn — counted through the deal — and carries it to the client and the share page, where it also fixes the same latent mis-titling. Also aboard: the cutaway shot. When the eyes aim at something they cannot see — a wraith summoned across the maze, a spell through walls — the camera cuts to the target's cell for that beat, standing back down its deepest corridor, and cuts home on the next step. The wraith no longer materializes off-screen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
6788de2f6e
commit
a28d27eedc
@@ -117,20 +117,9 @@ function shareData(id: string): ShareData | null {
|
||||
const share = getShare(id);
|
||||
const room = share ? getRoom(share.roomId) : undefined;
|
||||
if (share && room?.state) {
|
||||
const steps = momentSteps(room, SPECTATOR, share.turn);
|
||||
if (!("error" in steps) && steps.length > 0) {
|
||||
let actor: string = steps[steps.length - 1]!.actor;
|
||||
let round = 0;
|
||||
outer: for (const st of steps) {
|
||||
for (const e of st.events) {
|
||||
if (e.type === "turnStarted" || e.type === "extraTurnStarted") {
|
||||
actor = e.player;
|
||||
if (e.type === "turnStarted") round = e.round;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
data = { steps: steps as unknown as ShareData["steps"], actor, round };
|
||||
const reel = momentSteps(room, SPECTATOR, share.turn);
|
||||
if (!("error" in reel) && reel.steps.length > 0) {
|
||||
data = { steps: reel.steps as unknown as ShareData["steps"], actor: reel.owner, round: reel.round };
|
||||
}
|
||||
}
|
||||
if (shareCache.size > 50) shareCache.clear();
|
||||
@@ -624,8 +613,8 @@ wss.on("connection", (socket) => {
|
||||
return send(socket, { type: "error", message: "one moment" });
|
||||
}
|
||||
session.lastCatchUpAt = now;
|
||||
const steps = momentSteps(room, session.playerId, turn);
|
||||
if ("error" in steps) return send(socket, { type: "error", message: steps.error });
|
||||
const reel = momentSteps(room, session.playerId, turn);
|
||||
if ("error" in reel) return send(socket, { type: "error", message: reel.error });
|
||||
const share = mintShare(room.id, turn);
|
||||
send(socket, { type: "share", id: share.id, turn });
|
||||
break;
|
||||
@@ -639,9 +628,9 @@ wss.on("connection", (socket) => {
|
||||
return send(socket, { type: "error", message: "catching up already — one moment" });
|
||||
}
|
||||
session.lastCatchUpAt = now;
|
||||
const steps = momentSteps(room, session.playerId, Number(msg.turn ?? -1));
|
||||
if ("error" in steps) return send(socket, { type: "error", message: steps.error });
|
||||
send(socket, { type: "moment", steps });
|
||||
const reel = momentSteps(room, session.playerId, Number(msg.turn ?? -1));
|
||||
if ("error" in reel) return send(socket, { type: "error", message: reel.error });
|
||||
send(socket, { type: "moment", steps: reel.steps, owner: reel.owner });
|
||||
break;
|
||||
}
|
||||
case "pickColor": {
|
||||
|
||||
Reference in New Issue
Block a user