@kingdomsconnected/types 1.6.0 → 1.6.2

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.
@@ -18,18 +18,35 @@ declare global {
18
18
  /**
19
19
  * Dispatched once per accepted death report. Call player.revive() to request revival; there is no automatic respawn.
20
20
  *
21
- * `killer` is the player whose blow took the last of the health, as the dying player's own client saw it -- null for a fall, a bleed-out, or anything that was not a player. `reason` is the game's own for that last write: `combat` for a blade or a bow, `fall`, `bleeding`, `poison` and so on.
21
+ * `killer` is the player or server NPC whose blow took the last of the health, as the dying player's own client saw it -- null for a fall, a bleed-out, or anything without an identified attacker. `reason` is the game's own for that last write: `combat` for a blade or a bow, `fall`, `bleeding`, `poison` and so on.
22
22
  */
23
- playerDied: [player: Player, killer: Player | null, reason: "unknown" | "combat" | "gunshot" | "starvation" | "collision" | "scripted" | "disintegrate" | "fall" | "poison" | "bleeding" | "selfHarm"];
23
+ playerDied: [player: Player, killer: Player | Npc | null, reason: "unknown" | "combat" | "gunshot" | "starvation" | "collision" | "scripted" | "disintegrate" | "fall" | "poison" | "bleeding" | "selfHarm"];
24
24
 
25
25
  /**
26
- * Dispatched when something takes health off a player: a weapon, an arrow, a fall, a collision, a scripted hit. The hit player's own client reports it, because only it resolved the blow against its armour and its skills, so `amount` is what was really taken. It arrives ahead of the `playerDied` a killing blow causes.
26
+ * Dispatched when something takes health off a player: a weapon, an arrow, a fall, a collision, a scripted hit. Player combat and server NPC melee are raised by the server as it rules on them, after `playerHit` had its say, so `amount` is what the ruling takes; anything else is reported by the hit player's own client, which resolved it against its armour and its skills. It arrives ahead of the `playerDied` a killing blow causes.
27
27
  *
28
- * `attacker` is the player who dealt it, or null. `bodyPart` is where it landed, or null for damage that lands nowhere in particular. The weapon is the attacker's own `rightHandItem` or `leftHandItem`.
28
+ * `attacker` is the player or server NPC who dealt it, or null. `bodyPart` is where it landed, or null for damage that lands nowhere in particular. A player attacker's weapon is available through `rightHandItem` or `leftHandItem`; an NPC's equipped items are in `wearing`.
29
29
  *
30
30
  * Bleeding, poison and hunger wear health down a tick at a time without raising this -- `bleeding`, `poisoning` and `hunger` are live numbers already. The tick that kills does arrive, with its own reason, just before the `playerDied` it causes.
31
31
  */
32
- playerDamage: [player: Player, attacker: Player | null, amount: number, bodyPart: "head" | "torso" | "leftArm" | "rightArm" | "leftLeg" | "rightLeg" | null, reason: "unknown" | "combat" | "gunshot" | "starvation" | "collision" | "scripted" | "disintegrate" | "fall" | "poison" | "bleeding" | "selfHarm"];
32
+ playerDamage: [player: Player, attacker: Player | Npc | null, amount: number, bodyPart: "head" | "torso" | "leftArm" | "rightArm" | "leftLeg" | "rightLeg" | null, reason: "unknown" | "combat" | "gunshot" | "starvation" | "collision" | "scripted" | "disintegrate" | "fall" | "poison" | "bleeding" | "selfHarm"];
33
+
34
+ /**
35
+ * A melee swing aimed at another player was admitted by the server, including a miss. Raised once per attack generation, after presentation admission. Use it to track combat inactivity in your resource.
36
+ */
37
+ playerAttack: [player: Player, opponent: Player];
38
+
39
+ /**
40
+ * A resource called cancelCombat for this pair. Raised after the cancellation was sent to both players and their observers.
41
+ */
42
+ playerCombatCancelled: [first: Player, second: Player];
43
+
44
+ /**
45
+ * Dispatched when another player's blade or arrow, or a server NPC's melee attack, lands on a player, before anything is taken -- the place for teams, safe zones, friendly fire and damage rules. The game resolved the blow against the guard the victim really held -- whether it was blocked, perfectly or not, and where it landed -- and the server works out what a swing takes from there; it has checked that the swing was one it relayed and could still land, or that the arrow was one whose impact it accepted, and that the two stood within reach. Only what is ruled here comes off the victim's health, on every client at once.
46
+ *
47
+ * Return `false` from a handler to refuse the blow: no health is taken and no `playerDamage` follows. NPC melee uses the victim client's native damage with `priced: false`; set `hit.damage` to change it. For priced player swings, scale `hit.modifiers` to change how a swing is worked out -- a stronger attack, weaker armour -- or set `hit.damage` to say outright what it takes: `0` for a blow that lands harmlessly, more for a heavier one. Either way the blow is still seen and heard: the blades met. Handlers run synchronously, so the decision cannot wait on anything awaited.
48
+ */
49
+ playerHit: [player: Player, attacker: Player | Npc, hit: PlayerHit];
33
50
 
34
51
  /**
35
52
  * Dispatched when a limb becomes injured -- usually a blow landing there, sometimes a fall on both legs. `player.injuries` already says so. A limb hit again while injured stays injured and raises nothing new.
@@ -120,6 +137,11 @@ declare global {
120
137
  */
121
138
  playerInventoryReady: [player: Player];
122
139
 
140
+ /**
141
+ * A move or patrol leg reached its destination, was blocked, or failed. Intermediate path corners do not emit this event.
142
+ */
143
+ horseIntentDone: [horse: Horse, status: string];
144
+
123
145
  /**
124
146
  * Dispatched immediately after a horse is created and replicated, whether by `Horse.spawn`, the `/horse` command, or anything else.
125
147
  */
@@ -350,14 +372,14 @@ declare global {
350
372
  npcIntentDone: [npc: Npc, status: string];
351
373
 
352
374
  /**
353
- * Dispatched after health came off the ledger. The attacker's own client resolved the hit and the server agreed to it, so `amount` is what was actually taken, not what was claimed.
375
+ * Dispatched after health came off the ledger. For melee, the victim's simulator resolves the native hit and the server checks the accepted swing before changing health. `amount` is what was actually taken.
354
376
  */
355
- npcDamage: [npc: Npc, attacker: Player | null, amount: number];
377
+ npcDamage: [npc: Npc, attacker: Player | Npc | null, amount: number];
356
378
 
357
379
  /**
358
380
  * Dispatched when the last of an NPC's health goes. The body stays as a corpse and the handle keeps resolving.
359
381
  */
360
- npcDeath: [npc: Npc, attacker: Player | null];
382
+ npcDeath: [npc: Npc, attacker: Player | Npc | null];
361
383
 
362
384
  /**
363
385
  * Dispatched when a dead NPC is brought back. Every client makes a new body for it.
@@ -379,6 +401,16 @@ declare global {
379
401
  */
380
402
  npcSimulatorChange: [npc: Npc, player: Player | null];
381
403
 
404
+ /**
405
+ * One accepted waypoint outcome; intermediate path corners do not emit it.
406
+ */
407
+ patrolWaypoint: [actor: Npc, info: PatrolState & { status: 'reached' | 'blocked' | 'failed' }];
408
+
409
+ /**
410
+ * A patrol ended, failed, or was replaced. Edits to its definition do not replace its snapshot.
411
+ */
412
+ patrolFinished: [actor: Npc, info: PatrolState & { status: 'completed' | 'failed' | 'cancelled' }];
413
+
382
414
  /**
383
415
  * Dispatched when a player starts or stops following a quest in the game's journal, whichever way it happened: the track button, the game auto-tracking a quest that turns active, or the untrack that follows finishing or failing one. The client reports it -- following a quest is decided there and cannot be refused here -- so a handler reacts rather than vetoes. It fires only on an actual change, and only for a quest that player was given.
384
416
  */
@@ -432,9 +464,9 @@ declare global {
432
464
  siegeEngineReady: [engine: SiegeEngine];
433
465
 
434
466
  /**
435
- * Dispatched when a player presses a `usable` engine's native prompt, standing at it, on the step the prompt was offered for. Return false to refuse; otherwise the engine loads, or fires along the player's facing at `range` with the player as the attacker. A handler that works the engine itself should refuse, so it is not worked twice.
467
+ * Dispatched when a player asks something of a `usable` engine, standing at it: to take its place (`operate`) or a free winch (`winch`) from the game's own prompt, or -- in its place -- to `load` it or `fire` it where they laid it, with the player as the attacker. Return false to refuse. `leave` reports a player stepping away from either and cannot be refused. A handler that works the engine itself should refuse, so it is not worked twice.
436
468
  */
437
- siegeEngineUse: [player: Player, engine: SiegeEngine, action: "load" | "fire"];
469
+ siegeEngineUse: [player: Player, engine: SiegeEngine, action: "operate" | "winch" | "leave" | "load" | "fire"];
438
470
 
439
471
  /**
440
472
  * Dispatched the moment an engine lets its projectile go, partway through the shot `fire` started.
@@ -442,7 +474,7 @@ declare global {
442
474
  siegeFire: [engine: SiegeEngine, attacker: Player | null, target: Vector3];
443
475
 
444
476
  /**
445
- * Dispatched where a projectile came down: what the player nearest the target saw it hit, checked against the arc it was thrown on, or the target itself when nobody could see it. Players within `damageRadius` have already been told to take their share, and NPCs have taken theirs. `engine` is null when it was destroyed while the stone was in the air.
477
+ * Dispatched where a projectile came down: what the reporting player -- the attacker when near enough, else whoever is nearest the target -- saw it hit, checked against the arc it was thrown on, or the target itself when nobody could see it. Players within `damageRadius` have already been told to take their share, and NPCs have taken theirs. `engine` is null when it was destroyed while the stone was in the air.
446
478
  */
447
479
  siegeImpact: [engine: SiegeEngine | null, position: Vector3, attacker: Player | null];
448
480
 
@@ -456,6 +488,11 @@ declare global {
456
488
  */
457
489
  areaExit: [area: Area, entity: Player | Horse | Cart | Npc, matchingVirtualWorld: boolean];
458
490
 
491
+ /**
492
+ * Raised once after every configured world export has loaded successfully, including an empty list. WorldResource.ready is true inside the handler. A script starting later must check WorldResource.ready first; the event is not replayed. Do not await this event inside resourceStart: exports load after script startup. Handler promises are not awaited.
493
+ */
494
+ worldResourcesReady: [];
495
+
459
496
  /**
460
497
  * A container now exists: a scripted chest, a virtual stash, or one the level places, built in a virtual world the first time anything there asked for it. Every container starts empty; restore saved contents here with `setInventory`. The level's containers in the global world are built before any resource runs, so restore those from `resourceStart` by walking `Stash.all()`.
461
498
  */
@@ -582,11 +619,221 @@ declare global {
582
619
  * Dispatched when a player asks to join, before the connection exists: they hold no player slot, are not counted as online, and are sent nothing -- no resource list, no download, no body. The request waits until every handler has returned and every Promise a handler returned has settled, then it is let in if a player slot is free (otherwise it is refused as full). `connection.reject()` turns it away instead, and so does a handler that throws or rejects, or handlers that have not settled within the server's admission timeout (30 seconds by default, restarted by every `connection.update()`). With no handler at all, every request is let in at once.
583
620
  */
584
621
  playerConnecting: [connection: PendingConnection];
622
+
623
+ /**
624
+ * Dispatched when a blast takes `amount` off an engine with a `maxHealth`, before it is wrecked by it. `health` already reads what is left.
625
+ */
626
+ siegeEngineDamage: [engine: SiegeEngine, amount: number, attacker: Player | null];
627
+
628
+ /**
629
+ * Dispatched when an engine's health runs out. Its operator and crew have been let go, and a stone still in its sling went down with it.
630
+ */
631
+ siegeEngineWreck: [engine: SiegeEngine, attacker: Player | null];
632
+
633
+ /**
634
+ * Dispatched immediately after a siege ladder is placed.
635
+ */
636
+ siegeLadderSpawn: [ladder: SiegeLadder];
637
+
638
+ /**
639
+ * Dispatched while a siege ladder is being removed. The handle still resolves.
640
+ */
641
+ siegeLadderDestroy: [ladder: SiegeLadder];
642
+
643
+ /**
644
+ * Dispatched when a player asks to push a `usable` ladder from the walk at its top, or to raise a fallen one from beside its foot. Return false to refuse.
645
+ */
646
+ siegeLadderUse: [player: Player, ladder: SiegeLadder, action: "push" | "raise"];
647
+
648
+ /**
649
+ * Dispatched when a pushed ladder hits the ground. Anyone who was on it was thrown off as it began to fall, and took the game's own fall.
650
+ */
651
+ siegeLadderFall: [ladder: SiegeLadder, pusher: Player | null];
652
+
653
+ /**
654
+ * Dispatched when a raised ladder leans on its wall again and can be climbed.
655
+ */
656
+ siegeLadderRaise: [ladder: SiegeLadder];
657
+
658
+ /**
659
+ * Dispatched immediately after a stone pile is placed.
660
+ */
661
+ stonePileSpawn: [pile: StonePile];
662
+
663
+ /**
664
+ * Dispatched while a stone pile is being removed. The handle still resolves.
665
+ */
666
+ stonePileDestroy: [pile: StonePile];
667
+
668
+ /**
669
+ * Dispatched when a player takes a stone off a pile. The game's own stone throwing has already lifted it and heaves it over the wall at once, so it cannot be refused; make the pile not `usable` to stop the next one.
670
+ */
671
+ stonePileThrow: [player: Player, pile: StonePile];
672
+
673
+ /**
674
+ * Dispatched where a thrown stone first met something, as its thrower saw it, checked to lie within 30 m of its pile. Players within the pile's `damageRadius` have been told to take their share, and NPCs have taken theirs.
675
+ */
676
+ stoneImpact: [pile: StonePile | null, position: Vector3, attacker: Player];
585
677
  }
586
678
 
587
679
  /** Names of native events available in this scripting environment. */
588
680
  type EventName = keyof EventMap;
589
681
 
682
+ /**
683
+ * Writable player stats, in native units. Use getStat and the server's setStat.
684
+ */
685
+ const PlayerStat: {
686
+ /**
687
+ * Current health, in native units. Zero can kill.
688
+ */
689
+ readonly Health: "health";
690
+
691
+ /**
692
+ * Current stamina; the game continues spending and regenerating it.
693
+ */
694
+ readonly Stamina: "stamina";
695
+
696
+ /**
697
+ * Current energy reserve; higher means better rested.
698
+ */
699
+ readonly Exhaust: "exhaust";
700
+
701
+ /**
702
+ * Current nourishment; higher means better fed.
703
+ */
704
+ readonly Hunger: "hunger";
705
+ };
706
+
707
+ /**
708
+ * Read-only computed player stats. Use getDerivedStat; these values cannot be passed to setStat.
709
+ */
710
+ const DerivedPlayerStat: {
711
+ /**
712
+ * Total bleeding strength.
713
+ */
714
+ readonly Bleeding: "bleeding";
715
+
716
+ /**
717
+ * Sleepiness; above zero means asleep.
718
+ */
719
+ readonly Sleeping: "sleeping";
720
+
721
+ /**
722
+ * Consciousness; zero means knocked out.
723
+ */
724
+ readonly Consciousness: "consciousness";
725
+
726
+ /**
727
+ * Native drunkenness value.
728
+ */
729
+ readonly Drunkenness: "drunkenness";
730
+
731
+ /**
732
+ * Native poisoning value; not every named poison changes this value.
733
+ */
734
+ readonly Poisoning: "poisoning";
735
+
736
+ /**
737
+ * Effective charisma.
738
+ */
739
+ readonly Charisma: "charisma";
740
+
741
+ /**
742
+ * Effective visibility.
743
+ */
744
+ readonly Visibility: "visibility";
745
+
746
+ /**
747
+ * Effective conspicuousness.
748
+ */
749
+ readonly Conspicuousness: "conspicuousness";
750
+
751
+ /**
752
+ * Effective noise.
753
+ */
754
+ readonly Noise: "noise";
755
+
756
+ /**
757
+ * Native dirtiness reading; reading it does not clean the body or equipment.
758
+ */
759
+ readonly Dirtiness: "dirtiness";
760
+
761
+ /**
762
+ * Native bloodiness reading.
763
+ */
764
+ readonly Bloodiness: "bloodiness";
765
+
766
+ /**
767
+ * Native smell reading.
768
+ */
769
+ readonly Smell: "smell";
770
+
771
+ /**
772
+ * Native smell intensity.
773
+ */
774
+ readonly SmellIntensity: "smellIntensity";
775
+
776
+ /**
777
+ * Native fragrance reading.
778
+ */
779
+ readonly Fragrance: "fragrance";
780
+
781
+ /**
782
+ * Carried weight in the same units as InventoryCapacity.
783
+ */
784
+ readonly CarriedWeight: "carriedWeight";
785
+
786
+ /**
787
+ * Native carrying capacity, including applicable equipment effects.
788
+ */
789
+ readonly InventoryCapacity: "inventoryCapacity";
790
+
791
+ /**
792
+ * Native encumbrance reading.
793
+ */
794
+ readonly Encumbrance: "encumbrance";
795
+
796
+ /**
797
+ * Native hangover reading.
798
+ */
799
+ readonly Hangover: "hangover";
800
+
801
+ /**
802
+ * Computed alcoholism reading, not the persistent soul resource.
803
+ */
804
+ readonly Alcoholism: "alcoholism";
805
+
806
+ /**
807
+ * Effective armor rating.
808
+ */
809
+ readonly ArmorRating: "armorRating";
810
+
811
+ /**
812
+ * Overall armor defense.
813
+ */
814
+ readonly OverallArmorDefense: "overallArmorDefense";
815
+
816
+ /**
817
+ * Overall weapon attack.
818
+ */
819
+ readonly OverallWeaponAttack: "overallWeaponAttack";
820
+
821
+ /**
822
+ * Normalized run speed; not world-space velocity.
823
+ */
824
+ readonly NormalizedRunSpeed: "normalizedRunSpeed";
825
+
826
+ /**
827
+ * Native base run speed.
828
+ */
829
+ readonly RunSpeedBase: "runSpeedBase";
830
+
831
+ /**
832
+ * Native morale reading.
833
+ */
834
+ readonly Morale: "morale";
835
+ };
836
+
590
837
  /**
591
838
  * How a player's body looks: four of the game's own character-component names, and the gender whose catalog they come from.
592
839
  *
@@ -956,6 +1203,136 @@ declare global {
956
1203
  walkEnforced: boolean;
957
1204
  }
958
1205
 
1206
+ /**
1207
+ * One number per damage type a blow is worked out in. A blade's stab, slash and smash are priced separately and added; a blow runs only the passes its attack and weapon call for.
1208
+ */
1209
+ interface DamagePasses {
1210
+ /**
1211
+ * The stab pass.
1212
+ */
1213
+ stab: number;
1214
+
1215
+ /**
1216
+ * The slash pass.
1217
+ */
1218
+ slash: number;
1219
+
1220
+ /**
1221
+ * The smash pass.
1222
+ */
1223
+ smash: number;
1224
+ }
1225
+
1226
+ /**
1227
+ * Scales a `playerHit` handler puts on the server's price of a melee blow, each 1 until a handler changes it. The server works the blow out again with them, step by step as the game does: a heavier attack has to get through the same armour and the same block, so doubling `attack` does not simply double the damage. Never negative.
1228
+ */
1229
+ interface PlayerHitModifiers {
1230
+ /**
1231
+ * Scales the attacker's attack in every pass, after their weapon, strength, skill and the swing itself.
1232
+ */
1233
+ attack: number;
1234
+
1235
+ /**
1236
+ * Scales the victim's armour where the blow landed.
1237
+ */
1238
+ defense: number;
1239
+
1240
+ /**
1241
+ * Scales what the victim's block put up. Nothing for a blow that was not blocked.
1242
+ */
1243
+ block: number;
1244
+
1245
+ /**
1246
+ * Scales the health the blow takes, once everything else is worked out. The game's own cap of 200 a blow is applied before it, so this can go past it.
1247
+ */
1248
+ health: number;
1249
+ }
1250
+
1251
+ /**
1252
+ * A player or NPC blow, as `playerHit` shows it before the referee rules. `damage` is what the blow will take and `modifiers` scale how the server works it out; a handler may change either. Every other field describes what happened and is read-only in effect.
1253
+ */
1254
+ interface PlayerHit {
1255
+ /**
1256
+ * Health the blow takes. For melee between players the server works it out itself, the way the game does, from the attacker's weapon and its wear, both players' strength and skills, the armour the victim wears where it landed, the block and the perks and buffs it can vouch for; for NPC melee or an arrow it is what the victim's own game worked out. Set it and it stands as set: `modifiers` are then ignored. Never negative.
1257
+ */
1258
+ damage: number;
1259
+
1260
+ /**
1261
+ * Health the game itself took for the blow on the machine that saw it land. Matches `damage` unless a perk that depends on the moment -- a heavy weapon's, a first strike's -- was in play, which the server leaves out.
1262
+ */
1263
+ engineDamage: number;
1264
+
1265
+ /**
1266
+ * Whether the server worked `damage` out itself: true for a swing, false for an arrow.
1267
+ */
1268
+ priced: boolean;
1269
+
1270
+ /**
1271
+ * The attacker's weapon as 32 hex digits, or null for a bare hand.
1272
+ */
1273
+ weapon: string | null;
1274
+
1275
+ /**
1276
+ * The attacker's attack in each pass, after the swing's own strength and before `modifiers`.
1277
+ */
1278
+ attack: DamagePasses;
1279
+
1280
+ /**
1281
+ * The victim's armour in each pass where the blow landed, before `modifiers`.
1282
+ */
1283
+ armor: DamagePasses;
1284
+
1285
+ /**
1286
+ * What the victim's block put up, or 0 when nothing blocked it.
1287
+ */
1288
+ blockDefense: number;
1289
+
1290
+ /**
1291
+ * How much the place it landed multiplies the damage by: 1.5 for the head, 1 for the torso, 0.7 for a limb.
1292
+ */
1293
+ bodyPartCoefficient: number;
1294
+
1295
+ /**
1296
+ * Scales on the server's price; see `PlayerHitModifiers`. Ignored for an arrow.
1297
+ */
1298
+ modifiers: PlayerHitModifiers;
1299
+
1300
+ /**
1301
+ * Stamina the blow cost the victim. Already spent: stamina decides their next block, which cannot wait for a ruling.
1302
+ */
1303
+ stamina: number;
1304
+
1305
+ /**
1306
+ * The limb it landed on, or null for none in particular.
1307
+ */
1308
+ bodyPart: "head" | "torso" | "leftArm" | "rightArm" | "leftLeg" | "rightLeg" | null;
1309
+
1310
+ /**
1311
+ * The game's own reason for the damage: `combat` for a blade or a bow.
1312
+ */
1313
+ reason: "unknown" | "combat" | "gunshot" | "starvation" | "collision" | "scripted" | "disintegrate" | "fall" | "poison" | "bleeding" | "selfHarm";
1314
+
1315
+ /**
1316
+ * Whether it was a swing or an arrow.
1317
+ */
1318
+ source: "melee" | "missile";
1319
+
1320
+ /**
1321
+ * The victim's block caught it.
1322
+ */
1323
+ blocked: boolean;
1324
+
1325
+ /**
1326
+ * The victim's perfect block caught it. The game takes nothing for one.
1327
+ */
1328
+ perfectBlock: boolean;
1329
+
1330
+ /**
1331
+ * The victim's block gave way under it.
1332
+ */
1333
+ blockBroken: boolean;
1334
+ }
1335
+
959
1336
  /**
960
1337
  * Which of a player's limbs carry an injury, one flag per limb. An injury is the game's own: it lowers the stamina ceiling (`healthyStamina`), can bleed, and heals slowly by itself or at once with a bandage or `player.heal`.
961
1338
  */
@@ -1069,12 +1446,12 @@ declare global {
1069
1446
  readonly healthyStamina: number;
1070
1447
 
1071
1448
  /**
1072
- * Current tiredness, in the game's own units.
1449
+ * Current energy reserve, in the game's own units. Higher means better rested.
1073
1450
  */
1074
1451
  readonly exhaust: number;
1075
1452
 
1076
1453
  /**
1077
- * Tiredness capacity, in the game's own units.
1454
+ * Maximum energy reserve, in the game's own units.
1078
1455
  */
1079
1456
  readonly maxExhaust: number;
1080
1457
 
@@ -1144,7 +1521,7 @@ declare global {
1144
1521
  readonly relativeSkills: SoulSkills;
1145
1522
 
1146
1523
  /**
1147
- * The velocity the body's own animation was driven by this frame, not the one its physics settled on.
1524
+ * On the owning machine, the velocity the body's own animation was driven by this frame, not the one its physics settled on. Everywhere else, measured from successive replicated positions.
1148
1525
  */
1149
1526
  readonly velocity: Vector3;
1150
1527
 
@@ -1158,21 +1535,6 @@ declare global {
1158
1535
  */
1159
1536
  readonly inAir: boolean;
1160
1537
 
1161
- /**
1162
- * The engine's own locomotion pace tag -- walk, jog, sprint -- as its animation system picked it. Raw Mannequin tag ids; 255 means nothing is set.
1163
- */
1164
- readonly moveSpeedTag: number;
1165
-
1166
- /**
1167
- * The engine's own movement direction tag. Raw Mannequin tag ids; 255 means nothing is set.
1168
- */
1169
- readonly moveDirTag: number;
1170
-
1171
- /**
1172
- * The engine's own stance tag -- upright, sneaking, sitting, lying. Raw Mannequin tag ids; 255 means nothing is set.
1173
- */
1174
- readonly stanceTag: number;
1175
-
1176
1538
  /**
1177
1539
  * Whether this player is crouched, as their own game's crouch action reports it. False once their body is gone.
1178
1540
  */
@@ -1285,6 +1647,18 @@ declare global {
1285
1647
  */
1286
1648
  toString(): string;
1287
1649
 
1650
+ /**
1651
+ * Reads the latest reported stat in native units. Returns zero when no valid body snapshot exists; check player.ready to distinguish that from a real zero. Throws for an unknown stat or invalid arguments.
1652
+ * @param stat A PlayerStat value.
1653
+ */
1654
+ getStat(stat: "health" | "stamina" | "exhaust" | "hunger"): number;
1655
+
1656
+ /**
1657
+ * Reads a computed stat from the latest body snapshot. Bleeding, Sleeping, Consciousness, Drunkenness and Poisoning follow the body as it changes; the others are sampled about every 250 ms to a hundredth of a native unit, then replicated. Values use native units and can be negative; they are not universally percentages. Returns zero without a valid snapshot. Throws for an unknown stat or invalid arguments. These readings do not override another player's native calculations.
1658
+ * @param stat A DerivedPlayerStat value.
1659
+ */
1660
+ getDerivedStat(stat: "bleeding" | "sleeping" | "consciousness" | "drunkenness" | "poisoning" | "charisma" | "visibility" | "conspicuousness" | "noise" | "dirtiness" | "bloodiness" | "smell" | "smellIntensity" | "fragrance" | "carriedWeight" | "inventoryCapacity" | "encumbrance" | "hangover" | "alcoholism" | "armorRating" | "overallArmorDefense" | "overallWeaponAttack" | "normalizedRunSpeed" | "runSpeedBase" | "morale"): number;
1661
+
1288
1662
  /**
1289
1663
  * Where this player stands on one track: level, XP towards the next one, and unspent perk points.
1290
1664
  * @param track A track name, from `Progression.tracks()`.
@@ -1356,6 +1730,13 @@ declare global {
1356
1730
  */
1357
1731
  revive(): boolean;
1358
1732
 
1733
+ /**
1734
+ * Ends melee combat between these two players and retires their pending blows against each other. Other opponents are left alone. A later attack can start combat again. Consent and timeout rules belong to your resource.
1735
+ * @param opponent The other player. Both sides are cancelled.
1736
+ * @returns True when sent; false for disconnected players, the same player, or different virtual worlds.
1737
+ */
1738
+ cancelCombat(opponent: Player): boolean;
1739
+
1359
1740
  /**
1360
1741
  * Puts this player somewhere, as a spawn rather than as a teleport: their client holds the body still until there is real ground under it, so it cannot fall through a world that has not streamed in yet.
1361
1742
  *
@@ -1434,6 +1815,13 @@ declare global {
1434
1815
  */
1435
1816
  setAppearance(appearance: Partial<Appearance>): boolean;
1436
1817
 
1818
+ /**
1819
+ * Grants or revokes World Builder access for this player. Multiplayer connections start without access. Enabling allows F7 and the client MapEditor.open API; disabling also closes an open editor. The permission lasts until changed or disconnected and does not affect other players. Offline editing is always allowed.
1820
+ * @param enabled Whether this player may open World Builder.
1821
+ * @returns True when the permission was sent; false for a player with no connection. Throws unless enabled is a boolean.
1822
+ */
1823
+ setWorldBuilderEnabled(enabled: boolean): boolean;
1824
+
1437
1825
  /**
1438
1826
  * Puts a pace rule on this player. `walkByDefault` makes walking the pace they keep coming back to and leaves their own key working; `walkEnforced` forbids running and sprinting outright, and their key stops mattering.
1439
1827
  *
@@ -1448,7 +1836,7 @@ declare global {
1448
1836
  setMovementMode(mode: Partial<MovementMode>): boolean;
1449
1837
 
1450
1838
  /**
1451
- * Grants items into this player's inventory, which the server holds; their game shows them on the next tick. `Inventory.add` does the same and can also set the items' properties.
1839
+ * Grants items into this player's inventory, which the server holds; their game shows them on the next tick and announces them with its own "You received" toast. `Inventory.add` does the same, can set the items' properties, and can leave out the toast.
1452
1840
  * @param item Item class GUID, or the exact name the game's own item tables use.
1453
1841
  * @param amount How many to grant; defaults to 1, and at most 10000.
1454
1842
  * @returns True when the items were added; false for an unknown item, an amount outside 1..10000, or a player with no inventory.
@@ -1456,7 +1844,7 @@ declare global {
1456
1844
  giveItem(item: string, amount?: number): boolean;
1457
1845
 
1458
1846
  /**
1459
- * Takes items of a class out of this player's inventory, across its rows, all of them or none. The server holds the inventory, so the promise is already settled when it is returned; it stays a promise so existing scripts keep working. To move items between players use `Inventory.transfer`, which cannot lose them half way.
1847
+ * Takes items of a class out of this player's inventory, across its rows, all of them or none. The server holds the inventory, so the promise is already settled when it is returned; it stays a promise so existing scripts keep working. Their game announces the loss with its own toast; `Inventory.remove` can leave it out. To move items between players use `Inventory.transfer`, which cannot lose them half way.
1460
1848
  * @param item Item class GUID, or the exact name the game's own item tables use. The same spelling `giveItem` takes.
1461
1849
  * @param amount How many units to take; defaults to 1, and at most 10000. Zero is refused rather than read as "all of them".
1462
1850
  * @returns An object carrying `removed` (the amount when it happened, otherwise 0), `requested`, `ok`, and `reason` (empty on success, otherwise the inventory code, such as `insufficientItems`).
@@ -1470,6 +1858,13 @@ declare global {
1470
1858
  */
1471
1859
  dropInventory(options?: { keepEquipped?: boolean }): Stash | null;
1472
1860
 
1861
+ /**
1862
+ * Dresses this player in one of the game's own outfits. Every piece of clothing they wear comes off and stays in their inventory, and a new set of the outfit's clothes is added and worn; weapons and everything else are left as they are. Their game dresses them a moment later, as it does after `Inventory.set`.
1863
+ * @param preset One of the game's own outfits for this player's gender, by a name from `Player.outfitPresets(player.appearance.gender)` or its GUID.
1864
+ * @returns True when the inventory was changed; false for a preset that is not in the catalog or is the other gender's, a player with no inventory, or an inventory with no room.
1865
+ */
1866
+ setOutfit(preset: string): boolean;
1867
+
1473
1868
  /**
1474
1869
  * Reads this player's inventory; the same as `Inventory.get(player)`.
1475
1870
  * @returns A copy of it, or null for a player who is not connected.
@@ -1506,6 +1901,28 @@ declare global {
1506
1901
  */
1507
1902
  hasBuff(buff: string): boolean;
1508
1903
 
1904
+ /**
1905
+ * Sets health, stamina, energy or nourishment on the living body. Call once player.ready is true. Lowering health raises playerDamage with a null attacker; a fatal change also raises playerDied with a null killer. Zero health can kill. Does not clear buffs or revive; normal regeneration and consumption continue.
1906
+ * @param stat Writable PlayerStat; derived stats are rejected.
1907
+ * @param value Finite native value from 0 to 1000000, clamped to the native maximum. Positive health must exceed 0.00001; positive values must not underflow to zero.
1908
+ * @returns True when sent, not confirmation of application; false for a missing, unready or dead body. Throws for invalid arguments or a read-only stat. Requests for a previous life are discarded. Read getStat after the client's next report to observe the result.
1909
+ */
1910
+ setStat(stat: "health" | "stamina" | "exhaust" | "hunger", value: number): boolean;
1911
+
1912
+ /**
1913
+ * Sets this living player's health, raising or lowering it. Lowering raises playerDamage with a null attacker and the amount removed; a fatal change also raises playerDied with a null killer. This includes restoring a lower saved value. Zero can kill; this never revives a dead player. Leaves injuries, poison and bleeding in place. Call after playerSpawned or playerReady when restoring a saved value. The client applies the request asynchronously; health continues to show its last report until a new one arrives.
1914
+ * @param value Health in the same units as player.health. Clamped to maxHealth on the player's client.
1915
+ * @returns True when sent; false when the body is missing, not ready or dead. Throws unless value is a finite number from 0 to 1000000, with positive health greater than 0.00001 after conversion to native float units. A request for a life that has since ended is ignored.
1916
+ */
1917
+ setHealth(value: number): boolean;
1918
+
1919
+ /**
1920
+ * Sets this living player's nourishment, raising or lowering it. Call after playerSpawned or playerReady when restoring a saved value. The client applies the request asynchronously; hunger continues to show its last report until a new one arrives.
1921
+ * @param value Nourishment in the same units as player.hunger. Higher means better fed. Clamped to maxHunger on the player's client.
1922
+ * @returns True when sent; false when the body is missing, not ready or dead. Throws unless value is a finite number from 0 to 1000000 that does not round from positive to zero in native float units. A request for a life that has since ended is ignored.
1923
+ */
1924
+ setHunger(value: number): boolean;
1925
+
1509
1926
  /**
1510
1927
  * Nurses this player back, on their own client and with the game's own recipe -- the one its quests use for a full heal: the `remove_injuries` and `remove_all_posions` cures, which each wipe their whole kind of effect as they land, then health raised through the soul's own setter, the way a potion raises it. What comes off raises `playerInjuryHealed` and `playerBuffRemoved` as usual.
1511
1928
  *
@@ -1559,11 +1976,19 @@ declare global {
1559
1976
  putDownItem(options?: { immediate?: boolean }): boolean;
1560
1977
 
1561
1978
  /**
1562
- * Puts this player in a horse's saddle, the way the game's own forced mount does -- their client plays the climb. It is an instruction to their client, so the seat is reported back like any other mount: `horseMounting` can still refuse it, and `horseMount` and `player.horse` follow once it lands. The player has to be standing near the horse; teleport them beside it first.
1563
- * @param horse The horse to climb onto.
1979
+ * Puts this player in a horse's saddle. Everyone near enough to watch sees it the way it was asked for -- the get-on, or the instant seat -- while a client that only streams the rider in later finds them already seated. It is an instruction to their client, so the seat is reported back like any other mount: `horseMounting` can still refuse it, and `horseMount` and `player.horse` follow once it lands. The player has to be standing near the horse; teleport them beside it first.
1980
+ * @param horse The horse to get on.
1981
+ * @param options `instant` puts them straight into the seat, as the game's own forced mount does; by default they play the get-on a player plays at a horse.
1564
1982
  * @returns True when the order went out; false when the horse is dead or somebody else is riding it, or the player has no connection.
1565
1983
  */
1566
- mount(horse: Horse): boolean;
1984
+ mount(horse: Horse, options?: { instant?: boolean }): boolean;
1985
+
1986
+ /**
1987
+ * The game's own outfits, from its clothing presets: what `player.setOutfit` and `Npc.setOutfit` dress a body in. Many belong to one named character.
1988
+ * @param gender Only the outfits authored for this gender. The game will not put a man's clothes on a woman or the reverse, so `player.setOutfit` takes only the presets of the player's own `appearance.gender`.
1989
+ * @returns Preset names, men's first, each gender's in name order.
1990
+ */
1991
+ static outfitPresets(gender?: "male" | "female"): string[];
1567
1992
 
1568
1993
  /**
1569
1994
  * Lists every player currently connected, including those whose body has no pose yet.
@@ -1676,7 +2101,7 @@ declare global {
1676
2101
  revision: number;
1677
2102
 
1678
2103
  /**
1679
- * `add`, `remove`, `properties`, `set`, `transfer`, `wear` when the player's game wore an item down in use, `use` for food, potions and ointments, `shot` for a fired round, `pickpocket`, `trade` for a vendor deal, `drop` for `player.dropInventory`, or the ground, stash and gathering reasons.
2104
+ * `add`, `remove`, `properties`, `set`, `transfer`, `wear` when the player's game wore an item down in use, `use` for food, potions and ointments, `shot` for a fired round, `pickpocket`, `trade` for a vendor deal, `repair` for a repair kit, `drop` for `player.dropInventory`, or the ground, stash and gathering reasons.
1680
2105
  */
1681
2106
  reason: string;
1682
2107
 
@@ -1696,7 +2121,7 @@ declare global {
1696
2121
  ok: boolean;
1697
2122
 
1698
2123
  /**
1699
- * Empty on success, otherwise why not: `inventoryUnavailable`, `invalidRequest`, `staleRevision`, `invalidItem`, `invalidItems`, `invalidAmount`, `unknownItem`, `insufficientItems`, `inventoryCapacity`, `sameInventory`, or a property policy code (`invalidMetadata`, `unknownItemClass`, `questItem`, `invalidQuality`, `immutableItemHealth`, `invalidItemHealth`, `contradictoryItemHealth`, `invalidCreationSentinel`, `unsupportedPoisonProperties`, `unsupportedOnEquipBuffs`).
2124
+ * Empty on success, otherwise why not: `inventoryUnavailable`, `invalidRequest`, `staleRevision`, `invalidItem`, `invalidItems`, `invalidAmount`, `unknownItem`, `insufficientItems`, `inventoryCapacity`, `sameInventory`, `invalidEquipment`, or a property policy code (`invalidMetadata`, `unknownItemClass`, `questItem`, `invalidQuality`, `immutableItemHealth`, `invalidItemHealth`, `contradictoryItemHealth`, `invalidCreationSentinel`, `unsupportedPoisonProperties`, `unsupportedOnEquipBuffs`).
1700
2125
  */
1701
2126
  code: string;
1702
2127
 
@@ -1722,14 +2147,14 @@ declare global {
1722
2147
  get(player: Player): InventoryState | null;
1723
2148
 
1724
2149
  /**
1725
- * Gives a player items of a class, 1 to 10000 at a time. `item` is the class GUID or the exact name the game's own item tables use, the same spelling `giveItem` takes. Left-out properties mean quality 1 at full condition; `metadata.quality` asks for a higher tier, up to what the class is made in, and `invalidQuality` refuses one past it. The units join the row that already holds this class with these properties, if there is one.
2150
+ * Gives a player items of a class, 1 to 10000 at a time. `item` is the class GUID or the exact name the game's own item tables use, the same spelling `giveItem` takes. Left-out properties mean quality 1 at full condition; `metadata.quality` asks for a higher tier, up to what the class is made in, and `invalidQuality` refuses one past it. The units join the row that already holds this class with these properties, if there is one. The player's game announces them with its own "You received" toast unless `notify` is false.
1726
2151
  */
1727
- add(player: Player, request: { item: string; amount: number; metadata?: Record<string, unknown>; revision?: number }): InventoryResult;
2152
+ add(player: Player, request: { item: string; amount: number; metadata?: Record<string, unknown>; revision?: number; notify?: boolean }): InventoryResult;
1728
2153
 
1729
2154
  /**
1730
- * Takes exact units from named rows, every one of them or none.
2155
+ * Takes exact units from named rows, every one of them or none. The player's game announces the loss with its own toast unless `notify` is false.
1731
2156
  */
1732
- remove(player: Player, request: { units: InventoryUnit[]; revision?: number }): InventoryResult;
2157
+ remove(player: Player, request: { units: InventoryUnit[]; revision?: number; notify?: boolean }): InventoryResult;
1733
2158
 
1734
2159
  /**
1735
2160
  * Replaces a row's properties. The row keeps its identity and amount. It replaces rather than merges: carry over anything you want to keep, and give `health` or `condition`, not two that disagree.
@@ -1737,14 +2162,14 @@ declare global {
1737
2162
  setProperties(player: Player, request: { id: string; metadata: Record<string, unknown>; revision?: number }): InventoryResult;
1738
2163
 
1739
2164
  /**
1740
- * Replaces a player's whole inventory, which is how a saved one comes back. Rows keep the ids they are given (letters, digits and `-_:.`, up to 64) and get new ones when they have none. `equipped` is how many units of a gear row the body wears, up to 48 in all; their game dresses in them. An empty list clears the inventory.
2165
+ * Replaces a player's whole inventory, which is how a saved one comes back. It is never announced in the player's game. Rows keep the ids they are given (letters, digits and `-_:.`, up to 64) and get new ones when they have none. `equipped` is how many units of a gear row the body wears, up to 48 in all; their game dresses in them. An empty list clears the inventory.
1741
2166
  */
1742
2167
  set(player: Player, request: { items: { id?: string; item: string; amount: number; metadata?: Record<string, unknown>; equipped?: number }[]; revision?: number }): InventoryResult;
1743
2168
 
1744
2169
  /**
1745
- * Moves exact units from one player to another with their properties, all or nothing. They join matching rows in the target, so the target's row ids are the ones in the result's `items`. Whether the two may trade -- distance, consent, price -- is for the script to decide.
2170
+ * Moves exact units from one player to another with their properties, all or nothing. They join matching rows in the target, so the target's row ids are the ones in the result's `items`. Whether the two may trade -- distance, consent, price -- is for the script to decide. Both players' games announce what they lost and gained unless `notify` is false.
1746
2171
  */
1747
- transfer(source: Player, target: Player, request: { units: InventoryUnit[]; sourceRevision?: number; targetRevision?: number }): InventoryResult;
2172
+ transfer(source: Player, target: Player, request: { units: InventoryUnit[]; sourceRevision?: number; targetRevision?: number; notify?: boolean }): InventoryResult;
1748
2173
 
1749
2174
  /**
1750
2175
  * What the game prices one unit of an item at, in money units, worked out the way the game does it. `pristine` is the price at the best health its quality allows, `current` at its own health. Quality changes the price only through that health. The metadata reads as `Inventory.add` reads it -- left out, quality 1 at full condition -- so `Inventory.getItemPrice(row.item, row.metadata)` prices a row. This is the item's own worth: what the game's shopkeepers would ask depends on their terms and the haggling, and a `Vendor` charges whatever its script says.
@@ -1772,6 +2197,11 @@ declare global {
1772
2197
  */
1773
2198
  constructor(id: number);
1774
2199
 
2200
+ /**
2201
+ * The current route's status: idle, running, reached, blocked, or failed.
2202
+ */
2203
+ readonly navigationStatus: string;
2204
+
1775
2205
  /**
1776
2206
  * What this horse wears, by slot: `saddle` (the saddlebags are part of it, and so is the carrying capacity they add), `head` (a bridle or chanfron), `torso` (a caparison), `shoe`. Item class names, null for an empty slot. A spawned horse wears the game's own tack for it unless `Horse.spawn` said otherwise. The gear changes the horse's stats as well as its look.
1777
2207
  */
@@ -1863,6 +2293,25 @@ declare global {
1863
2293
  */
1864
2294
  destroy(): void;
1865
2295
 
2296
+ /**
2297
+ * Routes an unridden horse over the server navigation mesh. Mounting cancels the order. Returns false without a mesh, for a dead or mounted horse, or invalid input.
2298
+ * @param position Destination in world coordinates.
2299
+ * @param options Defaults to walking and a 1.5 metre arrival radius.
2300
+ */
2301
+ moveTo(position: Vector3, options?: { speed?: 'walk' | 'jog' | 'run'; radius?: number }): boolean;
2302
+
2303
+ /**
2304
+ * Patrols using the NPC route state machine. Requires a loaded mesh and an alive, unridden horse. Mounting cancels the patrol.
2305
+ * @param points One to 256 waypoints.
2306
+ * @param options Defaults to walking, looping, and no wait.
2307
+ */
2308
+ patrol(points: Vector3[], options?: { speed?: 'walk' | 'jog' | 'run'; loop?: boolean; waitSeconds?: number }): boolean;
2309
+
2310
+ /**
2311
+ * Cancels navigation and holds an unridden horse where it stands. Does not take control from a rider.
2312
+ */
2313
+ hold(): void;
2314
+
1866
2315
  /**
1867
2316
  * Makes this horse another player's. Every client makes it that player's horse in the game's own terms -- theirs is never a stolen horse -- and `horseOwnerChanged` follows. Ownership decides nothing about who may ride it: that is `horseMounting`'s to refuse. Throws when `player` is not a connected player.
1868
2317
  * @param player The horse's new owner, or null to leave it ownerless.
@@ -3009,12 +3458,12 @@ declare global {
3009
3458
  * @param model Mesh to build, as either a full catalog path (`objects/manmade/barrels/barrel_a.cgf`) or its file stem (`barrel_a`). A stem several meshes share resolves to the first of them, so pass the path when it matters which. A mesh this server streams -- a `.cgf` in a resource's `stream/objects/kcdc/<resource>/` folder -- is named by its full path, `objects/kcdc/<resource>/chair.cgf`; a player whose game does not have it yet sees the prop as soon as it does.
3010
3459
  * @param position Optional world-space spawn position; omitted components default to zero.
3011
3460
  * @param rotation Optional initial orientation: a Quaternion, or a Vector3 of Euler angles in degrees.
3012
- * @param scale Optional uniform scale from 0.01 to 100; omitted spawns the mesh at its own size.
3461
+ * @param scale Uniform size or separate X/Y/Z sizes, each from 0.01 to 100. Omitted uses the mesh size. Nonuniform collision follows the native engine limitations.
3013
3462
  * @param physics Optional collision: `static` (the default), `rigid` or `none`.
3014
3463
  * @param virtualWorld Optional virtual world the prop belongs to; omitted puts it in the global one.
3015
3464
  * @returns The newly spawned prop handle.
3016
3465
  */
3017
- static spawn(model: string, position?: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, scale?: number, physics?: string, virtualWorld?: number): Prop;
3466
+ static spawn(model: string, position?: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, scale?: number | Vector3, physics?: string, virtualWorld?: number): Prop;
3018
3467
 
3019
3468
  /**
3020
3469
  * Lists every prop the server currently has.
@@ -3536,7 +3985,7 @@ declare global {
3536
3985
  */
3537
3986
  class LevelEdit {
3538
3987
  /**
3539
- * Wraps an edit the server already holds; use LevelEdit.apply or LevelEdit.applyMap to make one.
3988
+ * Wraps an edit the server already holds; use LevelEdit.apply to make one, or WorldResource for a whole export.
3540
3989
  * @param id Network entity identifier.
3541
3990
  */
3542
3991
  constructor(id: number);
@@ -3620,14 +4069,6 @@ declare global {
3620
4069
  */
3621
4070
  static apply(definition: LevelEditDefinition, virtualWorld?: number): LevelEdit;
3622
4071
 
3623
- /**
3624
- * Applies every entry of a map's `world` array, which is how edits made in the World Builder reach every player instead of being loaded by hand on each.
3625
- * @param map A World Builder map saved from the editor, as its JSON text or the parsed object. Only its `world` array is read: its placed objects are `Prop.spawn`'s, its areas `Area.create`'s.
3626
- * @param virtualWorld Optional virtual world whose players see the edits; the global one when omitted.
3627
- * @returns One edit per entry, in the map's order. Throws, naming the entry, for one no client could find the object by.
3628
- */
3629
- static applyMap(map: string | Record<string, unknown>, virtualWorld?: number): LevelEdit[];
3630
-
3631
4072
  /**
3632
4073
  * Lists every edit the server currently has.
3633
4074
  * @param virtualWorld Optional virtual world to list; omitted lists every one of them.
@@ -3666,7 +4107,7 @@ declare global {
3666
4107
  readonly soul: string;
3667
4108
 
3668
4109
  /**
3669
- * Entity class the body is spawned as -- `NPC` or `NPC_Female`.
4110
+ * Native entity class, including `NPC`, `NPC_Female`, or the matching animal class from `Npc.animals()`.
3670
4111
  */
3671
4112
  readonly actorClass: string;
3672
4113
 
@@ -3686,7 +4127,7 @@ declare global {
3686
4127
  faction: number;
3687
4128
 
3688
4129
  /**
3689
- * The server's ledger of this body's health, clamped to `maxHealth`. Damage from players arrives here after the server has agreed to it.
4130
+ * The server's ledger of this body's health, clamped to `maxHealth`. Combat damage arrives here after the server has agreed to it.
3690
4131
  */
3691
4132
  health: number;
3692
4133
 
@@ -3731,10 +4172,15 @@ declare global {
3731
4172
  locomotion: string;
3732
4173
 
3733
4174
  /**
3734
- * What the NPC has been told to do: `hold`, `moveTo`, `follow`, `flee`, `lookAt`, `playAnim` or `talk`.
4175
+ * What the NPC has been told to do: `hold`, `moveTo`, `follow`, `flee`, `lookAt`, `playAnim`, `talk` or `attack`.
3735
4176
  */
3736
4177
  readonly intent: string;
3737
4178
 
4179
+ /**
4180
+ * Current patrol snapshot and progress, or null when not patrolling. Updating a route does not change a running patrol.
4181
+ */
4182
+ readonly patrolState: PatrolState | null;
4183
+
3738
4184
  /**
3739
4185
  * What has become of the current order: `idle`, `running`, `reached`, `blocked` or `failed`. A move reads `running` from the moment it is given -- while its route is planned and while it walks the route's corners -- until it ends, and then the outcome `npcIntentDone` announced, which stays until the next order. A follow reads `reached` while it is within its radius. Dormant moves in `auto` or `server` mode are carried out and decided by the server; dormant `game` moves wait for a client simulator.
3740
4186
  */
@@ -3837,11 +4283,19 @@ declare global {
3837
4283
  * Walks the waypoints in order. The server stores the route and replicates the current target. `npcIntentDone` fires once per leg, after its final mesh corner or a movement failure.
3838
4284
  *
3839
4285
  * A leg that ends `blocked` or `failed` is skipped after at least 2 seconds. When every leg of a lap has failed in a row, the patrol is abandoned and that last leg reports `failed` instead.
3840
- * @param points The waypoints, in order.
3841
- * @param options `loop` defaults to true; `waitSeconds` is the wait at each waypoint, 0 to 3600 (default 0); `speed` defaults to `walk`. `pathfinding` uses the modes documented for `moveTo` and applies to every leg.
4286
+ * @param points Waypoints, a named route handle, or its stable id. Named routes are copied at start.
4287
+ * @param options Point arrays retain their defaults: loop, walk, zero wait. Named routes use their authored defaults. Call options override route defaults; waypoint overrides take priority. Use mode for once, loop or pingPong; do not combine mode and loop. radius is the arrival distance. pathfinding uses the moveTo modes for every leg.
3842
4288
  * @returns True when the route was accepted; false for an empty route, more than 256 waypoints, a waypoint that is not finite or lies outside the world, or a `waitSeconds` that is not a number. Throws if server mode has no loaded mesh, leaving the previous order intact.
3843
4289
  */
3844
- patrol(points: (Vector3 | Partial<Vector3>)[], options?: { speed?: 'walk' | 'jog' | 'run'; loop?: boolean; waitSeconds?: number; pathfinding?: 'auto' | 'game' | 'server' }): boolean;
4290
+ patrol(points: (Vector3 | Partial<Vector3>)[] | PatrolRoute | string, options?: { speed?: 'walk' | 'jog' | 'run'; loop?: boolean; mode?: 'once' | 'loop' | 'pingPong'; radius?: number; waitSeconds?: number; pathfinding?: 'auto' | 'game' | 'server' }): boolean;
4291
+
4292
+ /**
4293
+ * Orders native combat against a live player or NPC in the same visible world within 128 metres. Another order stops it. The order fails when its target dies, disappears or leaves that range. It waits while dormant; no offline damage is simulated. Bow attacks stop within 18 metres and use native projectiles. Equipped NPC arrows are replenished while shooting.
4294
+ * @param target The combatant to pursue and attack.
4295
+ * @param options Defaults to melee. Bow requires an equipped bow and compatible arrows.
4296
+ * @returns True when accepted. Invalid targets leave the previous order unchanged.
4297
+ */
4298
+ attack(target: Player | Npc | number, options?: { weapon?: "melee" | "bow" }): boolean;
3845
4299
 
3846
4300
  /**
3847
4301
  * Keeps the NPC near somebody as they move, steering straight at them. `npcIntentDone` reports `reached` the first time it catches up, and the follow carries on. If the body reports `blocked`, a loaded mesh lets the server route to the target's current position before reporting it. After recovery it resumes following the moving target.
@@ -3967,7 +4421,7 @@ declare global {
3967
4421
  * Spawns an NPC and replicates it. It exists on the server from this moment: every client near enough makes a body for it, one of them is elected to run it, and the rest draw what that one reports.
3968
4422
  *
3969
4423
  * The body is not simulated until somebody is close enough to run it, which is not a failure -- a guard on the other side of the map has nothing to do that anybody can see. Read `simulator` to tell.
3970
- * @param options `soul` is a role name from `Npc.roles()` or a soul GUID; `position` is where to put it. Everything else has a default.
4424
+ * @param options `soul` is a role from `Npc.roles()`, an animal name from `Npc.animals()`, or a soul GUID; `position` is where to put it. Everything else has a default.
3971
4425
  * @returns The new NPC's handle.
3972
4426
  */
3973
4427
  static create(options: { soul?: string; class?: string; name?: string; outfit?: string; wearing?: string[]; appearance?: Partial<Appearance>; position?: Vector3 | Partial<Vector3>; rotation?: Quaternion | Vector3 | Partial<Vector3>; faction?: number; health?: number; maxHealth?: number; locomotion?: 'kinematic' | 'native'; invulnerable?: boolean; frozen?: boolean; interactable?: boolean; nametag?: boolean; lootable?: boolean; virtualWorld?: number }): Npc;
@@ -4002,14 +4456,175 @@ declare global {
4002
4456
  static removeAll(virtualWorld?: number): number;
4003
4457
 
4004
4458
  /**
4005
- * The named kinds of NPC this build ships -- `guard`, `bandit`, `townswoman` and the rest. Each is a real soul out of the game's own tables, so a role spawns a body that already looks the part. Anything not in this list is taken as a soul GUID.
4459
+ * The named kinds of NPC this build ships -- `guard`, `bandit`, `townswoman` and the rest. Each is a real soul out of the game's own tables, so a role spawns a body that already looks the part. Animal names are listed separately by `Npc.animals()`. Other values are taken as soul GUIDs.
4006
4460
  * @returns The role names.
4007
4461
  */
4008
4462
  static roles(): string[];
4463
+
4464
+ /**
4465
+ * Animal souls with matching native classes. Pass a name or soul to Npc.create. Chickens use flock entities and are excluded.
4466
+ */
4467
+ static animals(): { name: string; soul: string; actorClass: string }[];
4468
+
4469
+ /**
4470
+ * Level-authored animal spawners. Positions are markers and must be projected onto navigation. GUIDs are hex strings. Counts and respawn days describe the original game; scripts decide their population and respawn policy.
4471
+ * @param level Defaults to the running server's level. Pass * for all levels.
4472
+ */
4473
+ static animalSpawnpoints(level?: string): { level: string; guid: string; name: string; layer: string; soul: string; actorClass: string; position: Vector3; count: number; respawnDays: number; spawnInFlock: boolean; spawnAreaGuid: string }[];
4009
4474
  }
4010
4475
 
4011
4476
  interface Npc extends Entity {}
4012
4477
 
4478
+ /**
4479
+ * One authored stop, independent of actor type.
4480
+ */
4481
+ interface PatrolPoint {
4482
+ /**
4483
+ * World-space waypoint.
4484
+ */
4485
+ position: Vector3;
4486
+
4487
+ /**
4488
+ * Overrides the route and call speed for this leg.
4489
+ */
4490
+ speed?: 'walk' | 'jog' | 'run' | undefined;
4491
+
4492
+ /**
4493
+ * Wait after arrival, 0 to 3600 seconds.
4494
+ */
4495
+ waitSeconds?: number | undefined;
4496
+
4497
+ /**
4498
+ * Arrival radius in metres.
4499
+ */
4500
+ radius?: number | undefined;
4501
+ }
4502
+
4503
+ /**
4504
+ * The format saved by World Builder and accepted by PatrolRoute.create.
4505
+ */
4506
+ interface PatrolRouteDefinition {
4507
+ /**
4508
+ * Stable globally unique id, up to 128 bytes. Use a namespace such as town.guard-loop.
4509
+ */
4510
+ id: string;
4511
+
4512
+ /**
4513
+ * Display name, up to 256 bytes.
4514
+ */
4515
+ name?: string | undefined;
4516
+
4517
+ /**
4518
+ * 1 to 256 ordered waypoints.
4519
+ */
4520
+ points: PatrolPoint[];
4521
+
4522
+ /**
4523
+ * Defaults to loop. Ping-pong visits each endpoint once per turn.
4524
+ */
4525
+ mode?: 'once' | 'loop' | 'pingPong' | undefined;
4526
+
4527
+ /**
4528
+ * Default leg speed; walk when omitted.
4529
+ */
4530
+ speed?: 'walk' | 'jog' | 'run' | undefined;
4531
+
4532
+ /**
4533
+ * Default arrival wait, 0 to 3600; defaults to zero.
4534
+ */
4535
+ waitSeconds?: number | undefined;
4536
+
4537
+ /**
4538
+ * Default arrival radius; 1.5 metres when omitted.
4539
+ */
4540
+ radius?: number | undefined;
4541
+ }
4542
+
4543
+ /**
4544
+ * A running patrol's snapshot. Indices and laps start at zero.
4545
+ */
4546
+ interface PatrolState {
4547
+ /**
4548
+ * Stable route id; null for an anonymous point-array patrol.
4549
+ */
4550
+ routeId: string | null;
4551
+
4552
+ /**
4553
+ * Target waypoint index.
4554
+ */
4555
+ waypointIndex: number;
4556
+
4557
+ /**
4558
+ * Completed loops or round trips.
4559
+ */
4560
+ lap: number;
4561
+
4562
+ /**
4563
+ * 1 forward, -1 backward.
4564
+ */
4565
+ direction: number;
4566
+
4567
+ /**
4568
+ * Whether the actor is approaching or waiting at the waypoint.
4569
+ */
4570
+ phase: 'moving' | 'waiting';
4571
+ }
4572
+
4573
+ /**
4574
+ * Named patrol definition. Actors snapshot it when ordered; update or destroy affects future starts.
4575
+ */
4576
+ class PatrolRoute {
4577
+ private constructor();
4578
+
4579
+ /**
4580
+ * False after destruction.
4581
+ */
4582
+ readonly exists: boolean;
4583
+
4584
+ /**
4585
+ * Stable id; empty after destruction.
4586
+ */
4587
+ readonly id: string;
4588
+
4589
+ /**
4590
+ * Display name.
4591
+ */
4592
+ readonly name: string;
4593
+
4594
+ /**
4595
+ * Returns an independent definition, or null after destruction.
4596
+ */
4597
+ toJSON(): PatrolRouteDefinition | null;
4598
+
4599
+ /**
4600
+ * Removes the definition. Active patrols keep their snapshots.
4601
+ */
4602
+ destroy(): boolean;
4603
+
4604
+ /**
4605
+ * Updates defaults or waypoints atomically. Invalid input throws; a destroyed handle returns false.
4606
+ * @param changes Fields to replace; id cannot change.
4607
+ */
4608
+ update(changes: Partial<PatrolRouteDefinition>): boolean;
4609
+
4610
+ /**
4611
+ * Registers a route. Invalid data or a duplicate id throws.
4612
+ * @param definition The route to register.
4613
+ */
4614
+ static create(definition: PatrolRouteDefinition): PatrolRoute;
4615
+
4616
+ /**
4617
+ * Looks up a registered route.
4618
+ * @param id Exact route id.
4619
+ */
4620
+ static getById(id: string): PatrolRoute | null;
4621
+
4622
+ /**
4623
+ * Lists registered routes in creation order.
4624
+ */
4625
+ static all(): PatrolRoute[];
4626
+ }
4627
+
4013
4628
  /**
4014
4629
  * Replicated journal quest handle.
4015
4630
  */
@@ -4311,65 +4926,147 @@ declare global {
4311
4926
  */
4312
4927
  interface GatheringProposal {
4313
4928
  /**
4314
- * Item class GUID of the herb.
4929
+ * Item class GUID of the herb.
4930
+ */
4931
+ item: string;
4932
+
4933
+ /**
4934
+ * How many, as the game computes it from the player's survival level and the plants harvested together.
4935
+ */
4936
+ amount: number;
4937
+
4938
+ /**
4939
+ * The game's pickable area id for the plant.
4940
+ */
4941
+ kind: number;
4942
+
4943
+ /**
4944
+ * Where the plant grows, as the player's game reported it.
4945
+ */
4946
+ position: number[];
4947
+
4948
+ /**
4949
+ * The player's virtual world.
4950
+ */
4951
+ virtualWorld: number;
4952
+ }
4953
+
4954
+ /**
4955
+ * A plant a player picked, and what they were given.
4956
+ */
4957
+ interface GatheringHarvestedEvent {
4958
+ /**
4959
+ * Item class GUID of the herb.
4960
+ */
4961
+ item: string;
4962
+
4963
+ /**
4964
+ * How many.
4965
+ */
4966
+ amount: number;
4967
+
4968
+ /**
4969
+ * The game's pickable area id for the plant.
4970
+ */
4971
+ kind: number;
4972
+
4973
+ /**
4974
+ * Where the plant grows.
4975
+ */
4976
+ position: number[];
4977
+
4978
+ /**
4979
+ * The player's virtual world.
4980
+ */
4981
+ virtualWorld: number;
4982
+
4983
+ /**
4984
+ * The inventory rows that received the herb.
4985
+ */
4986
+ items: InventoryUnit[];
4987
+ }
4988
+
4989
+ /**
4990
+ * A frozen snapshot of one stew pot in one virtual world.
4991
+ */
4992
+ interface CookPotSnapshot {
4993
+ /**
4994
+ * The fireplace's level GUID.
4995
+ */
4996
+ guid: string;
4997
+
4998
+ /**
4999
+ * Position of the eating trigger.
5000
+ */
5001
+ position: { readonly x: number; readonly y: number; readonly z: number };
5002
+
5003
+ /**
5004
+ * Unreserved meals remaining.
4315
5005
  */
4316
- item: string;
5006
+ portions: number;
4317
5007
 
4318
5008
  /**
4319
- * How many, as the game computes it from the player's survival level and the plants harvested together.
5009
+ * Portions in the most recent refill; sets the halfway point.
4320
5010
  */
4321
- amount: number;
5011
+ capacity: number;
4322
5012
 
4323
5013
  /**
4324
- * The game's pickable area id for the plant.
5014
+ * Whether eating is allowed. Disabling preserves the contents.
4325
5015
  */
4326
- kind: number;
5016
+ enabled: boolean;
4327
5017
 
4328
5018
  /**
4329
- * Where the plant grows, as the player's game reported it.
5019
+ * Visible food level, derived from remaining portions.
4330
5020
  */
4331
- position: number[];
5021
+ state: "empty" | "half" | "full";
4332
5022
 
4333
5023
  /**
4334
- * The player's virtual world.
5024
+ * Virtual world that owns this stock.
4335
5025
  */
4336
5026
  virtualWorld: number;
4337
5027
  }
4338
5028
 
4339
5029
  /**
4340
- * A plant a player picked, and what they were given.
5030
+ * Server-owned stew pots. Stocked pots begin with four shared meals, with no automatic refill. State lasts until the server stops.
4341
5031
  */
4342
- interface GatheringHarvestedEvent {
4343
- /**
4344
- * Item class GUID of the herb.
4345
- */
4346
- item: string;
4347
-
5032
+ const CookPot: {
4348
5033
  /**
4349
- * How many.
5034
+ * Lists every catalogued pot on the server's level in one virtual world; empty for a world no player or write has used yet.
5035
+ * @param virtualWorld Virtual world id; defaults to 0. The global visibility sentinel is not a stock world.
4350
5036
  */
4351
- amount: number;
5037
+ all(virtualWorld?: number): CookPotSnapshot[];
4352
5038
 
4353
5039
  /**
4354
- * The game's pickable area id for the plant.
5040
+ * Returns a snapshot, or null for an unknown pot.
5041
+ * @param guid Fireplace level GUID from CookPot.all().
5042
+ * @param virtualWorld Virtual world id; defaults to 0. The global visibility sentinel is not a stock world.
4355
5043
  */
4356
- kind: number;
5044
+ get(guid: string, virtualWorld?: number): CookPotSnapshot | null;
4357
5045
 
4358
5046
  /**
4359
- * Where the plant grows.
5047
+ * Replaces remaining stock and capacity, preserving enabled. Returns false for an unknown pot.
5048
+ * @param guid Fireplace level GUID from CookPot.all().
5049
+ * @param portions Integer from 0 to 1000; defaults to four.
5050
+ * @param virtualWorld Virtual world id; defaults to 0. The global visibility sentinel is not a stock world.
4360
5051
  */
4361
- position: number[];
5052
+ refill(guid: string, portions?: number, virtualWorld?: number): boolean;
4362
5053
 
4363
5054
  /**
4364
- * The player's virtual world.
5055
+ * Allows or blocks eating. Returns false for an unknown pot.
5056
+ * @param guid Fireplace level GUID from CookPot.all().
5057
+ * @param enabled False blocks eating without changing stock or its appearance.
5058
+ * @param virtualWorld Virtual world id; defaults to 0. The global visibility sentinel is not a stock world.
4365
5059
  */
4366
- virtualWorld: number;
5060
+ setEnabled(guid: string, enabled: boolean, virtualWorld?: number): boolean;
4367
5061
 
4368
5062
  /**
4369
- * The inventory rows that received the herb.
5063
+ * Changes food level and stock together, preserving enabled. Returns false for an unknown pot.
5064
+ * @param guid Fireplace level GUID from CookPot.all().
5065
+ * @param state Empty, two portions, or four portions; resets capacity to four.
5066
+ * @param virtualWorld Virtual world id; defaults to 0. The global visibility sentinel is not a stock world.
4370
5067
  */
4371
- items: InventoryUnit[];
4372
- }
5068
+ setState(guid: string, state: "empty" | "half" | "full", virtualWorld?: number): boolean;
5069
+ };
4373
5070
 
4374
5071
  /** */
4375
5072
  interface NearestDoor {
@@ -4557,7 +5254,7 @@ declare global {
4557
5254
  }
4558
5255
 
4559
5256
  /**
4560
- * Replicated handle for one of the level's animated gates.
5257
+ * Replicated handle for one of the level's castle gates.
4561
5258
  */
4562
5259
  class Gate {
4563
5260
  /**
@@ -4567,12 +5264,12 @@ declare global {
4567
5264
  constructor(id: number);
4568
5265
 
4569
5266
  /**
4570
- * The level's own EntityGuid, as sixteen lowercase hex digits. The same on every machine, so it is the identity to store a gate under; `Gate.find` takes it back.
5267
+ * The level's own EntityGuid, as sixteen lowercase hex digits. The same on every machine, so it is the identity to store a gate under; `Gate.find` takes it back. A `gate` has no entity of its own, so its key is the GUID of the layer that draws it shut.
4571
5268
  */
4572
5269
  readonly guid: string;
4573
5270
 
4574
5271
  /**
4575
- * What piece of architecture this is: `drawbridge` or `portcullis`. The shipped game has two in total.
5272
+ * What piece of architecture this is: `drawbridge` or `portcullis`, which animate, or `gate`, a pair of leaves the level swaps between drawn open and drawn shut -- the Ratborsch and Nebakov fortress gates and the Ruthard palace gate. A `gate` opens and closes at once.
4576
5273
  */
4577
5274
  readonly kind: string;
4578
5275
 
@@ -4592,7 +5289,7 @@ declare global {
4592
5289
  readonly moving: boolean;
4593
5290
 
4594
5291
  /**
4595
- * How long opening takes, in seconds, from the key range the asset's animation database stores. A gate with no opening clip runs its closing one backwards, so this is that clip's length.
5292
+ * How long opening takes, in seconds, from the key range the asset's animation database stores. A gate with no opening clip runs its closing one backwards, so this is that clip's length. 0 for a `gate`.
4596
5293
  */
4597
5294
  readonly openDuration: number;
4598
5295
 
@@ -4706,12 +5403,12 @@ declare global {
4706
5403
  damageRadius: number;
4707
5404
 
4708
5405
  /**
4709
- * Whether players within 12 m of the engine get the game's own action hint for it on the use key: Load while it is idle, Fire while it is loaded. A press raises `siegeEngineUse`, and unless a handler refuses it the engine loads, or fires along the player's facing at `range`. Off by default.
5406
+ * Whether players may work the engine. A player within 2 m of an empty one gets the game's own action hint on the use key to take its place, and becomes its `operator`; near a trebuchet with a `crewRequired`, a free winch is offered too. Each ask raises `siegeEngineUse` first, which may refuse it. Off by default.
4710
5407
  */
4711
5408
  usable: boolean;
4712
5409
 
4713
5410
  /**
4714
- * How far a shot fired from the native prompt goes along the player's facing, in metres; kept between `minRange` and `maxRange`. 150 for a trebuchet and 120 for a cannon to start with.
5411
+ * How far a shot goes along the operator's facing when they fire before laying the engine anywhere, in metres; kept between `minRange` and `maxRange`. 150 for a trebuchet and 120 for a cannon to start with.
4715
5412
  */
4716
5413
  range: number;
4717
5414
 
@@ -4730,6 +5427,46 @@ declare global {
4730
5427
  */
4731
5428
  readonly loadDuration: number;
4732
5429
 
5430
+ /**
5431
+ * What the engine can take before it is wrecked; 0, the default, means nothing harms it. Setting it heals the engine to the new maximum and repairs a wreck. A blast within `damageRadius` of an engine -- any engine's, its own included -- takes its share of that shot's `damage` off it, raising `siegeEngineDamage`.
5432
+ */
5433
+ maxHealth: number;
5434
+
5435
+ /**
5436
+ * What is left of `maxHealth`. Setting it to 0 wrecks the engine and raising it from 0 repairs one; ignored while `maxHealth` is 0.
5437
+ */
5438
+ health: number;
5439
+
5440
+ /**
5441
+ * Whether the engine's health ran out. A wrecked cannon shows the game's broken gun and a wrecked trebuchet leans and settles; nothing loads, aims or fires it, and its operator and crew are let go, until `repair` or a new `maxHealth`.
5442
+ */
5443
+ readonly wrecked: boolean;
5444
+
5445
+ /**
5446
+ * Shots left to load; each `load` takes one, and an engine with none refuses to load. -1, the default, never runs out; any negative value means the same.
5447
+ */
5448
+ ammo: number;
5449
+
5450
+ /**
5451
+ * How many of the engine's winches must be manned for its arm to be winched down; 0, the default, winds it by itself. With fewer hands than this the winding holds where it is, and goes on when they come back. Players near a usable engine that needs them are offered its winches, and each one there plays the game's own pull. Kept to `crewPlaces`.
5452
+ */
5453
+ crewRequired: number;
5454
+
5455
+ /**
5456
+ * How many winches the engine has: 2 on a trebuchet, 0 on a cannon.
5457
+ */
5458
+ readonly crewPlaces: number;
5459
+
5460
+ /**
5461
+ * The player in the engine's place, or null. They lay it where they look while they hold the block key, load it with the torch key, fire it with the attack key and step away with the use key; walking off lets go of it too. `setOperator` puts somebody there.
5462
+ */
5463
+ readonly operator: Player | null;
5464
+
5465
+ /**
5466
+ * Who mans each winch, in place order, with null for an empty one.
5467
+ */
5468
+ readonly crew: (Player | null)[];
5469
+
4733
5470
  /**
4734
5471
  * Formats this engine handle for logging and debugging.
4735
5472
  * @returns The engine ID, its kind and where it is in its cycle.
@@ -4743,7 +5480,7 @@ declare global {
4743
5480
  load(): SiegeResult;
4744
5481
 
4745
5482
  /**
4746
- * Turns a loaded engine to face the target and shoots at it. A trebuchet's arm lets the stone go at one angle, so its speed is solved for the distance; a cannon fires at one speed, so its elevation is. The stone is let go partway through the shot (`seconds`), then every client nearby draws it along the same arc. It comes down where the world stops it, which the player nearest the target is asked to report, or on the target when nobody can.
5483
+ * Turns a loaded engine to face the target and shoots at it. A trebuchet's arm lets the stone go at one angle, so its speed is solved for the distance; a cannon fires at one speed, so its elevation is. The stone is let go partway through the shot (`seconds`), then every client nearby draws it along the same arc. It comes down where the world stops it, which the attacker is asked to report when near enough, else the player nearest the target, or on the target when nobody can.
4747
5484
  * @param target Where the projectile should come down.
4748
5485
  * @param attacker The player credited with whatever it hits, in `playerDamage`, `npcDamage` and `siegeImpact`.
4749
5486
  * @returns What happened, and the phrase to explain it with when nothing did.
@@ -4764,6 +5501,30 @@ declare global {
4764
5501
  */
4765
5502
  canHit(target: Vector3 | Partial<Vector3>): string;
4766
5503
 
5504
+ /**
5505
+ * Shows or hides the operator's aim guide: a translucent red beam along the shot's path -- out of a trebuchet's sling and along its arc, or straight from a cannon's muzzle -- to where it would come down, with a ball there. Off by default, which leaves laying the engine to the eye; the Fire hint says how far the shot goes either way.
5506
+ * @param enabled Whether the operator sees the beam.
5507
+ */
5508
+ setAimGuide(enabled: boolean): void;
5509
+
5510
+ /**
5511
+ * Whether the operator sees the aim guide; see `setAimGuide`.
5512
+ * @returns True when the beam is shown.
5513
+ */
5514
+ getAimGuide(): boolean;
5515
+
5516
+ /**
5517
+ * Makes the engine whole again: `health` back to `maxHealth`, and a wreck idle and unloaded.
5518
+ */
5519
+ repair(): void;
5520
+
5521
+ /**
5522
+ * Puts a player in the engine's place without asking them, or takes whoever is there out of it. A player holds one place at a time, so they leave any other engine or winch first. Raises no `siegeEngineUse`.
5523
+ * @param player Who takes the engine's place, or null to empty it.
5524
+ * @returns False for a player who is no longer connected.
5525
+ */
5526
+ setOperator(player: Player | null): boolean;
5527
+
4767
5528
  /**
4768
5529
  * Removes the engine on every client after emitting `siegeEngineDestroy`. A projectile already in the air still lands.
4769
5530
  */
@@ -5091,6 +5852,76 @@ declare global {
5091
5852
  static all(kind?: 'level' | 'script'): Area[];
5092
5853
  }
5093
5854
 
5855
+ /**
5856
+ * A named world export loaded from mod.world_resources. Server-owned, with live access to its surviving props, effects, level edits, areas and patrol routes. Obtain handles through all or find; runtime loading, reloading and unloading are not exposed.
5857
+ */
5858
+ class WorldResource {
5859
+ private constructor();
5860
+
5861
+ /**
5862
+ * Unique case-sensitive resource name: the filename without .world.json, or the explicit config name. Empty after shutdown.
5863
+ */
5864
+ readonly name: string;
5865
+
5866
+ /**
5867
+ * Resolved absolute source file path, in UTF-8. Empty after shutdown.
5868
+ */
5869
+ readonly path: string;
5870
+
5871
+ /**
5872
+ * The exported game level, checked against the server level at startup. Empty after shutdown.
5873
+ */
5874
+ readonly level: string;
5875
+
5876
+ /**
5877
+ * Whether this export is registered. Remains true even if scripts destroy all of its contents.
5878
+ */
5879
+ readonly loaded: boolean;
5880
+
5881
+ /**
5882
+ * A fresh array of surviving props in export order. Changing the array does not change membership; the handles support normal Prop operations.
5883
+ */
5884
+ readonly props: Prop[];
5885
+
5886
+ /**
5887
+ * A fresh array of surviving effects in export order, excluding destroyed effects.
5888
+ */
5889
+ readonly effects: Vfx[];
5890
+
5891
+ /**
5892
+ * A fresh array of surviving level edits in export order, excluding restored edits.
5893
+ */
5894
+ readonly levelEdits: LevelEdit[];
5895
+
5896
+ /**
5897
+ * A fresh array of surviving exported areas in export order, excluding destroyed areas.
5898
+ */
5899
+ readonly areas: Area[];
5900
+
5901
+ /**
5902
+ * Surviving exported patrol definitions, in export order.
5903
+ */
5904
+ readonly patrolRoutes: PatrolRoute[];
5905
+
5906
+ /**
5907
+ * True after every configured export has loaded successfully, even when the config list is empty. Check this before subscribing to worldResourcesReady when a script may start later.
5908
+ */
5909
+ static readonly ready: boolean;
5910
+
5911
+ /**
5912
+ * Lists config-loaded world exports in configuration order. Empty before successful startup and after shutdown.
5913
+ * @returns A fresh array of resource handles.
5914
+ */
5915
+ static all(): WorldResource[];
5916
+
5917
+ /**
5918
+ * Finds a config-loaded export by name. Throws for a non-string argument.
5919
+ * @param name Exact, case-sensitive resource name.
5920
+ * @returns The resource, or null when absent or startup has not completed.
5921
+ */
5922
+ static find(name: string): WorldResource | null;
5923
+ }
5924
+
5094
5925
  /**
5095
5926
  * Container handle for a spawned chest, a level chest, or virtual stock without a world entity.
5096
5927
  */
@@ -5624,7 +6455,7 @@ declare global {
5624
6455
  /**
5625
6456
  * Queries the level's navigation mesh on the server. The mesh includes walkable floors, bridges and stairs.
5626
6457
  *
5627
- * Copy the game's `Data/Levels/<level>/recast.pak` to the server's `files/<level>/` directory. The server searches `files/` recursively at startup. An optional `mod.navmesh` in `server.json` takes priority and can name a game install, level folder or pak file. The game data must be supplied separately. Without a mesh, `ready` is false and geometry queries return null or false. Points are world-space metres, Z up. Every query takes an optional options object. `searchRadius` and `searchHeight` limit how far a point may be from the mesh, across the ground and up or down: 2 metres by default, up to 64, and 4 by default, up to 128. Keep `searchHeight` under a storey's height, or a point on one floor snaps to the floor above. `doors` picks which doors a query walks through: `unlocked`, the default, is how an NPC treats a door -- open or shut, it goes through unless the door is locked; `open` only through doors that stand open; `any` ignores locks; `none` treats every doorway as a wall. A door's state is read off the door in the global world. A field given with the wrong type or out of range throws.
6458
+ * Copy the game's `Data/Levels/<level>/recast.pak` to the server's `files/<level>/` directory. The server searches `files/` recursively at startup. An optional `mod.navmesh` in `server.json` takes priority and can name a game install, level folder or pak file. The game data must be supplied separately. Without a mesh, `ready` is false and geometry queries return null or false. Points are world-space metres, Z up. Every query takes an optional options object. `searchRadius` and `searchHeight` limit how far a point may be from the mesh, across the ground and up or down: 2 metres by default, up to 64, and 4 by default, up to 128. Keep `searchHeight` under a storey's height, or a point on one floor snaps to the floor above. `doors` picks which doors a query walks through: `unlocked`, the default, is how an NPC treats a door -- open or shut, it goes through unless the door is locked; `open` only through doors that stand open; `any` ignores locks; `none` treats every doorway as a wall. Door states are read in the global world, except validatePatrol with an actor, which uses that actor's world. A field given with the wrong type or out of range throws.
5628
6459
  */
5629
6460
  const Navigation: {
5630
6461
  /**
@@ -5642,6 +6473,13 @@ declare global {
5642
6473
  */
5643
6474
  readonly activeOverlays: string[];
5644
6475
 
6476
+ /**
6477
+ * Checks all legs, including the closing leg of a loop and reverse legs of ping-pong. Uses the patrol runner's search budget. A single waypoint is checked against itself. Missing mesh reports available false; partial paths are incomplete. This does not start or change an actor's order.
6478
+ * @param route A registered route or its id.
6479
+ * @param options Optional actor chooses door policy in its virtual world: unlocked doors for humanoids, no doorways for horses and animals.
6480
+ */
6481
+ validatePatrol(route: PatrolRoute | string, options?: { actor?: Npc | Horse }): { available: boolean; complete: boolean; legs: { fromIndex: number; toIndex: number; complete: boolean; path: NavigationPath | null }[] };
6482
+
5645
6483
  /**
5646
6484
  * Snaps a point to the nearest walkable surface.
5647
6485
  * @param point The point to snap; omitted components default to zero.
@@ -7027,6 +7865,16 @@ declare global {
7027
7865
  * True in the authoritative server scripting runtime.
7028
7866
  */
7029
7867
  readonly isServer: boolean;
7868
+
7869
+ /**
7870
+ * Local Framework release version.
7871
+ */
7872
+ readonly frameworkVersion: string;
7873
+
7874
+ /**
7875
+ * Local mod version from InstanceOptions.modVersion; empty when unset.
7876
+ */
7877
+ readonly modVersion: string;
7030
7878
  };
7031
7879
 
7032
7880
  /**
@@ -7289,6 +8137,8 @@ declare global {
7289
8137
  * Arbitrary key/value state attached to one replicated entity, reached as `entity.state`. Keys set on the server replicate to every client that can currently see the entity.
7290
8138
  */
7291
8139
  class StateBag {
8140
+ private constructor();
8141
+
7292
8142
  /**
7293
8143
  * Reads one key from this entity's state.
7294
8144
  * @param key Key to read.
@@ -7438,7 +8288,7 @@ declare global {
7438
8288
 
7439
8289
  /**
7440
8290
  * Overrides the text drawn on this player's nametag.
7441
- * @param text Text to show instead of the player's name; empty or omitted restores the name.
8291
+ * @param text Text to show instead of the player's name, cut to 64 bytes; empty or omitted restores the name.
7442
8292
  */
7443
8293
  setNametagText(text?: string): void;
7444
8294
 
@@ -7451,6 +8301,219 @@ declare global {
7451
8301
 
7452
8302
  interface BasePlayer extends Entity {}
7453
8303
 
8304
+ /** */
8305
+ interface SiegeLadderKind {
8306
+ /**
8307
+ * Its name: `siege`, `tall`, `short` or `low`.
8308
+ */
8309
+ kind: string;
8310
+
8311
+ /**
8312
+ * The mesh it stands as, a path from the shared prop catalog.
8313
+ */
8314
+ model: string;
8315
+
8316
+ /**
8317
+ * How far up its rungs go, in metres.
8318
+ */
8319
+ height: number;
8320
+
8321
+ /**
8322
+ * How far it leans towards the wall standing, in degrees about its own X; it leans towards its forward.
8323
+ */
8324
+ lean: number;
8325
+ }
8326
+
8327
+ /**
8328
+ * Replicated handle for a siege ladder leaning on a wall.
8329
+ */
8330
+ class SiegeLadder {
8331
+ /**
8332
+ * Creates a script wrapper for an existing siege ladder with this ID; use SiegeLadder.spawn() to place one.
8333
+ * @param id Network entity identifier.
8334
+ */
8335
+ constructor(id: number);
8336
+
8337
+ /**
8338
+ * Which of the game's ladders it is: `siege` (the Suchdol siege ladder, 9.75 m), `tall` (5.5 m), `short` (3.25 m) or `low` (2 m).
8339
+ */
8340
+ readonly kind: string;
8341
+
8342
+ /**
8343
+ * `standing` against its wall, `pushed` (a defender's swing, then its fall), `down`, `raising` or `broken`. Named `pose` because every entity already has a `state`, which is its state bag.
8344
+ */
8345
+ readonly pose: string;
8346
+
8347
+ /**
8348
+ * How far up its rungs go, in metres: its top rests this high above its foot on the wall's top. Pick the kind whose height meets the walk.
8349
+ */
8350
+ readonly height: number;
8351
+
8352
+ /**
8353
+ * Whether the game's own climb is offered on it: while it stands and nobody has started to push it.
8354
+ */
8355
+ readonly climbable: boolean;
8356
+
8357
+ /**
8358
+ * Whether players are offered the push at its top and the raise at the foot of a fallen one, each raising `siegeLadderUse` first. On by default. The climb is the game's and is offered whenever the ladder stands.
8359
+ */
8360
+ usable: boolean;
8361
+
8362
+ /**
8363
+ * Who last pushed it, or null.
8364
+ */
8365
+ readonly pusher: Player | null;
8366
+
8367
+ /**
8368
+ * Formats this ladder handle for logging and debugging.
8369
+ * @returns The ladder ID, its kind and its pose.
8370
+ */
8371
+ toString(): string;
8372
+
8373
+ /**
8374
+ * Pushes a standing ladder off its wall. It stands through the swing, falls away from the wall as the blade meets it -- throwing off anyone climbing it -- and lies where it lands, about 4.5 seconds later.
8375
+ * @param player Who pushes it: they play the game's own halberd push, and are credited with it in `siegeLadderFall`.
8376
+ * @returns What happened, and the phrase to explain it with when nothing did.
8377
+ */
8378
+ push(player?: Player | number | null): SiegeResult;
8379
+
8380
+ /**
8381
+ * Lays a fallen ladder back against its wall, over the lift's 5.7 seconds.
8382
+ * @param player Who raises it: they play the game's own ladder lift.
8383
+ * @returns What happened, and the phrase to explain it with when nothing did.
8384
+ */
8385
+ raise(player?: Player | number | null): SiegeResult;
8386
+
8387
+ /**
8388
+ * Breaks the ladder: it lies in pieces where it stands, anyone on it falls, and nothing raises it until `repair`.
8389
+ */
8390
+ break(): void;
8391
+
8392
+ /**
8393
+ * Puts a fallen or broken ladder back against its wall at once.
8394
+ */
8395
+ repair(): void;
8396
+
8397
+ /**
8398
+ * Removes the ladder on every client after emitting `siegeLadderDestroy`.
8399
+ */
8400
+ destroy(): void;
8401
+
8402
+ /**
8403
+ * Places one of the game's own ladders leaning on a wall, the way the Suchdol and Nebakov sieges stand theirs: the game's climb, and the game's step off over the palisade at its top, which wants the top a little over the walk.
8404
+ * @param kind `siege`, `tall`, `short` or `low`.
8405
+ * @param position Where its foot stands, on the ground below the wall.
8406
+ * @param rotation Its facing: forward is the way to the wall it leans on. A Quaternion, or a Vector3 of Euler angles in degrees.
8407
+ * @param virtualWorld Optional virtual world the ladder belongs to; omitted puts it in the global one.
8408
+ * @returns The new ladder's handle.
8409
+ */
8410
+ static spawn(kind: string, position: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, virtualWorld?: number): SiegeLadder;
8411
+
8412
+ /**
8413
+ * What one kind of ladder is: its mesh, its climb and its lean -- what a placement preview needs to show it as it will stand.
8414
+ * @param kind `siege`, `tall`, `short` or `low`.
8415
+ * @returns The kind, or null for a name that is not one.
8416
+ */
8417
+ static describe(kind: string): SiegeLadderKind | null;
8418
+
8419
+ /**
8420
+ * Lists the siege ladders the server has.
8421
+ * @param virtualWorld Optional virtual world to list; omitted lists every one.
8422
+ * @returns One handle per ladder, in no particular order.
8423
+ */
8424
+ static all(virtualWorld?: number): SiegeLadder[];
8425
+
8426
+ /**
8427
+ * Looks a ladder up by its network entity ID.
8428
+ * @param id Network entity identifier.
8429
+ * @returns The ladder's handle, or null when no live ladder has that ID.
8430
+ */
8431
+ static getById(id: number): SiegeLadder | null;
8432
+
8433
+ /**
8434
+ * Removes siege ladders, emitting `siegeLadderDestroy` for each one.
8435
+ * @param virtualWorld Optional virtual world to clear; omitted clears every one.
8436
+ * @returns How many were removed.
8437
+ */
8438
+ static destroyAll(virtualWorld?: number): number;
8439
+ }
8440
+
8441
+ interface SiegeLadder extends Entity {}
8442
+
8443
+ /**
8444
+ * Replicated handle for a pile of hurling stones on a battlement.
8445
+ */
8446
+ class StonePile {
8447
+ /**
8448
+ * Creates a script wrapper for an existing stone pile with this ID; use StonePile.spawn() to place one.
8449
+ * @param id Network entity identifier.
8450
+ */
8451
+ constructor(id: number);
8452
+
8453
+ /**
8454
+ * Stones left to throw; each throw takes one, and a pile with none offers nothing. Players see at most nine in the heap. -1, the default, never runs out; any negative value means the same.
8455
+ */
8456
+ stones: number;
8457
+
8458
+ /**
8459
+ * Whether players are offered the game's own prompt at the pile. On by default.
8460
+ */
8461
+ usable: boolean;
8462
+
8463
+ /**
8464
+ * Health taken from anyone at the point a stone comes down, up to 1000; a quarter of it reaches the edge of `damageRadius`. 60 to start with; a player has 100.
8465
+ */
8466
+ damage: number;
8467
+
8468
+ /**
8469
+ * How far from where a stone comes down anyone is hurt, in metres, up to 10. 1.5 to start with.
8470
+ */
8471
+ damageRadius: number;
8472
+
8473
+ /**
8474
+ * Formats this pile handle for logging and debugging.
8475
+ * @returns The pile ID and the stones it has left.
8476
+ */
8477
+ toString(): string;
8478
+
8479
+ /**
8480
+ * Removes the pile on every client after emitting `stonePileDestroy`. A stone already thrown still lands.
8481
+ */
8482
+ destroy(): void;
8483
+
8484
+ /**
8485
+ * Places the game's own battlement pile of hurling stones, the Nebakov and Suchdol defenders' heap. Its prompt, the lift and the heave over the wall are the game's stone throwing; each stone is a real rigid body that falls where it falls.
8486
+ * @param position Where the thrower stands on the walk, behind the parapet.
8487
+ * @param rotation Its facing: forward is the way the stones go, over the wall. A Quaternion, or a Vector3 of Euler angles in degrees.
8488
+ * @param virtualWorld Optional virtual world the pile belongs to; omitted puts it in the global one.
8489
+ * @returns The new pile's handle.
8490
+ */
8491
+ static spawn(position: Vector3 | Partial<Vector3>, rotation?: Vector3 | Quaternion, virtualWorld?: number): StonePile;
8492
+
8493
+ /**
8494
+ * Lists the stone piles the server has.
8495
+ * @param virtualWorld Optional virtual world to list; omitted lists every one.
8496
+ * @returns One handle per pile, in no particular order.
8497
+ */
8498
+ static all(virtualWorld?: number): StonePile[];
8499
+
8500
+ /**
8501
+ * Looks a pile up by its network entity ID.
8502
+ * @param id Network entity identifier.
8503
+ * @returns The pile's handle, or null when no live pile has that ID.
8504
+ */
8505
+ static getById(id: number): StonePile | null;
8506
+
8507
+ /**
8508
+ * Removes stone piles, emitting `stonePileDestroy` for each one.
8509
+ * @param virtualWorld Optional virtual world to clear; omitted clears every one.
8510
+ * @returns How many were removed.
8511
+ */
8512
+ static destroyAll(virtualWorld?: number): number;
8513
+ }
8514
+
8515
+ interface StonePile extends Entity {}
8516
+
7454
8517
  /**
7455
8518
  * Calls a function once after a delay.
7456
8519
  * @param handler Function to call.