@pompidup/kingdomino-engine 3.4.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,18 @@
1
+ type Result<T> = Ok<T> | Err;
2
+ interface Ok<T> {
3
+ readonly tag: "Ok";
4
+ readonly value: T;
5
+ }
6
+ interface Err {
7
+ readonly tag: "Err";
8
+ readonly error: string;
9
+ }
10
+
1
11
  /**
2
12
  * All possible ground/terrain types in Kingdomino.
3
13
  * Each type can form contiguous properties for scoring.
4
14
  */
5
- declare const GROUND: readonly ["castle", "wheat", "forest", "sea", "plain", "swamp", "mine"];
15
+ declare const GROUND: readonly ["castle", "wheat", "forest", "sea", "plain", "swamp", "mine", "grassland", "lake", "jungle", "quarry", "desert", "volcano"];
6
16
  /** Union type of all terrain types */
7
17
  type Ground = (typeof GROUND)[number];
8
18
  /** Special ground type for empty/unplaced tiles */
@@ -16,10 +26,16 @@ type Crown = number;
16
26
  type Tile = {
17
27
  /** The terrain type of this tile */
18
28
  type: Ground;
19
- /** Number of crowns (0-3), multiplier for scoring */
29
+ /** Number of crowns (0-3), multiplier for scoring. In Origins, represents fire symbols. */
20
30
  crowns: Crown;
21
31
  /** Whether this tile has a construction square for buildings (Queendomino) */
22
32
  hasConstructionSquare?: boolean;
33
+ /** Number of volcanic craters on this tile (Origins, 1-3). Determines fire token type. */
34
+ volcanoCraters?: number;
35
+ /** Whether this tile has a giant icon (Age of Giants, letter dominos A-F) */
36
+ hasGiant?: boolean;
37
+ /** Whether this tile has footprint icons (Age of Giants, dominos 49-54) */
38
+ hasFootprint?: boolean;
23
39
  };
24
40
  /**
25
41
  * Represents an empty/unplaced tile on the kingdom grid.
@@ -39,8 +55,10 @@ type Domino = {
39
55
  left: Tile;
40
56
  /** The right tile of the domino */
41
57
  right: Tile;
42
- /** Unique number identifying this domino (1-48 in Classic mode) */
58
+ /** Unique number identifying this domino (1-48 in Classic mode). Letter dominos use fractional numbers (A=0.01...F=0.06). */
43
59
  number: number;
60
+ /** Display letter for Age of Giants giant dominos (A-F). Undefined for numbered dominos. */
61
+ letter?: string;
44
62
  };
45
63
  /**
46
64
  * Represents a domino that has been revealed for player selection.
@@ -91,6 +109,255 @@ declare const GRIDSIZE = 9;
91
109
  */
92
110
  declare const MAX_KINGDOM_SIZE = 5;
93
111
 
112
+ type ObjectValues<T> = T[keyof T];
113
+
114
+ /**
115
+ * A giant placed on a player's kingdom, covering a crown.
116
+ * The covered crown does not count for scoring.
117
+ */
118
+ type PlacedGiant = {
119
+ /** Position on the kingdom grid where the giant covers a crown */
120
+ position: Position;
121
+ };
122
+ /**
123
+ * All quest tile types available in Age of Giants.
124
+ */
125
+ declare const questTypes: {
126
+ /** 5pts per matching terrain tile adjacent (8-dir) to castle */
127
+ readonly localTrade: "localTrade";
128
+ /** 5pts per matching terrain tile in the 4 corners of the kingdom */
129
+ readonly kingdomBorders: "kingdomBorders";
130
+ /** 5pts if kingdom is complete (no discarded dominos) */
131
+ readonly harmony: "harmony";
132
+ /** 10pts if castle is in the center of the kingdom */
133
+ readonly middleKingdom: "middleKingdom";
134
+ /** 20pts if castle is in one of the 4 corners of the kingdom */
135
+ readonly lostCorner: "lostCorner";
136
+ /** 10pts per alignment of 3+ tiles with crowns (H/V/diagonal) */
137
+ readonly megalomania: "megalomania";
138
+ /** 10pts per property of 5+ wheat/forest/sea/plain tiles with 0 crowns */
139
+ readonly austereKing: "austereKing";
140
+ };
141
+ type QuestType = ObjectValues<typeof questTypes>;
142
+ /**
143
+ * A quest tile drawn at game start.
144
+ * Provides a specific end-of-game bonus scoring condition.
145
+ */
146
+ type QuestTile = {
147
+ /** Unique identifier for the quest tile */
148
+ id: number;
149
+ /** Type of quest determining the scoring rule */
150
+ type: QuestType;
151
+ /** Display name of the quest */
152
+ name: string;
153
+ /** Description of the scoring condition */
154
+ description: string;
155
+ /** Points awarded per match (e.g., 5 for localTrade, 10 for megalomania) */
156
+ points: number;
157
+ /** Target terrain type (only for localTrade and kingdomBorders quests) */
158
+ terrain?: Ground;
159
+ };
160
+ /**
161
+ * Complete Age of Giants-specific game state.
162
+ * Stored as an optional field on Game and only present in AoG modes.
163
+ */
164
+ type AgeOfGiantsState = {
165
+ /** Number of giant figurines remaining in the pool (starts at 6) */
166
+ giantPool: number;
167
+ /** The 2 quest tiles drawn for this game */
168
+ questTiles: QuestTile[];
169
+ };
170
+
171
+ /**
172
+ * Represents a lord (player token) used for turn order and domino selection.
173
+ * In games with 2 players, each player has 2 lords.
174
+ * In games with 3-4 players, each player has 1 lord.
175
+ */
176
+ type Lord = {
177
+ /** Unique identifier for this lord */
178
+ id: string;
179
+ /** ID of the player who owns this lord */
180
+ playerId: string;
181
+ /** Whether this lord has finished their turn */
182
+ turnEnded: boolean;
183
+ /** Whether this lord has picked a domino this round */
184
+ hasPick: boolean;
185
+ /** Whether this lord has placed/discarded a domino this round */
186
+ hasPlace: boolean;
187
+ /** The domino this lord picked (if any) */
188
+ dominoPicked?: Domino;
189
+ };
190
+
191
+ /**
192
+ * Represents a game mode with its configuration.
193
+ * Currently only "Classic" mode is available.
194
+ */
195
+ type GameMode = {
196
+ /** Name of the game mode (e.g., "Classic") */
197
+ name: string;
198
+ /** Description of the game mode */
199
+ description: string;
200
+ };
201
+
202
+ /**
203
+ * The three gameplay modes within Kingdomino Origins.
204
+ * Discovery is the base, Totem adds resources/totems, Tribe adds cavemen.
205
+ */
206
+ declare const originsSubModes: {
207
+ readonly discovery: "Discovery";
208
+ readonly totem: "Totem";
209
+ readonly tribe: "Tribe";
210
+ };
211
+ type OriginsSubMode = ObjectValues<typeof originsSubModes>;
212
+ /**
213
+ * Represents the pool of available fire tokens.
214
+ * Discovery Mode starts with: 5×1-fire, 4×2-fire, 1×3-fire = 10 total.
215
+ */
216
+ type FireTokenPool = {
217
+ ones: number;
218
+ twos: number;
219
+ threes: number;
220
+ };
221
+ /**
222
+ * A fire token that has been placed on a player's kingdom.
223
+ */
224
+ type PlacedFireToken = {
225
+ /** Number of fires on this token (1, 2, or 3) */
226
+ fires: 1 | 2 | 3;
227
+ /** Position on the kingdom grid */
228
+ position: Position;
229
+ };
230
+ /**
231
+ * Tracks which volcano granted the current pending fire token,
232
+ * so the placement validation knows the launch position.
233
+ */
234
+ type PendingFireToken = {
235
+ /** Number of fires on the token to place */
236
+ fires: 1 | 2 | 3;
237
+ /** Position of the volcano that granted this token */
238
+ volcanoPosition: Position;
239
+ };
240
+ /**
241
+ * Types of wooden resources in Origins.
242
+ * Each maps to a specific terrain type.
243
+ */
244
+ declare const resourceTypes: {
245
+ readonly mammoth: "mammoth";
246
+ readonly fish: "fish";
247
+ readonly mushroom: "mushroom";
248
+ readonly flint: "flint";
249
+ };
250
+ type ResourceType = ObjectValues<typeof resourceTypes>;
251
+ /**
252
+ * A wooden resource placed on a player's kingdom tile.
253
+ */
254
+ type Resource = {
255
+ /** Type of resource */
256
+ type: ResourceType;
257
+ /** Position on the kingdom grid */
258
+ position: Position;
259
+ };
260
+ /**
261
+ * Tracks which player holds each totem tile.
262
+ * null means no player currently holds that totem.
263
+ */
264
+ type TotemState = Record<ResourceType, string | null>;
265
+ /**
266
+ * Point values for each totem tile at end of game.
267
+ */
268
+ type TotemBonus = Record<ResourceType, number>;
269
+ /**
270
+ * The 7 kinds of hunter-gatherers.
271
+ * Each has a specific scoring rule based on surrounding resources.
272
+ */
273
+ declare const hunterGathererKinds: {
274
+ /** Scores per mammoth adjacent */
275
+ readonly mammothHunter: "mammothHunter";
276
+ /** Scores per fish adjacent */
277
+ readonly fisherman: "fisherman";
278
+ /** Scores per mushroom adjacent */
279
+ readonly mushroomPicker: "mushroomPicker";
280
+ /** Scores per flint adjacent */
281
+ readonly flintCollector: "flintCollector";
282
+ /** Scores per unique resource type adjacent */
283
+ readonly trapper: "trapper";
284
+ /** Scores per total resource adjacent (any type) */
285
+ readonly gatherer: "gatherer";
286
+ /** Scores per fire symbol adjacent (Fire Lady) */
287
+ readonly fireLady: "fireLady";
288
+ };
289
+ type HunterGathererKind = ObjectValues<typeof hunterGathererKinds>;
290
+ /**
291
+ * Warrior size categories with their power values.
292
+ */
293
+ declare const warriorTypes: {
294
+ readonly small: "small";
295
+ readonly amazon: "amazon";
296
+ readonly oafish: "oafish";
297
+ };
298
+ type WarriorType = ObjectValues<typeof warriorTypes>;
299
+ /**
300
+ * Power values for each warrior type.
301
+ */
302
+ declare const WARRIOR_POWER: Record<WarriorType, number>;
303
+ /**
304
+ * A hunter-gatherer caveman tile.
305
+ */
306
+ type HunterGathererTile = {
307
+ kind: "hunterGatherer";
308
+ id: number;
309
+ /** Specific hunter-gatherer type determining scoring rule */
310
+ hunterType: HunterGathererKind;
311
+ /** Points per matching adjacent resource/symbol */
312
+ pointsPerMatch: number;
313
+ };
314
+ /**
315
+ * A warrior caveman tile.
316
+ */
317
+ type WarriorTile = {
318
+ kind: "warrior";
319
+ id: number;
320
+ /** Warrior size category */
321
+ warriorType: WarriorType;
322
+ /** Combat power (1, 2, or 3) */
323
+ power: number;
324
+ };
325
+ /** Discriminated union of all caveman tile types. */
326
+ type CavemanTile = HunterGathererTile | WarriorTile;
327
+ /**
328
+ * A caveman tile placed on a player's kingdom.
329
+ */
330
+ type PlacedCaveman = {
331
+ caveman: CavemanTile;
332
+ position: Position;
333
+ };
334
+ /**
335
+ * The Cave board used in Tribe mode.
336
+ * Shows 4 visible caveman tiles and a face-down draw pile.
337
+ */
338
+ type CaveBoard = {
339
+ /** Up to 4 visible caveman tiles available for recruitment */
340
+ visible: CavemanTile[];
341
+ /** Face-down draw pile */
342
+ drawPile: CavemanTile[];
343
+ };
344
+ /**
345
+ * Complete Origins-specific game state.
346
+ * Stored as an optional field on Game and only present in Origins modes.
347
+ */
348
+ type OriginsState = {
349
+ /** Which Origins sub-mode is being played */
350
+ subMode: OriginsSubMode;
351
+ /** Available fire tokens pool */
352
+ fireTokenPool: FireTokenPool;
353
+ /** Pending fire token to place (set after placing a volcano domino) */
354
+ pendingFireToken?: PendingFireToken;
355
+ /** Totem holder state (Totem mode only) */
356
+ totems?: TotemState;
357
+ /** Cave board state (Tribe mode only) */
358
+ caveBoard?: CaveBoard;
359
+ };
360
+
94
361
  /**
95
362
  * Types of immediate bonuses a building can grant when constructed.
96
363
  */
@@ -158,49 +425,6 @@ type PlacedBuilding = {
158
425
  position: Position;
159
426
  };
160
427
 
161
- type Result<T> = Ok<T> | Err;
162
- interface Ok<T> {
163
- readonly tag: "Ok";
164
- readonly value: T;
165
- }
166
- interface Err {
167
- readonly tag: "Err";
168
- readonly error: string;
169
- }
170
-
171
- /**
172
- * Represents a lord (player token) used for turn order and domino selection.
173
- * In games with 2 players, each player has 2 lords.
174
- * In games with 3-4 players, each player has 1 lord.
175
- */
176
- type Lord = {
177
- /** Unique identifier for this lord */
178
- id: string;
179
- /** ID of the player who owns this lord */
180
- playerId: string;
181
- /** Whether this lord has finished their turn */
182
- turnEnded: boolean;
183
- /** Whether this lord has picked a domino this round */
184
- hasPick: boolean;
185
- /** Whether this lord has placed/discarded a domino this round */
186
- hasPlace: boolean;
187
- /** The domino this lord picked (if any) */
188
- dominoPicked?: Domino;
189
- };
190
-
191
- /**
192
- * Represents a game mode with its configuration.
193
- * Currently only "Classic" mode is available.
194
- */
195
- type GameMode = {
196
- /** Name of the game mode (e.g., "Classic") */
197
- name: string;
198
- /** Description of the game mode */
199
- description: string;
200
- };
201
-
202
- type ObjectValues<T> = T[keyof T];
203
-
204
428
  /**
205
429
  * Represents a knight placed on a player's kingdom (Queendomino).
206
430
  */
@@ -232,6 +456,14 @@ type Player = {
232
456
  knights?: Knight[];
233
457
  /** Buildings placed on the kingdom (Queendomino) */
234
458
  buildings?: PlacedBuilding[];
459
+ /** Fire tokens placed on the kingdom (Origins) */
460
+ fireTokens?: PlacedFireToken[];
461
+ /** Wooden resources on the kingdom (Origins Totem/Tribe) */
462
+ resources?: Resource[];
463
+ /** Cavemen placed on the kingdom (Origins Tribe) */
464
+ cavemen?: PlacedCaveman[];
465
+ /** Giants placed on the kingdom covering crowns (Age of Giants) */
466
+ giants?: PlacedGiant[];
235
467
  };
236
468
  /**
237
469
  * Payload for creating a new player.
@@ -260,8 +492,16 @@ declare const playerActions: {
260
492
  readonly constructBuilding: "constructBuilding";
261
493
  /** Use the Dragon to burn a building tile (Queendomino, optional) */
262
494
  readonly useDragon: "useDragon";
263
- /** Skip the current optional action (Queendomino) */
495
+ /** Skip the current optional action (Queendomino/Origins/AoG) */
264
496
  readonly skipOptionalAction: "skipOptionalAction";
497
+ /** Place a giant on a crown after placing a giant domino (Age of Giants, mandatory) */
498
+ readonly placeGiant: "placeGiant";
499
+ /** Send a giant to an opponent after placing a footprint domino (Age of Giants, optional) */
500
+ readonly sendGiant: "sendGiant";
501
+ /** Place a fire token after placing a volcano domino (Origins, optional) */
502
+ readonly placeFireToken: "placeFireToken";
503
+ /** Recruit a caveman from the cave board (Origins Tribe, optional) */
504
+ readonly recruitCaveman: "recruitCaveman";
265
505
  };
266
506
  /** Union type of all player actions */
267
507
  type PlayerActions = ObjectValues<typeof playerActions>;
@@ -295,6 +535,8 @@ type BasicRules = {
295
535
  maxTurns: number;
296
536
  /** Maximum kingdom grid size (5 for standard, 7 for Mighty Duel) */
297
537
  maxKingdomSize: number;
538
+ /** Number of dominos discarded from each draw before selection (Age of Giants) */
539
+ dominoesDiscardedPerTurn?: number;
298
540
  };
299
541
  /**
300
542
  * Optional extra rules that modify gameplay and scoring.
@@ -315,6 +557,8 @@ type ExtraRule = {
315
557
  type Rules = {
316
558
  /** Basic rules indexed by player count (1-4) */
317
559
  basic: Record<number, BasicRules>;
560
+ /** Age of Giants basic rules indexed by player count (2-5) */
561
+ aogBasic?: Record<number, BasicRules>;
318
562
  /** Available extra rules */
319
563
  extraRules: ExtraRule[];
320
564
  };
@@ -355,6 +599,10 @@ type Game = {
355
599
  seed?: string;
356
600
  /** Queendomino-specific state (only present in QueenDomino mode) */
357
601
  queendomino?: QueenDominoState;
602
+ /** Origins-specific state (only present in KingdominoOrigins modes) */
603
+ origins?: OriginsState;
604
+ /** Age of Giants-specific state (only present in AgeOfGiants modes) */
605
+ ageOfGiants?: AgeOfGiantsState;
358
606
  };
359
607
  /**
360
608
  * Available game steps representing phases of game setup and completion.
@@ -451,6 +699,29 @@ type GameWithResults = Game & {
451
699
  result: FinalResult[];
452
700
  };
453
701
 
702
+ type AddExtraRulesCommand = {
703
+ game: GameState;
704
+ extraRules: string[];
705
+ };
706
+
707
+ /**
708
+ * Input for a single player: either a name string (human) or an object with bot config.
709
+ */
710
+ type PlayerInput = string | {
711
+ name: string;
712
+ bot?: {
713
+ strategyName: string;
714
+ };
715
+ };
716
+ type AddPlayersCommand = {
717
+ game: GameState;
718
+ players: PlayerInput[];
719
+ };
720
+
721
+ type CalculateScoreCommand = {
722
+ kingdom: Kingdom;
723
+ };
724
+
454
725
  /**
455
726
  * Severity level for a validation issue.
456
727
  * - "error": The state is corrupted and cannot be used safely.
@@ -471,39 +742,16 @@ type ValidationIssue = {
471
742
  severity: ValidationSeverity;
472
743
  };
473
744
 
474
- type GetModesCommand = Record<string, never>;
475
-
476
- type GetExtraRulesCommand = {
477
- mode: GameMode["name"];
478
- players: number;
479
- };
480
-
481
- type CreateGameCommand = {
482
- mode: string;
483
- seed?: string;
484
- };
485
-
486
745
  /**
487
- * Input for a single player: either a name string (human) or an object with bot config.
746
+ * Command to check if a domino can be placed anywhere on a kingdom.
488
747
  */
489
- type PlayerInput = string | {
490
- name: string;
491
- bot?: {
492
- strategyName: string;
493
- };
494
- };
495
- type AddPlayersCommand = {
496
- game: GameState;
497
- players: PlayerInput[];
498
- };
499
-
500
- type AddExtraRulesCommand = {
501
- game: GameState;
502
- extraRules: string[];
503
- };
504
-
505
- type StartGameCommand = {
506
- game: GameState;
748
+ type CanPlaceDominoCommand = {
749
+ /** The kingdom grid to check */
750
+ kingdom: Kingdom;
751
+ /** The domino to check placement for */
752
+ domino: Domino;
753
+ /** Maximum kingdom size (default: 5, use 7 for Mighty Duel) */
754
+ maxKingdomSize?: number;
507
755
  };
508
756
 
509
757
  type ChooseDominoCommand = {
@@ -512,11 +760,16 @@ type ChooseDominoCommand = {
512
760
  lordId: string;
513
761
  };
514
762
 
515
- type PlaceDominoCommand = {
516
- game: GameState;
763
+ type ConstructBuildingCommand = {
764
+ game: GameWithNextAction;
517
765
  lordId: string;
766
+ buildingId: number;
518
767
  position: Position;
519
- rotation: Rotation;
768
+ };
769
+
770
+ type CreateGameCommand = {
771
+ mode: string;
772
+ seed?: string;
520
773
  };
521
774
 
522
775
  type DiscardDominoCommand = {
@@ -524,12 +777,19 @@ type DiscardDominoCommand = {
524
777
  lordId: string;
525
778
  };
526
779
 
527
- type GetResultCommand = {
528
- game: GameState;
780
+ type GetDynastyResultCommand = {
781
+ games: GameWithResults[];
529
782
  };
530
783
 
531
- type CalculateScoreCommand = {
532
- kingdom: Kingdom;
784
+ type GetExtraRulesCommand = {
785
+ mode: GameMode["name"];
786
+ players: number;
787
+ };
788
+
789
+ type GetModesCommand = Record<string, never>;
790
+
791
+ type GetResultCommand = {
792
+ game: GameState;
533
793
  };
534
794
 
535
795
  /**
@@ -544,16 +804,51 @@ type GetValidPlacementsCommand = {
544
804
  maxKingdomSize?: number;
545
805
  };
546
806
 
547
- /**
548
- * Command to check if a domino can be placed anywhere on a kingdom.
549
- */
550
- type CanPlaceDominoCommand = {
551
- /** The kingdom grid to check */
552
- kingdom: Kingdom;
553
- /** The domino to check placement for */
554
- domino: Domino;
555
- /** Maximum kingdom size (default: 5, use 7 for Mighty Duel) */
556
- maxKingdomSize?: number;
807
+ type PlaceDominoCommand = {
808
+ game: GameState;
809
+ lordId: string;
810
+ position: Position;
811
+ rotation: Rotation;
812
+ };
813
+
814
+ type PlaceFireTokenCommand = {
815
+ game: GameWithNextAction;
816
+ lordId: string;
817
+ position: Position;
818
+ };
819
+
820
+ type PlaceGiantCommand = {
821
+ game: GameWithNextAction;
822
+ lordId: string;
823
+ position: Position;
824
+ };
825
+
826
+ type PlaceKnightCommand = {
827
+ game: GameWithNextAction;
828
+ lordId: string;
829
+ position: Position;
830
+ };
831
+
832
+ type RecruitCavemanCommand = {
833
+ game: GameWithNextAction;
834
+ lordId: string;
835
+ /** ID of the caveman tile to recruit */
836
+ cavemanId: number;
837
+ /** Position on the kingdom to place the caveman */
838
+ position: Position;
839
+ /** Positions of resources to spend as payment */
840
+ resourcePositions: Position[];
841
+ };
842
+
843
+ type SendGiantCommand = {
844
+ game: GameWithNextAction;
845
+ lordId: string;
846
+ /** Index of the giant to send from the current player's giants array */
847
+ giantIndex: number;
848
+ /** ID of the opponent player to receive the giant */
849
+ targetPlayerId: string;
850
+ /** Position on the opponent's kingdom where the giant will cover a crown */
851
+ targetCrownPosition: Position;
557
852
  };
558
853
 
559
854
  /**
@@ -571,21 +866,13 @@ type DeserializeGameCommand = {
571
866
  json: string;
572
867
  };
573
868
 
574
- type GetDynastyResultCommand = {
575
- games: GameWithResults[];
576
- };
577
-
578
- type PlaceKnightCommand = {
869
+ type SkipOptionalActionCommand = {
579
870
  game: GameWithNextAction;
580
871
  lordId: string;
581
- position: Position;
582
872
  };
583
873
 
584
- type ConstructBuildingCommand = {
585
- game: GameWithNextAction;
586
- lordId: string;
587
- buildingId: number;
588
- position: Position;
874
+ type StartGameCommand = {
875
+ game: GameState;
589
876
  };
590
877
 
591
878
  type UseDragonCommand = {
@@ -594,9 +881,12 @@ type UseDragonCommand = {
594
881
  buildingId: number;
595
882
  };
596
883
 
597
- type SkipOptionalActionCommand = {
598
- game: GameWithNextAction;
599
- lordId: string;
884
+ type DynastyResult = {
885
+ playerId: string;
886
+ playerName: string;
887
+ totalPoints: number;
888
+ gamesPoints: number[];
889
+ position: number;
600
890
  };
601
891
 
602
892
  /**
@@ -607,14 +897,6 @@ type ValidPlacement = {
607
897
  rotation: Rotation;
608
898
  };
609
899
 
610
- type DynastyResult = {
611
- playerId: string;
612
- playerName: string;
613
- totalPoints: number;
614
- gamesPoints: number[];
615
- position: number;
616
- };
617
-
618
900
  /**
619
901
  * The main interface for interacting with the Kingdomino game engine.
620
902
  *
@@ -748,6 +1030,20 @@ type GameEngine = {
748
1030
  * @returns Ranked dynasty results per player
749
1031
  */
750
1032
  getDynastyResults: (command: GetDynastyResultCommand) => DynastyResult[];
1033
+ /**
1034
+ * Places a giant on a crown in the lord's kingdom (Age of Giants).
1035
+ * Mandatory after placing a giant domino (A-F). The giant covers the crown for scoring.
1036
+ * @param command - Contains game state, lord ID, and crown position
1037
+ * @returns Updated game state with next action
1038
+ */
1039
+ placeGiant: (command: PlaceGiantCommand) => GameState;
1040
+ /**
1041
+ * Sends a giant from the lord's kingdom to an opponent's kingdom (Age of Giants).
1042
+ * Optional after placing a footprint domino (49-54). The opponent chooses which crown is covered.
1043
+ * @param command - Contains game state, lord ID, giant index, target player ID, and target crown position
1044
+ * @returns Updated game state with next action
1045
+ */
1046
+ sendGiant: (command: SendGiantCommand) => GameState;
751
1047
  /**
752
1048
  * Places a knight on the lord's kingdom at the specified position (Queendomino).
753
1049
  * @param command - Contains game state, lord ID, and position
@@ -767,7 +1063,19 @@ type GameEngine = {
767
1063
  */
768
1064
  useDragon: (command: UseDragonCommand) => GameState;
769
1065
  /**
770
- * Skips the current optional action (Queendomino).
1066
+ * Places a fire token on the lord's kingdom after placing a volcano domino (Origins).
1067
+ * @param command - Contains game state, lord ID, and target position
1068
+ * @returns Updated game state with next action
1069
+ */
1070
+ placeFireToken: (command: PlaceFireTokenCommand) => GameState;
1071
+ /**
1072
+ * Recruits a caveman from the cave board and places it on the lord's kingdom (Origins).
1073
+ * @param command - Contains game state, lord ID, caveman ID, position, and resource positions to spend
1074
+ * @returns Updated game state with next action
1075
+ */
1076
+ recruitCaveman: (command: RecruitCavemanCommand) => GameState;
1077
+ /**
1078
+ * Skips the current optional action (Queendomino/Origins).
771
1079
  * @param command - Contains game state and lord ID
772
1080
  * @returns Updated game state with next action
773
1081
  */
@@ -809,6 +1117,18 @@ declare const ErrorCode: {
809
1117
  readonly QUEEN_HOLDER_CANNOT_USE_DRAGON: "QUEEN_HOLDER_CANNOT_USE_DRAGON";
810
1118
  readonly BUILDING_NOT_FOUND: "BUILDING_NOT_FOUND";
811
1119
  readonly INVALID_OPTIONAL_ACTION: "INVALID_OPTIONAL_ACTION";
1120
+ readonly GIANT_POOL_EMPTY: "GIANT_POOL_EMPTY";
1121
+ readonly GIANT_NOT_FOUND: "GIANT_NOT_FOUND";
1122
+ readonly INVALID_GIANT_PLACEMENT: "INVALID_GIANT_PLACEMENT";
1123
+ readonly NOT_AOG_MODE: "NOT_AOG_MODE";
1124
+ readonly FIRE_TOKEN_POOL_EMPTY: "FIRE_TOKEN_POOL_EMPTY";
1125
+ readonly FIRE_TOKEN_INVALID_POSITION: "FIRE_TOKEN_INVALID_POSITION";
1126
+ readonly NO_PENDING_FIRE_TOKEN: "NO_PENDING_FIRE_TOKEN";
1127
+ readonly CANNOT_RECRUIT_CAVEMAN: "CANNOT_RECRUIT_CAVEMAN";
1128
+ readonly INSUFFICIENT_RESOURCES: "INSUFFICIENT_RESOURCES";
1129
+ readonly INVALID_CAVEMAN_PLACEMENT: "INVALID_CAVEMAN_PLACEMENT";
1130
+ readonly CAVEMAN_NOT_FOUND: "CAVEMAN_NOT_FOUND";
1131
+ readonly NOT_TRIBE_MODE: "NOT_TRIBE_MODE";
812
1132
  };
813
1133
  type ErrorCodeType = (typeof ErrorCode)[keyof typeof ErrorCode];
814
1134
  /**
@@ -929,6 +1249,18 @@ declare const TranslationKey: {
929
1249
  readonly ERROR_QUEEN_HOLDER_CANNOT_USE_DRAGON: "error.queenHolderCannotUseDragon";
930
1250
  readonly ERROR_BUILDING_NOT_FOUND: "error.buildingNotFound";
931
1251
  readonly ERROR_INVALID_OPTIONAL_ACTION: "error.invalidOptionalAction";
1252
+ readonly ERROR_GIANT_POOL_EMPTY: "error.giantPoolEmpty";
1253
+ readonly ERROR_GIANT_NOT_FOUND: "error.giantNotFound";
1254
+ readonly ERROR_INVALID_GIANT_PLACEMENT: "error.invalidGiantPlacement";
1255
+ readonly ERROR_NOT_AOG_MODE: "error.notAogMode";
1256
+ readonly ERROR_FIRE_TOKEN_POOL_EMPTY: "error.fireTokenPoolEmpty";
1257
+ readonly ERROR_FIRE_TOKEN_INVALID_POSITION: "error.fireTokenInvalidPosition";
1258
+ readonly ERROR_NO_PENDING_FIRE_TOKEN: "error.noPendingFireToken";
1259
+ readonly ERROR_CANNOT_RECRUIT_CAVEMAN: "error.cannotRecruitCaveman";
1260
+ readonly ERROR_INSUFFICIENT_RESOURCES: "error.insufficientResources";
1261
+ readonly ERROR_INVALID_CAVEMAN_PLACEMENT: "error.invalidCavemanPlacement";
1262
+ readonly ERROR_CAVEMAN_NOT_FOUND: "error.cavemanNotFound";
1263
+ readonly ERROR_NOT_TRIBE_MODE: "error.notTribeMode";
932
1264
  };
933
1265
  type TranslationKeyType = (typeof TranslationKey)[keyof typeof TranslationKey];
934
1266
  /**
@@ -1111,6 +1443,45 @@ type GameEventCallbacks = {
1111
1443
  onGameEnd?: (event: {
1112
1444
  game: GameState;
1113
1445
  }) => void;
1446
+ /** Called after a lord places a knight on their kingdom (QueenDomino) */
1447
+ onKnightPlaced?: (event: {
1448
+ game: GameState;
1449
+ lordId: string;
1450
+ }) => void;
1451
+ /** Called after a lord constructs a building (QueenDomino) */
1452
+ onBuildingConstructed?: (event: {
1453
+ game: GameState;
1454
+ lordId: string;
1455
+ buildingId: number;
1456
+ }) => void;
1457
+ /** Called after a lord uses the dragon to destroy a building (QueenDomino) */
1458
+ onDragonUsed?: (event: {
1459
+ game: GameState;
1460
+ lordId: string;
1461
+ buildingId: number;
1462
+ }) => void;
1463
+ /** Called after a lord places a fire token on their kingdom (Origins) */
1464
+ onFireTokenPlaced?: (event: {
1465
+ game: GameState;
1466
+ lordId: string;
1467
+ }) => void;
1468
+ /** Called after a lord recruits a caveman from the cave board (Origins Tribe) */
1469
+ onCavemanRecruited?: (event: {
1470
+ game: GameState;
1471
+ lordId: string;
1472
+ cavemanId: number;
1473
+ }) => void;
1474
+ /** Called after a lord places a giant on a crown in their kingdom */
1475
+ onGiantPlaced?: (event: {
1476
+ game: GameState;
1477
+ lordId: string;
1478
+ }) => void;
1479
+ /** Called after a lord sends a giant to an opponent's kingdom */
1480
+ onGiantSent?: (event: {
1481
+ game: GameState;
1482
+ lordId: string;
1483
+ targetPlayerId: string;
1484
+ }) => void;
1114
1485
  };
1115
1486
  /**
1116
1487
  * Wraps a GameEngine to emit event callbacks after each state-changing method.
@@ -1169,6 +1540,10 @@ type BuildingsRepository = {
1169
1540
  getAll: () => BuildingTile[];
1170
1541
  };
1171
1542
 
1543
+ type CavemenRepository = {
1544
+ getAll: () => CavemanTile[];
1545
+ };
1546
+
1172
1547
  type DominoesRepository = {
1173
1548
  getForMode: (mode: GameMode) => Domino[] | [];
1174
1549
  };
@@ -1177,6 +1552,10 @@ type ModeRepository = {
1177
1552
  getAvailables: () => GameMode[];
1178
1553
  };
1179
1554
 
1555
+ type QuestTilesRepository = {
1556
+ getAll: () => QuestTile[];
1557
+ };
1558
+
1180
1559
  type RuleRepository = {
1181
1560
  getAll: () => Rules;
1182
1561
  getAllExtra: () => ExtraRule[];
@@ -1274,10 +1653,12 @@ declare const getStrategy: (name: string, custom?: Record<string, BotStrategy>)
1274
1653
  */
1275
1654
  declare const getStrategyNames: () => string[];
1276
1655
 
1656
+ type ConstructBuildingUseCase = (game: GameWithNextAction, lordId: string, buildingId: number, position: Position) => GameStateResult;
1657
+
1277
1658
  /**
1278
1659
  * The types of state-changing actions that can be recorded.
1279
1660
  */
1280
- type ActionType = "createGame" | "addPlayers" | "addExtraRules" | "startGame" | "chooseDomino" | "placeDomino" | "discardDomino";
1661
+ type ActionType = "createGame" | "addPlayers" | "addExtraRules" | "startGame" | "chooseDomino" | "placeDomino" | "discardDomino" | "placeGiant" | "sendGiant";
1281
1662
  /**
1282
1663
  * Payload types for each action, containing only the command parameters
1283
1664
  * (excluding the game state, which is too large to store).
@@ -1306,6 +1687,16 @@ type ActionPayloadMap = {
1306
1687
  discardDomino: {
1307
1688
  lordId: string;
1308
1689
  };
1690
+ placeGiant: {
1691
+ lordId: string;
1692
+ position: Position;
1693
+ };
1694
+ sendGiant: {
1695
+ lordId: string;
1696
+ giantIndex: number;
1697
+ targetPlayerId: string;
1698
+ targetCrownPosition: Position;
1699
+ };
1309
1700
  };
1310
1701
  /**
1311
1702
  * A single recorded action in the game log.
@@ -1471,13 +1862,15 @@ declare const getHistorySize: (history: GameHistory) => {
1471
1862
  future: number;
1472
1863
  };
1473
1864
 
1474
- type PlaceKnightUseCase = (game: GameWithNextAction, lordId: string, position: Position) => GameStateResult;
1865
+ type PlaceFireTokenUseCase = (game: GameWithNextAction, lordId: string, position: Position) => GameStateResult;
1475
1866
 
1476
- type ConstructBuildingUseCase = (game: GameWithNextAction, lordId: string, buildingId: number, position: Position) => GameStateResult;
1867
+ type PlaceGiantUseCase = (game: GameWithNextAction, lordId: string, position: Position) => GameStateResult;
1477
1868
 
1478
- type UseDragonUseCase = (game: GameWithNextAction, lordId: string, buildingId: number) => GameStateResult;
1869
+ type PlaceKnightUseCase = (game: GameWithNextAction, lordId: string, position: Position) => GameStateResult;
1479
1870
 
1480
- type SkipOptionalActionUseCase = (game: GameWithNextAction, lordId: string) => GameStateResult;
1871
+ type RecruitCavemanUseCase = (game: GameWithNextAction, lordId: string, cavemanId: number, position: Position, resourcePositions: Position[]) => GameStateResult;
1872
+
1873
+ type SendGiantUseCase = (game: GameWithNextAction, lordId: string, giantIndex: number, targetPlayerId: string, targetCrownPosition: Position) => GameStateResult;
1481
1874
 
1482
1875
  /**
1483
1876
  * Serializes a game state to a JSON string.
@@ -1524,6 +1917,10 @@ declare const createSavePoint: (game: GameState) => GameSavePoint;
1524
1917
  */
1525
1918
  declare const restoreFromSavePoint: (savePoint: GameSavePoint) => Result<GameState>;
1526
1919
 
1920
+ type SkipOptionalActionUseCase = (game: GameWithNextAction, lordId: string) => GameStateResult;
1921
+
1922
+ type UseDragonUseCase = (game: GameWithNextAction, lordId: string, buildingId: number) => GameStateResult;
1923
+
1527
1924
  /**
1528
1925
  * Creates a new Kingdomino game engine instance.
1529
1926
  *
@@ -1549,4 +1946,4 @@ declare const restoreFromSavePoint: (savePoint: GameSavePoint) => Result<GameSta
1549
1946
  */
1550
1947
  declare const createGameEngine: (config: Partial<EngineConfig>) => GameEngine;
1551
1948
 
1552
- export { type ActionEntry, ActionExecutionError, type ActionPayloadMap, type ActionType, type AddExtraRulesCommand, type AddPlayersCommand, type BasicRules, type BotStrategy, type BuildersBoard, type BuildingSlot, type BuildingTile, type BuildingsRepository, type CalculateScoreCommand, type CanPlaceDominoCommand, type ChooseDominoCommand, type ConstructBuildingCommand, type ConstructBuildingUseCase, type CreateGameCommand, type Crown, type DebugLogEntry, type DebugLogLevel, type DebugLogger, type DebugOptions, type DeserializeGameCommand, type DiscardDominoCommand, type DomainError, DomainException, type Domino, type DominoesRepository, type DynastyResult, type EmptyGround, type EmptyTile, type EndGameScoring, type EndGameScoringType, type EngineConfig, ErrorCode, type ErrorCodeType, type ExtraRule, type FinalResult, GRIDSIZE, GROUND, type Game, type GameActionLog, type GameEngine, type GameEventCallbacks, type GameHistory, type GameMode, type GameSavePoint, type GameState, type GameStateResult, type GameStateSummary, type GameSteps, type GameWithNextAction, type GameWithNextStep, type GameWithResults, type GetDynastyResultCommand, type GetExtraRulesCommand, type GetModesCommand, type GetResultCommand, type GetValidPlacementsCommand, type Ground, type ImmediateBonus, type ImmediateBonusType, InvalidStepError, type Kingdom, type Knight, type Logger, type Lord, MAX_KINGDOM_SIZE, type ModeRepository, type NextAction, type NextStep, NotFoundError, type ObjectValues, type PickContext, type PlaceContext, type PlaceDominoCommand, type PlaceKnightCommand, type PlaceKnightUseCase, type PlacedBuilding, type Player, type PlayerActions, type PlayerInput, type PlayerPayload, type Players, type PlayersPayload, type Position, type QueenDominoState, RedoError, type RevealsDomino, type Rotation, type RuleRepository, type Rules, type Score, type ScoreResult, type SelectedRules, type SerializeGameCommand, type ShuffleMethod, type SkipOptionalActionCommand, type SkipOptionalActionUseCase, type StartGameCommand, StepExecutionError, type StrategyName, type Tile, TranslationKey, type TranslationKeyType, type Translator, UndoError, type UseDragonCommand, type UseDragonUseCase, type UuidMethod, type ValidPlacement, ValidationError, type ValidationIssue, type ValidationSeverity, advancedStrategy, appendAction, canRedo, canUndo, clearHistory, createActionLog, createDomainError, createGameEngine, createGameHistory, createSavePoint, createTranslator, defaultTranslations, defaultTranslator, deserializeGame, errorCodeToTranslationKey, expertStrategy, gameSteps, getActions, getActionsByTurn, getActionsByType, getHistorySize, getStrategy, getStrategyNames, greedyStrategy, isBotTurn, isGameWithNextAction, isGameWithNextStep, playBotTurn, playBotTurns, playerActions, pushState, randomStrategy, redo, replayActions, restoreFromSavePoint, serializeGame, summarizeGameState, translateErrorCode, undo, validateGameState, wrapWithActionLog, wrapWithDebug, wrapWithEvents };
1949
+ export { type ActionEntry, ActionExecutionError, type ActionPayloadMap, type ActionType, type AddExtraRulesCommand, type AddPlayersCommand, type AgeOfGiantsState, type BasicRules, type BotStrategy, type BuildersBoard, type BuildingSlot, type BuildingTile, type BuildingsRepository, type CalculateScoreCommand, type CanPlaceDominoCommand, type CaveBoard, type CavemanTile, type CavemenRepository, type ChooseDominoCommand, type ConstructBuildingCommand, type ConstructBuildingUseCase, type CreateGameCommand, type Crown, type DebugLogEntry, type DebugLogLevel, type DebugLogger, type DebugOptions, type DeserializeGameCommand, type DiscardDominoCommand, type DomainError, DomainException, type Domino, type DominoesRepository, type DynastyResult, type EmptyGround, type EmptyTile, type EndGameScoring, type EndGameScoringType, type EngineConfig, ErrorCode, type ErrorCodeType, type ExtraRule, type FinalResult, type FireTokenPool, GRIDSIZE, GROUND, type Game, type GameActionLog, type GameEngine, type GameEventCallbacks, type GameHistory, type GameMode, type GameSavePoint, type GameState, type GameStateResult, type GameStateSummary, type GameSteps, type GameWithNextAction, type GameWithNextStep, type GameWithResults, type GetDynastyResultCommand, type GetExtraRulesCommand, type GetModesCommand, type GetResultCommand, type GetValidPlacementsCommand, type Ground, type HunterGathererKind, type HunterGathererTile, type ImmediateBonus, type ImmediateBonusType, InvalidStepError, type Kingdom, type Knight, type Logger, type Lord, MAX_KINGDOM_SIZE, type ModeRepository, type NextAction, type NextStep, NotFoundError, type ObjectValues, type OriginsState, type OriginsSubMode, type PendingFireToken, type PickContext, type PlaceContext, type PlaceDominoCommand, type PlaceFireTokenCommand, type PlaceFireTokenUseCase, type PlaceGiantCommand, type PlaceGiantUseCase, type PlaceKnightCommand, type PlaceKnightUseCase, type PlacedBuilding, type PlacedCaveman, type PlacedFireToken, type PlacedGiant, type Player, type PlayerActions, type PlayerInput, type PlayerPayload, type Players, type PlayersPayload, type Position, type QueenDominoState, type QuestTile, type QuestTilesRepository, type QuestType, type RecruitCavemanCommand, type RecruitCavemanUseCase, RedoError, type Resource, type ResourceType, type RevealsDomino, type Rotation, type RuleRepository, type Rules, type Score, type ScoreResult, type SelectedRules, type SendGiantCommand, type SendGiantUseCase, type SerializeGameCommand, type ShuffleMethod, type SkipOptionalActionCommand, type SkipOptionalActionUseCase, type StartGameCommand, StepExecutionError, type StrategyName, type Tile, type TotemBonus, type TotemState, TranslationKey, type TranslationKeyType, type Translator, UndoError, type UseDragonCommand, type UseDragonUseCase, type UuidMethod, type ValidPlacement, ValidationError, type ValidationIssue, type ValidationSeverity, WARRIOR_POWER, type WarriorTile, type WarriorType, advancedStrategy, appendAction, canRedo, canUndo, clearHistory, createActionLog, createDomainError, createGameEngine, createGameHistory, createSavePoint, createTranslator, defaultTranslations, defaultTranslator, deserializeGame, errorCodeToTranslationKey, expertStrategy, gameSteps, getActions, getActionsByTurn, getActionsByType, getHistorySize, getStrategy, getStrategyNames, greedyStrategy, hunterGathererKinds, isBotTurn, isGameWithNextAction, isGameWithNextStep, originsSubModes, playBotTurn, playBotTurns, playerActions, pushState, questTypes, randomStrategy, redo, replayActions, resourceTypes, restoreFromSavePoint, serializeGame, summarizeGameState, translateErrorCode, undo, validateGameState, warriorTypes, wrapWithActionLog, wrapWithDebug, wrapWithEvents };