Exact source used by this build. SHA-256: 87dd54d751c456ec66b3a9ae0ab5aa1ff8e48d491d8d89397b1a3a4e7bf9bd3e.

1 import { z } from "zod";
2 import type { WorldState } from "../../types";
3 import { defineIntent, defineSystem } from "../registry";
4 export function nextCalendar(state: WorldState, preserveRemainder: boolean): WorldState {
5   const seasons: readonly WorldState["clock"]["season"][] = ["spring", "summer", "autumn", "winter"];
6   let { year, season, day, weekday } = state.clock;
7   day += 1;
8   weekday = (weekday + 1) % 7;
9   if (day > 28) { day = 1; const at = seasons.indexOf(season); season = seasons[(at + 1) % seasons.length]!; if (season === "spring") year += 1; }
10   const remainingDayMinutes = Math.max(0, 1560 - state.clock.minuteOfDay);
11   return { ...state, clock: { ...state.clock, year, season, day, weekday, minuteOfDay: 360, realMsRemainder: preserveRemainder ? state.clock.realMsRemainder : 0, machineMinutes: state.clock.machineMinutes + remainingDayMinutes + 400 } };
12 }
13 
14 
15 export const calendarSystem = defineSystem({
16   id: "calendar", worldDefaults: () => ({}), playerDefaults: () => ({}), events: ["pause", "overnight"],
17   initializeWorld: () => ({ clock: { year: 1, season: "spring", day: 1, weekday: 0, minuteOfDay: 360, realMsRemainder: 0, machineMinutes: 0 }, paused: false }),
18   intents: [defineIntent("pause", z.object({ type: z.literal("pause"), paused: z.boolean() }), ({ state, playerId }, intent) => ({
19     state: { ...state, revision: state.revision + 1, paused: intent.paused }, events: [{ type: "pause", playerId }],
20   }), { allowPaused: true, allowSleeping: true })],
21   onOvernight: ({ state, preserveRemainder }) => ({ state: nextCalendar(state, preserveRemainder ?? false), events: [{ type: "overnight", checkpoint: true }] }),
22 });
23