Exact source used by this build. SHA-256: c8cda3e3bcb83a466d3daa699e2abd143d34fb69e2effe8da0da99d8e659ed14.

1 export type Season = "spring" | "summer" | "autumn" | "winter";
2 export type Facing = "up" | "down" | "left" | "right";
3 export type Weather = "sunny" | "rain" | "storm" | "wind" | "snow";
4 export type Tool = "hoe" | "wateringCan";
5 
6 export interface CropDefinition {
7   id: string;
8   name: string;
9   description: string;
10   seasons: readonly Season[];
11   growthStages: readonly { days: number }[];
12   regrowthDays: number | null;
13   sellPrice: number;
14   seedPrice: number;
15 }
16 
17 export interface CropInstance {
18   cropId: string;
19   /** Zero based stage index. */
20   stage: number;
21   /** Watered days accumulated within this stage. */
22   daysInStage: number;
23   /** True when a crop can be harvested. */
24   ready: boolean;
25   /** True only after harvesting a regrowing crop. */
26   regrowing: boolean;
27 }
28 
29 export interface Landmark { id: string; kind: "home"; x: number; y: number; width: number; height: number }
30 /** Authored interaction targets; content owns names and any additional presentation metadata. */
31 export interface PointOfInterest { id: string; kind: string; x: number; y: number; width: number; height: number }
32 
33 export interface Tile {
34   ground: string;
35   tillable: boolean;
36   tilled: boolean;
37   watered: boolean;
38   objectId: string | null;
39   /** Occupies the tile for placement/planting but allows walking, e.g. a path. */
40   walkableObject?: boolean;
41   crop: CropInstance | null;
42 }
43 
44 export interface Warp {
45   id: string; x: number; y: number; width: number; height: number;
46   targetAreaId: string; targetX: number; targetY: number;
47   locked: boolean; label: string; kind?: string;
48 }
49 export interface SeasonAppearance { tint: number; groundCover: string; groundColor: number; foliageColor: number }
50 export interface Area {
51   id: string;
52   width: number;
53   height: number;
54   tiles: Tile[];
55   /** Time cost in real milliseconds for one game minute in this area. */
56   clockRateMsPerGameMinute: number;
57   spawn: TilePosition;
58   landmarks: Landmark[];
59   pois?: PointOfInterest[];
60   name?: string;
61   outdoor: boolean;
62   locked: boolean;
63   collision: boolean[];
64   groundTiles: number[];
65   decorTiles: number[];
66   warps: Warp[];
67   seasons?: Record<Season, SeasonAppearance>;
68   systems: Record<string, unknown>;
69 }
70 
71 export interface AreaConfig {
72   id: string;
73   width: number;
74   height: number;
75   ground: string;
76   tillable: boolean;
77   clockRateMsPerGameMinute?: number;
78   spawn?: TilePosition;
79   landmarks?: Landmark[];
80   pois?: PointOfInterest[];
81   name?: string;
82   outdoor?: boolean;
83   locked?: boolean;
84   collision?: boolean[];
85   groundTiles?: number[];
86   decorTiles?: number[];
87   tillableTiles?: boolean[];
88   warps?: Warp[];
89   seasons?: Record<Season, SeasonAppearance>;
90 }
91 export interface StarterPlayer { areaId: string; x: number; y: number; facing: Facing; inventory: Record<string, number> }
92 export interface WorldConfig { id: string; areas: readonly AreaConfig[]; starterPlayer?: StarterPlayer }
93 
94 export interface Player {
95   id: string;
96   name: string;
97   areaId: string;
98   x: number;
99   y: number;
100   facing: Facing;
101   energy: number;
102   maxEnergy: number;
103   inventory: Record<string, number>;
104   connected: boolean;
105   sleeping: boolean;
106   sleepConfirmedAt: number | null;
107   /** Set during a forced 2 AM end-of-day so overnight does not restore energy. */
108   passedOut: boolean;
109   systems: Record<string, unknown>;
110 }
111 
112 export interface Clock {
113   year: number;
114   season: Season;
115   day: number;
116   weekday: number;
117   /** Minutes after midnight. 6:00 is 360 and 2:00 AM next day is 1560. */
118   minuteOfDay: number;
119   realMsRemainder: number;
120   machineMinutes: number;
121 }
122 
123 export interface Wallet {
124   mode: "shared" | "separate";
125   shared: number;
126   balances: Record<string, number>;
127   ledger: WalletLedgerEntry[];
128 }
129 export interface WalletLedgerEntry { fromPlayerId: string; toPlayerId: string; amount: number }
130 
131 export interface WorldState {
132   revision: number;
133   clock: Clock;
134   areas: Record<string, Area>;
135   players: Record<string, Player>;
136   wallet: Wallet;
137   rngState: number;
138   paused: boolean;
139   starterPlayer: StarterPlayer;
140   weather: Weather;
141   systems: Record<string, unknown>;
142 }
143 
144 /** Derived from the registered system schemas; no protocol list to maintain. */
145 export type Intent = import("zod").z.infer<typeof import("./systems").IntentSchema>;
146 
147 export interface TilePosition { x: number; y: number }
148 export interface SimEvent {
149   /** Presentation/progress only: broadcast live, persist with the next bounded flush. */
150   transient?: boolean;
151   type: string;
152   areaId?: string;
153   checkpoint?: boolean;
154   snapshot?: boolean;
155   data?: Record<string, unknown>;
156   playerId?: string;
157   message?: string;
158 }
159 
160 export interface IntentResult {
161   state: WorldState;
162   events: SimEvent[];
163   error?: string;
164   /** Accepted input cost for the server's generic elapsed-time credit bucket. */
165   timingCostMs?: number;
166 }
167 export interface SimRules {
168   /** Domain-keyed validated content, injected by the content registry for independent systems. */
169   content?: Readonly<Record<string, unknown>>;
170   crops: Record<string, CropDefinition>;
171   /** Map a seed item id to its crop id. */
172   seedToCrop?: Record<string, string>;
173   weatherOdds?: Record<Season, Record<Weather, number>>;
174 }
175