feat: 게임 시계 reconciliation 권위 기반 추가

This commit is contained in:
2026-09-03 08:44:43 +00:00
parent b91dcbcaaa
commit ae7d55ef47
29 changed files with 1265 additions and 81 deletions
@@ -172,7 +172,20 @@ export class TurnDaemonLifecycle {
const nowMs = this.clock.nowMs();
const wallNow = new Date(nowMs);
const gameClock = await this.stateStore.loadGameClock?.(wallNow);
let gameClock = await this.stateStore.loadGameClock?.(wallNow);
if (gameClock?.phase === 'PREOPEN' && this.stateStore.promotePreopenAtOpening) {
await this.stateStore.promotePreopenAtOpening(wallNow);
gameClock = await this.stateStore.loadGameClock?.(wallNow);
}
if (
gameClock?.phase &&
gameClock.phase !== 'RUNNING' &&
gameClock.phase !== 'MANUAL'
) {
this.status.nextTurnTime = undefined;
await this.clock.sleepMs(500);
continue;
}
if (gameClock?.mode === 'manual') {
// Ref observes all generals due before one monthly boundary in
// a single snapshot. Manual mode advances directly to that
+9 -2
View File
@@ -7,7 +7,7 @@ import type {
TurnRunResult,
} from '@sammo-ts/common';
import type { GamePrisma } from '@sammo-ts/infra';
import type { GameClockMode } from '@sammo-ts/common';
import type { GameClockMode, GameClockPhase } from '@sammo-ts/common';
export type {
RunReason,
@@ -60,7 +60,14 @@ export interface TurnStateStore {
loadCheckpoint(): Promise<TurnCheckpoint | undefined>;
saveCheckpoint(checkpoint?: TurnCheckpoint): Promise<void>;
shouldHaltScheduledRuns?(): Promise<boolean>;
loadGameClock?(wallNow?: Date): Promise<{ mode: GameClockMode; now: Date }>;
loadGameClock?(wallNow?: Date): Promise<{
mode: GameClockMode;
now: Date;
phase?: GameClockPhase;
revision?: number;
deadlineGeneration?: number;
}>;
promotePreopenAtOpening?(wallNow: Date): Promise<boolean>;
shouldRebaseRealtimeBacklog?(wallNow: Date): Promise<boolean>;
rebaseRealtimeBacklog?(wallNow: Date): Promise<RealtimeBacklogRebaseResult | null>;
advanceGameClockTo?(target: Date, wallNow: Date): Promise<void>;