@adatechnology/game-contracts 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -71,11 +71,18 @@ interface PartSpec {
71
71
  fluid: FluidKind;
72
72
  liters: number;
73
73
  pressurized?: boolean;
74
+ /**
75
+ * Object-local direction the fluid leaves through a hole (the `leak` event's `direction`), for a fluid that does not spray back out of the hole
76
+ * but runs down through it: the water on a roof membrane goes `[0, -1, 0]` into the floor below. Default: out of the hole (its normal).
77
+ */
78
+ outflow?: Vec3;
74
79
  };
75
80
  /** The part explodes when destroyed, or when its temperature passes `atC` (gas bottle, fuel tank, aerosol). */
76
81
  explodes?: {
77
82
  energy: number;
78
83
  radius: number;
84
+ /** Inside this radius (metres) the blast is lethal to a body; from here to `radius` it only hurts, less with distance. Without it a body takes the energy falling off over `radius`. */
85
+ lethalRadius?: number;
79
86
  atC?: number;
80
87
  /**
81
88
  * Chain reaction: what sets the part off before it is destroyed and the seconds from that to the blast (a number, or `[min, max]` drawn
@@ -98,6 +105,8 @@ interface PartSpec {
98
105
  structure?: {
99
106
  role: StructureRole;
100
107
  capacity?: number;
108
+ rebar?: TensionRebar;
109
+ pile?: PileSpec;
101
110
  };
102
111
  /**
103
112
  * Coats over the core, outermost first (plaster, tile, the paper of a drywall board). `thickness` of the part is the core only; each coat adds
@@ -114,6 +123,18 @@ interface PartSpec {
114
123
  * `radius` metres of a point that adds up to `area` square metres opens the part: stage 2, the part stays with an opening.
115
124
  */
116
125
  breach?: PartBreach;
126
+ /**
127
+ * The part is a tuned mass damper: a mass on springs and dashpots near the top of a building that moves against its sway (`wind`). Its `mass` is the
128
+ * damper's mass and enters the load like any other part. Without `frequency` and `damping` the world tunes it to the building (Den Hartog).
129
+ */
130
+ damper?: TunedMassDamper;
131
+ }
132
+ /** A tuned mass damper (`PartSpec.damper`). */
133
+ interface TunedMassDamper {
134
+ /** Natural frequency of the damper on its springs, in Hz (default: tuned to the first mode of the building by `wind.tuning`). */
135
+ frequency?: number;
136
+ /** Damping ratio of the damper (default: the optimum for its mass ratio). */
137
+ damping?: number;
117
138
  }
118
139
  /** A coat over a part's core. `faces` says on which side(s) of the part's thinnest axis it lies (`'+'` and `'-'` are the local +/- directions). */
119
140
  interface SurfaceLayer {
@@ -132,6 +153,48 @@ interface Reinforcement {
132
153
  /** Fraction of the part's structural capacity the bare cage keeps (default 0.15). */
133
154
  residualCapacity?: number;
134
155
  }
156
+ /**
157
+ * Tension steel of a concrete beam, slab, roof or stair for the bending model (`DestructionOptions.structure.flexure`), when it is not taken from the
158
+ * `reinforcement` cage. `ratio` is the steel area over the effective section of the tension face, `As / (b * d)` (NBR 6118: at least 0.15% for
159
+ * C25-C30; beams 0.5-1.5%, slabs 0.2-0.6%). Unlike `reinforcement` it draws no bars and does not stage the part.
160
+ */
161
+ interface TensionRebar {
162
+ /** `As / (b * d)` of the tension face, 0..0.04. */
163
+ ratio: number;
164
+ /** Yield strength of the steel in MPa (default `flexure.rebarYieldMPa`, 500 = CA-50). */
165
+ yieldMPa?: number;
166
+ /** Concrete cover to the bar in metres (default `flexure.cover`). */
167
+ cover?: number;
168
+ }
169
+ /**
170
+ * Deep foundation under a `foundation` part (its pile cap): `count` concrete piles of `diameter` going `length` metres down from the bottom of the
171
+ * part, laid out in a grid under it. They carry the load by end bearing at the tip and skin friction along the shaft, from the soil layers they go
172
+ * through (`DestructibleSpec.soil`). Without it a foundation part is a shallow footing (pad, strip or raft) that bears on the soil under it.
173
+ */
174
+ interface PileSpec {
175
+ /** Metres below the bottom of the part. */
176
+ length: number;
177
+ /** Metres. */
178
+ diameter: number;
179
+ /** Piles under the part (default 1). */
180
+ count?: number;
181
+ /** `bored` (cast in place, the default) or `driven` (precast): how much of the soil's resistance the pile mobilises. */
182
+ method?: 'bored' | 'driven';
183
+ }
184
+ /** One layer of soil, from the top down. `soil` is a soil class id (`clay_soft`, `sand_dense`, `rock`...); the last layer goes on forever. */
185
+ interface SoilLayer {
186
+ soil: string;
187
+ /** Metres (ignored on the last layer). */
188
+ thickness?: number;
189
+ }
190
+ /** The ground under an object. Settlement, tilt and bearing failure are computed only for objects that have one. */
191
+ interface SoilProfile {
192
+ layers: readonly SoilLayer[];
193
+ /** Object-local height of the ground surface (default: the top of the highest foundation part). */
194
+ surface?: number;
195
+ /** Width a footing has at least where a part rests on a foundation tagged `terrain` (default 0.6 m, the NBR 6122 minimum). */
196
+ footingWidth?: number;
197
+ }
135
198
  /** Size of one masonry unit in the part's axes (`size[2]` is along the part's thinnest axis, clamped to it) and how rows are laid. */
136
199
  interface PartUnits {
137
200
  size: Vec3;
@@ -186,6 +249,31 @@ interface DestructibleSpec {
186
249
  joints?: JointSpec[];
187
250
  /** Free tags (`furniture`, `vehicle`, `plant`, `structure`, `weapon`, `item`...). */
188
251
  tags?: string[];
252
+ /**
253
+ * The ground the object stands on: a soil class id (one layer) or a profile. With it the foundations bear on the soil: the object settles, tilts
254
+ * and, when the soil cannot carry it, sinks and tips over (`ObjectState.soil`, `settle` events). Without it the foundations are fixed as before.
255
+ */
256
+ soil?: string | SoilProfile;
257
+ /**
258
+ * How this object takes the wind of the world (`DestructionOptions.wind`): where it stands and what shape it has. Each field replaces the world's for
259
+ * this object. `false` keeps the object out of the wind. Without the world's `wind` it does nothing.
260
+ */
261
+ wind?: WindExposure | false;
262
+ }
263
+ /** What belongs to the place and the shape of one building in the wind (`DestructibleSpec.wind`; the world's `wind` has the same fields as defaults). */
264
+ interface WindExposure {
265
+ /** Roughness category of the terrain around it, `I` (sea, flat water) to `V` (city centre with tall buildings): NBR 6123 table 1. */
266
+ terrain?: 'I' | 'II' | 'III' | 'IV' | 'V';
267
+ /** Class by the largest dimension, `A` up to 20 m, `B` to 50 m, `C` above (`auto`: from the building). */
268
+ class?: 'auto' | 'A' | 'B' | 'C';
269
+ /** Topographic factor S1 (1: flat ground; a hill top is above 1). */
270
+ topography?: number;
271
+ /** Statistical factor S3 (1: homes and offices; 1.1 for essential buildings). */
272
+ statistical?: number;
273
+ /** Drag coefficient Ca of the whole building (1.3: windward 0.8 + leeward 0.5). */
274
+ drag?: number;
275
+ /** Structural damping ratio of the first mode (0.016: reinforced concrete). */
276
+ damping?: number;
189
277
  }
190
278
  type DamageType =
191
279
  /** bullets and pellets: `energy`, `caliber`; makes holes, dents, cracks, ricochets */
@@ -272,6 +360,18 @@ interface BlastReport {
272
360
  /** Fragment hits that landed on this target. */
273
361
  fragmentHits: number;
274
362
  }
363
+ /**
364
+ * How likely a round is to set flammable vapour or fuel alight when it hits a container of it, as the weapons module resolves them for the round
365
+ * (core, jacket, incendiary or tracer composition, each with a configured chance). 0..1 each, per hit.
366
+ */
367
+ interface HitIgnition {
368
+ /** Sparks from a hard core or jacket striking metal: counts only when the struck part is metal. */
369
+ spark: number;
370
+ /** A flame the round carries (incendiary, tracer): counts whatever it hits. */
371
+ flame: number;
372
+ }
373
+ /** The ballistic fields of a `Hit` that come from the round and not from the shot geometry (see `shotExtras`). */
374
+ type BallisticExtras = Pick<Hit, 'piercing' | 'penetration' | 'incendiary' | 'tracer' | 'ignition'>;
275
375
  interface Hit {
276
376
  type: DamageType;
277
377
  /** Point of the hit (world space unless `space: 'local'`). For `explosive` it is the centre of the blast. */
@@ -284,6 +384,8 @@ interface Hit {
284
384
  caliber?: number;
285
385
  /** Radius of effect in metres (blast radius, flame radius, blunt contact radius). */
286
386
  radius?: number;
387
+ /** `explosive` only: inside this radius (metres) a body takes the blast as lethal; between it and `radius` it is hurt, less with distance. */
388
+ lethalRadius?: number;
287
389
  /** Source temperature for `fire` and `heat`. */
288
390
  temperature?: number;
289
391
  /** Seconds the heat is applied for (a flamethrower calls `hit` every frame with `duration: dt`). */
@@ -303,6 +405,19 @@ interface Hit {
303
405
  * less steel than its joules say, an armour-piercing core more: the energy that counts against the penetration of a hard material (metal, masonry) is `energy * piercing`; wood, glass and soft materials take the energy as it is.
304
406
  */
305
407
  piercing?: number;
408
+ /**
409
+ * Ballistic: how far the projectile goes through, in millimetres, by material class (`steel`, `concrete`, `brick`, `wood`, or a material id). The world
410
+ * takes the entry of the struck material (its `penetrationClass`, else its id, scaled by its `penetrationScale`) and the bullet goes through when it is
411
+ * at least as thick as the part; a material with no entry falls back to the energy rule (`energy` and `piercing`). The engine reads no calibre
412
+ * names: the weapons put the numbers here (`ammo.penetration` of `@adatechnology/game-weapons`, scaled by the energy left at the hit).
413
+ */
414
+ penetration?: Readonly<Record<string, number>>;
415
+ /** Ballistic: the round carries an incendiary composition (it can light flammable vapour and fuel whatever it hits). */
416
+ incendiary?: boolean;
417
+ /** Ballistic: the round is a tracer (a burning pyrotechnic in the base). */
418
+ tracer?: boolean;
419
+ /** Ballistic: chances that the round lights flammable vapour or fuel (see `HitIgnition`). Absent: it never does. */
420
+ ignition?: HitIgnition;
306
421
  /** Explosive: pressure multiplier the host knows (a room volume); the energy is then `energy * confinement` and the ray estimate is skipped. */
307
422
  confinement?: number;
308
423
  /** Explosive: per-call blast options (see `BlastOptions`). */
@@ -332,6 +447,8 @@ interface Hole {
332
447
  diameter: number;
333
448
  /** The projectile went through. */
334
449
  through: boolean;
450
+ /** An opening made on purpose (`DestructionWorld.vent`: a valve, a tap), not damage: `seal` closes it. */
451
+ vent?: boolean;
335
452
  }
336
453
  interface Crack {
337
454
  point: Vec3;
@@ -372,6 +489,16 @@ interface PartState {
372
489
  stress?: number;
373
490
  /** Damage stage; only present on parts that opted in (see `PartSpec.breach`). */
374
491
  stage?: DamageStage;
492
+ /**
493
+ * Beams, slabs, roofs and stairs of a material with `strength.tensileMPa` only: bending moment at rest over the moment the section holds (the steel's
494
+ * when it is reinforced and holds more than the concrete's cracking moment, else the cracking moment). `stress` is the largest of this and the
495
+ * compression ratio.
496
+ */
497
+ flexure?: number;
498
+ /** Axial force the wind adds to a wall or column, in newtons (compression positive, tension negative; `DestructionOptions.wind`). */
499
+ wind?: number;
500
+ /** The tension face cracked (a blast, an impact or the load bent it past the cracking moment): the concrete no longer carries tension, the steel does. */
501
+ cracked?: boolean;
375
502
  /** Reinforced part whose concrete is gone: only the rebar cage is left (capacity x `residualCapacity`); it is still part of the structure. */
376
503
  stripped?: boolean;
377
504
  /** Opening a breach left, in object-local space (stage 2). Raycasts and shots pass through it. */
@@ -382,6 +509,61 @@ interface PartState {
382
509
  /** Index into `ObjectState.groups` of the piece this part belongs to (-1 when the part is broken, melted or ash). */
383
510
  group: number;
384
511
  }
512
+ /** How the ground under an object is holding (`DestructibleSpec.soil`). */
513
+ interface SoilState {
514
+ /** Metres the foundations went down, at their centre of stiffness. */
515
+ settlement: number;
516
+ /** Degrees the object leans from the vertical. */
517
+ tilt: number;
518
+ /** Object-local horizontal unit vector the top leans toward (zero when it stands straight). */
519
+ direction: Vec3;
520
+ /** Weight of the object over what its foundations can carry before the soil gives way (above 1 it sinks). */
521
+ bearing: number;
522
+ /** Largest share of its capacity any foundation (a strip of a footing, a pile) is using, 0..1: at 1 the soil under it is yielding. */
523
+ edge: number;
524
+ /** `stable`: at rest; `yielding`: the soil is giving way and the object is still moving; `toppled`: it tipped over. */
525
+ status: 'stable' | 'yielding' | 'toppled';
526
+ /**
527
+ * The settled pose relative to the pose the host gave (`setTransform`), in object-local space: draw the object's parts under a node with this
528
+ * transform. `ObjectState.position` and `rotation` already include it.
529
+ */
530
+ offset: {
531
+ position: Vec3;
532
+ rotation: Quat;
533
+ };
534
+ }
535
+ /** How a building is taking the wind (`DestructionOptions.wind`). */
536
+ interface WindState {
537
+ /** Basic speed of the wind in m/s. */
538
+ speed: number;
539
+ /** Design pressure at the top, N/m². */
540
+ pressure: number;
541
+ /** Design shear at the base, N (the sum of the forces on every storey). */
542
+ shear: number;
543
+ /** Design overturning moment at the base, N m. */
544
+ moment: number;
545
+ /** Top deflection under the design wind, metres. */
546
+ deflection: number;
547
+ /** Top deflection over the height (the drift) and its limit (default 1/500). */
548
+ drift: number;
549
+ limit: number;
550
+ /** Overturning moment over what the weight resists (above 1 the building tips over on its foundation). */
551
+ overturn: number;
552
+ /** First-mode frequency in Hz. */
553
+ frequency: number;
554
+ /** Top deflection under the mean wind, metres: how far the building leans while the wind blows. */
555
+ lean: number;
556
+ /** Swing of the top about that lean now and its recent peak, metres, along the wind. */
557
+ sway: number;
558
+ peak: number;
559
+ /** Tuned mass damper: mass over the modal mass and its travel against the top now, metres. */
560
+ damper?: {
561
+ ratio: number;
562
+ travel: number;
563
+ };
564
+ /** `ok`; `drift`: the drift is over its limit; `overturn`: the overturning moment passes what the weight resists. */
565
+ status: 'ok' | 'drift' | 'overturn';
566
+ }
385
567
  interface JointState {
386
568
  id: string;
387
569
  a: string;
@@ -410,6 +592,10 @@ interface ObjectState {
410
592
  groups: string[][];
411
593
  /** Every part is broken, melted or ash. */
412
594
  destroyed: boolean;
595
+ /** Only objects with `DestructibleSpec.soil`: how the ground under it is holding. */
596
+ soil?: SoilState;
597
+ /** Only structures in the wind of the world (`DestructionOptions.wind`): the load, the drift and the sway of the building. */
598
+ wind?: WindState;
413
599
  /** Only objects that are a living body (a character, an animal): the summary the crowd and the HUD read. */
414
600
  body?: {
415
601
  alive: boolean;
@@ -535,6 +721,7 @@ type DestructionEvent = (EventBase & {
535
721
  point: Vec3;
536
722
  energy: number;
537
723
  radius: number;
724
+ lethalRadius?: number;
538
725
  effect?: string;
539
726
  })
540
727
  /** An explosive part was set off by a bullet, fire or a nearby blast and will explode `delay` seconds from now (`explodes.chain`). */
@@ -552,6 +739,32 @@ type DestructionEvent = (EventBase & {
552
739
  stress: number;
553
740
  load: number;
554
741
  })
742
+ /**
743
+ * The ground under an object moved (`DestructibleSpec.soil`): it settled or leans more, the soil started or stopped yielding, or it tipped over
744
+ * (`status: 'toppled'`, followed by a `collapse` of everything). Throttled to once per 0.5 s while it moves. `direction` is in world space.
745
+ */
746
+ | (EventBase & {
747
+ type: 'settle';
748
+ settlement: number;
749
+ tilt: number;
750
+ direction: Vec3;
751
+ bearing: number;
752
+ status: SoilState['status'];
753
+ })
754
+ /**
755
+ * A building in the wind (`DestructionOptions.wind`) changed how it stands: the drift went over its limit or came back, the overturning moment passed
756
+ * what the weight resists, or the sway of the top grew. Throttled to once per 0.5 s. `direction` is the wind's, in world space.
757
+ */
758
+ | (EventBase & {
759
+ type: 'sway';
760
+ sway: number;
761
+ peak: number;
762
+ drift: number;
763
+ overturn: number;
764
+ frequency: number;
765
+ direction: Vec3;
766
+ status: WindState['status'];
767
+ })
555
768
  /** A group with structural parts lost every anchored part (an anchored part exists in the object): it falls. Reported once per group. */
556
769
  | (EventBase & {
557
770
  type: 'collapse';
@@ -653,6 +866,79 @@ interface RayHit {
653
866
  distance: number;
654
867
  }
655
868
 
869
+ /**
870
+ * What the host lends a module so that a slow job never looks like a frozen page: the host shows its own indicator (a spinner, a bar, a line of text) while the job runs. Nothing here is
871
+ * specific to a kind of module; a host with no indicator leaves `ModuleHost.loading` out and the module just does the work.
872
+ */
873
+ interface BusyTask {
874
+ /** Updates the text and, when the task has a `total`, how many steps are done (the bar). Both optional. */
875
+ step(text?: string, done?: number): void;
876
+ /** Resolves after the browser painted what the task shows: await it between the steps of a long job so the indicator moves. */
877
+ paint(): Promise<void>;
878
+ /** Takes the indicator down (the last open task of the host hides it). Safe to call twice. */
879
+ end(): void;
880
+ }
881
+ interface BusyOptions {
882
+ /** How many steps the job has: the indicator draws a bar. Without it, only a spinner. */
883
+ readonly total?: number;
884
+ /** The indicator hides what is behind it (the first load of a page) instead of dimming it. */
885
+ readonly opaque?: boolean;
886
+ }
887
+ interface BusySink {
888
+ /** Shows the indicator at once and returns the task to update and end. The work that follows only paints it if the caller awaits `task.paint()` first. */
889
+ begin(label: string, options?: BusyOptions): BusyTask;
890
+ /**
891
+ * Shows the indicator, waits for it to be painted, runs `work` (synchronous work too) and takes the indicator down when it finishes or throws. Resolves with the result of `work`. The way to
892
+ * run a heavy synchronous job: the page shows what is going on instead of freezing.
893
+ */
894
+ busy<T>(label: string, work: (task: BusyTask) => T | Promise<T>, options?: BusyOptions): Promise<T>;
895
+ }
896
+
897
+ /**
898
+ * The numbers of the shove a blast gives to a body that moves (a loose item, a piece of furniture, a person): all of them a game value, with a default that reads well in a room,
899
+ * not a physical table. A host reads them once and lends them to the modules that move their own bodies (`ModuleHost.blastShove`).
900
+ */
901
+ interface BlastShoveOptions {
902
+ /**
903
+ * The share of the blast energy that reaches a body as motion: the speed at the centre is `sqrt(2 * energy * coupling / mass)`, before the falloff (default 0.02).
904
+ */
905
+ readonly coupling?: number;
906
+ /** Fastest a body is thrown, in m/s, at the centre of the blast (default 20). */
907
+ readonly maxSpeed?: number;
908
+ /** How much of the push goes up: the direction is `(away, lift)` normalised from the horizontal outward direction (default 0.3). */
909
+ readonly lift?: number;
910
+ /** Below this speed (m/s) nothing moves: a heavy thing far from a small blast stays where it is (default 0.3). */
911
+ readonly minSpeed?: number;
912
+ /** Exponent of the falloff `(1 - distance / radius) ^ power`, the same as the damage of the destruction world (default 2). */
913
+ readonly falloffPower?: number;
914
+ }
915
+ /** The defaults of `BlastShoveOptions`. */
916
+ declare const DEFAULT_BLAST_SHOVE: Readonly<Required<BlastShoveOptions>>;
917
+ /** A blast as the shove reads it: where, how much energy (J) and how far it reaches (m). `reach` (0..1) is the share that got through what stood in the way. */
918
+ interface BlastSource {
919
+ readonly point: Vec3;
920
+ readonly energy: number;
921
+ readonly radius: number;
922
+ readonly reach?: number;
923
+ }
924
+ /** What a blast does to one body: how fast it leaves (m/s), the unit direction it leaves in, and how far from the centre it was. */
925
+ interface BlastShove {
926
+ readonly speed: number;
927
+ readonly direction: Vec3;
928
+ readonly distance: number;
929
+ /** The falloff applied, 0..1. */
930
+ readonly falloff: number;
931
+ }
932
+ /**
933
+ * The shove a blast gives to a body of `mass` kg whose centre is at `position`: away from the centre, lifted a little, with the speed
934
+ * `min(maxSpeed, sqrt(2 * energy * reach * coupling / mass)) * (1 - distance / radius) ^ 2`. Undefined when the body is outside the radius or the speed is under `minSpeed`.
935
+ * The same rule moves the loose items and furniture of the test room and the people of the characters module, so a game that tunes the options tunes all of them.
936
+ */
937
+ declare function blastShove(blast: BlastSource, target: {
938
+ readonly position: Vec3;
939
+ readonly mass: number;
940
+ }, options?: BlastShoveOptions): BlastShove | undefined;
941
+
656
942
  /**
657
943
  * What a game module implements for an object whose behaviour it owns (a vehicle with its own panel deformation, a creature, a machine). The
658
944
  * world (`DestructionWorld.register`) hosts it next to its own objects: raycast, shoot, explode, hit, disassemble, extinguish, update, state,
@@ -770,7 +1056,21 @@ interface Shot {
770
1056
  /** snake_case weapon id. */
771
1057
  weapon: string;
772
1058
  source?: string;
1059
+ /** Kind of the round that was loaded (`fmj`, `hp`, `ap`, `buck`, `slug`, `incendiary`, `tracer`...). */
1060
+ ammo?: string;
1061
+ /** Millimetres of steel, concrete, brick and wood the round goes through at the muzzle (the ammo table of the weapons module). `shotToHit` scales it by the energy left. */
1062
+ penetration?: Readonly<Record<string, number>>;
1063
+ incendiary?: boolean;
1064
+ tracer?: boolean;
1065
+ /** Chances that the round lights flammable vapour or fuel. */
1066
+ ignition?: HitIgnition;
773
1067
  }
1068
+ /**
1069
+ * The fields of the round that a damage model takes besides the geometry: the penetration by material scaled by the energy that is left at `distance`
1070
+ * (linear in the energy: half the energy goes through half as much), the incendiary and tracer flags and the ignition chances. Pass it as the sixth
1071
+ * argument of `DestructionWorld.shoot` or spread it in a `Hit`.
1072
+ */
1073
+ declare const shotExtras: (shot: Shot, distance?: number) => BallisticExtras;
774
1074
  /** One use of a non-firearm (melee swing, flame tick, heat tick, throw, tool tick, extinguisher tick). */
775
1075
  type Use = {
776
1076
  kind: 'melee';
@@ -882,6 +1182,75 @@ type Use = {
882
1182
  * change the hit; it is accepted so that callers can pass what their raycast returned and so that a stricter implementation could use it.
883
1183
  */
884
1184
  declare const shotToHit: (shot: Shot, point: Vec3, normal?: Vec3) => Hit;
1185
+ /**
1186
+ * The `Hit` a non-firearm `Use` makes at `point` (world space), or `null` for uses that do not damage by themselves.
1187
+ *
1188
+ * - `melee` -> `blunt` / `slash` with the swing's `energy`, contact `radius` and `direction`;
1189
+ * - `flame` -> `fire` and `heat` -> `heat`, with `temperature`, `duration` and a contact radius of at most 0.3 m (one ray of the cone);
1190
+ * - `throw` -> the blast (`explosive`, `energy`, `radius`, centred on `point`, the place it detonates). A thrown item with no blast energy but
1191
+ * a `fire` patch (a molotov) gives that patch as a `fire` hit (`temperature`, `radius`, `seconds` as `duration`). No energy and no fire -> `null`;
1192
+ * - `tool`, `extinguish` and `hand` -> `null` (tools work on joints, the extinguisher cools, the hand only grabs).
1193
+ *
1194
+ * `normal` does not change the hit (same as `shotToHit`).
1195
+ */
1196
+ declare const useToHit: (use: Use, point: Vec3, normal?: Vec3) => Hit | null;
1197
+
1198
+ /**
1199
+ * How a container of flammable fluid (a fuel tank, a jerrycan, a gas bottle) is set alight by what hits it. A normal bullet that goes through only
1200
+ * makes a leak; the leak lights when something supplies a flame: a spark of a hard round on metal, an incendiary or tracer round, a fire nearby
1201
+ * or a blast. These are the numbers of the target side; the numbers of the round (core, jacket, incendiary, tracer) are in the weapons module
1202
+ * (`rules.ignition` of `@adatechnology/game-weapons`) and reach the target in `Hit.ignition`. Every number is a default to be changed per game.
1203
+ */
1204
+ interface IgnitionRules {
1205
+ /**
1206
+ * How much of the spark and of the flame of a round reaches the vapour, by how full the container is: points `[filled, factor]`, `filled` 0..1
1207
+ * (litres over capacity), `factor` 0..1, linear between points. A full container holds a mixture too rich to burn (the vapour has no air) and
1208
+ * mostly leaks; a nearly empty one holds the vapour/air mixture of a flammable range and lights the easiest; a dry one has little vapour left.
1209
+ * Default: 0.6 empty, 1 at 10 percent, 0.6 at 35, 0.3 at 65, 0.15 at 90 and 0.12 full.
1210
+ */
1211
+ fillCurve: ReadonlyArray<readonly [number, number]>;
1212
+ /** 0..1: how much of the fill factor also weighs on the flame of an incendiary or tracer (1: as much as on a spark; 0: not at all). Default 0.5. */
1213
+ flameFillInfluence: number;
1214
+ /** Chance of the flame of a round that is flagged `incendiary` or `tracer` but carries no `ignition` numbers (a host that passes only the flags). */
1215
+ flameDefaults: {
1216
+ incendiary: number;
1217
+ tracer: number;
1218
+ };
1219
+ /**
1220
+ * What a spark needs to strike: a factor 0..1 by material id of the struck part. A material that is not listed but is metal takes
1221
+ * `sparkMetalDefault`; a part that is not metal never sparks. Default: steel and iron 1, aluminium 0.25.
1222
+ */
1223
+ sparkTarget: Readonly<Record<string, number>>;
1224
+ sparkMetalDefault: number;
1225
+ /**
1226
+ * Factor 0..1 on the spark by fluid (default 1): diesel has a flash point of 52 degrees C and more, so a spark that lights petrol vapour does
1227
+ * not light it (a flame does). Default: diesel 0.15.
1228
+ */
1229
+ sparkFluid: Readonly<Record<string, number>>;
1230
+ /** A leaking container of flammable fluid within `radius` metres of a burning part or a burning fuel stain lights at `chancePerSecond`. */
1231
+ fireNear: {
1232
+ radius: number;
1233
+ chancePerSecond: number;
1234
+ };
1235
+ }
1236
+ /** Defaults of `IgnitionRules`. */
1237
+ declare const DEFAULT_IGNITION_RULES: IgnitionRules;
1238
+ /** Merges a partial `IgnitionRules` over the defaults (an object is merged one level deep). */
1239
+ declare const resolveIgnitionRules: (rules?: Partial<IgnitionRules>) => IgnitionRules;
1240
+ /** Linear interpolation of the fill curve at `fill` (0..1); outside the points it keeps the first or the last. */
1241
+ declare const fillFactor: (fill: number, curve?: IgnitionRules["fillCurve"]) => number;
1242
+ /** The factor of what a spark strikes: 0 when the struck part is not metal. */
1243
+ declare const sparkTargetFactor: (materialId: string, metal: boolean, rules?: IgnitionRules) => number;
1244
+ /**
1245
+ * Chance that one round that went through the wall of a container lights the fluid that leaks: the spark (only on metal) and the flame (any
1246
+ * wall), each weighed by the fill of the container; the two are independent. 0 when the round carries nothing (`Hit.ignition` absent and not
1247
+ * flagged `incendiary` or `tracer`): a plain bullet on a plain wall only leaks.
1248
+ */
1249
+ declare const ignitionChance: (hit: Pick<Hit, "incendiary" | "tracer" | "ignition">, target: {
1250
+ sparkTarget: number;
1251
+ fill: number;
1252
+ fluid?: string;
1253
+ }, rules?: IgnitionRules) => number;
885
1254
 
886
1255
  /**
887
1256
  * Fluid contract: what a module says about the liquid its item holds, and how the item is used. Types only: the liquids themselves, their
@@ -936,6 +1305,37 @@ interface ItemUseDef {
936
1305
  liquids?: LiquidId[];
937
1306
  }
938
1307
 
1308
+ /**
1309
+ * Where a hand should be, in world space. `position` is the middle of the palm; the orientation follows one convention for every hand: the hand-local +x runs from the wrist to the
1310
+ * knuckles (the way the fingers point when open), +y is the back of the hand and +z completes the frame (for a right hand the little finger side; the thumb is at -z). A left hand is the
1311
+ * mirror image of a right one, so the same numbers describe the same grip: its thumb is at +z.
1312
+ */
1313
+ interface HandPose {
1314
+ position: Vec3;
1315
+ /** Unit quaternion `[x, y, z, w]`, hand-local to world. */
1316
+ quaternion: [number, number, number, number];
1317
+ }
1318
+ /**
1319
+ * What a tool in the hands asks of the hands that hold it (a weapon asks for a grip on its grip and handguard, a carried item for a hand under it). A side left out or null is not held:
1320
+ * the hand stays in its rest stance. Nothing here knows what the tool is.
1321
+ */
1322
+ interface HandTargets {
1323
+ R?: HandPose | null;
1324
+ L?: HandPose | null;
1325
+ /** How closed the fingers are, 0 open to 1 closed on a grip. Default 1. */
1326
+ grip?: number;
1327
+ /** The same for the left hand, when it differs from `grip` (a hand laid on a forend is looser than the one on the trigger). */
1328
+ gripL?: number;
1329
+ /** The size of the hands against life size (a tool drawn smaller than real takes smaller hands). Default 1. */
1330
+ scale?: number;
1331
+ /** Fingers of the right hand that curl by themselves, 0 extended to 1 fully curled (the index finger of a trigger hand); the others follow `grip`. */
1332
+ fingers?: {
1333
+ index?: number;
1334
+ };
1335
+ }
1336
+ /** Read every frame by whoever draws the arms; answers null while nothing is held. */
1337
+ type HandTargetSource = () => HandTargets | null;
1338
+
939
1339
  /**
940
1340
  * The bench of a module: controls, layers and counters it declares as data. The host keeps the values, draws them in a generic way and hands
941
1341
  * every change back through `ModuleHost.bench`. Nothing here is specific to a kind of module.
@@ -954,6 +1354,11 @@ interface ControlBase {
954
1354
  readonly name: string;
955
1355
  readonly hint?: string;
956
1356
  readonly hidden?: boolean;
1357
+ /**
1358
+ * The change (or the press, for an action) takes a noticeable time, a third of a second or more: the host shows its loading indicator while it works, with this text, or the control's name for `true`.
1359
+ * Only the host's own controls panel does it; a change made through `TestRoom.bench().set / act` runs at once.
1360
+ */
1361
+ readonly slow?: boolean | string;
957
1362
  }
958
1363
  interface NumberControl extends ControlBase {
959
1364
  readonly kind: 'number';
@@ -1109,6 +1514,16 @@ interface EffectSink {
1109
1514
  catalog?(): readonly string[];
1110
1515
  }
1111
1516
 
1517
+ /**
1518
+ * Throwaway meshes that use every kind of material a renderer makes later on demand (a hole decal, a stream of liquid, a puff of smoke). A host adds `group` to its scene for
1519
+ * ONE render, so that the shader programs are built then and not in the middle of play (the first shot or leak stalls the frame otherwise), and calls `dispose` afterwards.
1520
+ * `group` is the three.js `Object3D`: `unknown` here because the contracts do not depend on three.js.
1521
+ */
1522
+ interface WarmUpProbes {
1523
+ readonly group: unknown;
1524
+ dispose(): void;
1525
+ }
1526
+
1112
1527
  /** Pose of one part (or of the whole item) at a key: position offset in metres and Euler XYZ rotation in radians, both relative to the rest pose. */
1113
1528
  interface AnimationPose {
1114
1529
  position?: Vec3;
@@ -1274,6 +1689,8 @@ interface TestableItem {
1274
1689
  animations?: AnimationClipSpec[];
1275
1690
  /** Can be grabbed and thrown. */
1276
1691
  movable?: boolean;
1692
+ /** Building it takes a noticeable time (a vehicle, a district): the host's catalogue shows its loading indicator while it spawns one. `true`, or the text to show. */
1693
+ slow?: boolean | string;
1277
1694
  /**
1278
1695
  * A picture of the item for menus, search results and the label of the aimed item: the URL of an image (an SVG silhouette is drawn in the text colour, so give it one colour with
1279
1696
  * the tones as opacity) or the SVG markup itself (starts with `<svg`). Optional: an item without one shows its name only.
@@ -1444,6 +1861,10 @@ type HostEvent =
1444
1861
  radius: number;
1445
1862
  cause: string;
1446
1863
  explosive?: string;
1864
+ }
1865
+ /** The player crouched or stood up, or the camera mode changed; read the new state with `host.player()`. */
1866
+ | {
1867
+ type: 'player';
1447
1868
  };
1448
1869
  /** The tool in hand as the host sees it. */
1449
1870
  interface HostTool {
@@ -1506,6 +1927,21 @@ interface ToolCommandResult {
1506
1927
  readonly reason?: string;
1507
1928
  readonly seconds?: number;
1508
1929
  }
1930
+ /** The player as the host sees it. Generic: any game with someone walking around in a world has these. */
1931
+ interface PlayerState {
1932
+ /** World position of the player's feet, metres. */
1933
+ readonly position: Vec3;
1934
+ /** Radians around the vertical axis; 0 looks down -z. */
1935
+ readonly yaw: number;
1936
+ /** Radians up (positive) or down (negative). */
1937
+ readonly pitch: number;
1938
+ readonly crouching: boolean;
1939
+ /** Horizontal speed in metres per second. */
1940
+ readonly speed: number;
1941
+ readonly running: boolean;
1942
+ /** How the camera follows the player (`first`, `shoulder`...); the ids are the host's. */
1943
+ readonly cameraMode: string;
1944
+ }
1509
1945
  /**
1510
1946
  * What the host lends a module that brings its own presentation (a weapon in the hands, sounds, ejected casings). `THREE`, `scene` and `camera`
1511
1947
  * are the host's three.js namespace, scene and camera: `unknown` here because the contracts do not depend on three.js.
@@ -1518,6 +1954,8 @@ interface ModuleHost {
1518
1954
  /** Height of whatever things rest on at (x, z): the floor, a table, a counter. */
1519
1955
  groundAt(x: number, z: number): number;
1520
1956
  tool(): HostTool;
1957
+ /** The player now: where, which way, crouching, how fast and how the camera follows. A `player` event tells when crouching or the camera mode changes. */
1958
+ player(): PlayerState;
1521
1959
  /** Follow the player's tool events. Returns the unsubscribe function. */
1522
1960
  on(listener: (event: HostEvent) => void): () => void;
1523
1961
  /** Run every simulated frame with the frame's seconds. Returns the unsubscribe function. */
@@ -1527,8 +1965,8 @@ interface ModuleHost {
1527
1965
  * unsubscribe function. A host that never clears leaves it out.
1528
1966
  */
1529
1967
  onClear?(listener: () => void): () => void;
1530
- /** Write a line to the host's behaviour log. */
1531
- log(text: string, data?: Record<string, unknown>): void;
1968
+ /** Write a line to the host's behaviour log; `type` is the kind of entry (default `module_note`), so a module can log what a filter looks for (`sound`). */
1969
+ log(text: string, data?: Record<string, unknown>, type?: string): void;
1532
1970
  /**
1533
1971
  * Sets what the host lets a module tune on its tools, keyed by the id of the module's own control (`ModuleControl.id`) with the id of the option as the value; the tool in hand changes at once and the
1534
1972
  * ones taken later start that way. A host applies the ids it knows and ignores the rest. The test room knows `condition` (how worn the tools are) and `ammo_quality` (how good what they load is).
@@ -1539,6 +1977,11 @@ interface ModuleHost {
1539
1977
  * player stops at them; the function is asked on every step, so it may follow a door that opens. Returns the function that takes it away. A host without a walking player leaves it out.
1540
1978
  */
1541
1979
  addBlocker?(blocked: (x: number, z: number, radius: number) => boolean): () => void;
1980
+ /**
1981
+ * Lends the host the place of the hands for the tool in the module's hands (a weapon's grip and handguard): the host that draws the player's arms reads `source` every frame, after the
1982
+ * frame hooks have run, and puts the hands there. Pass null (or call the returned function) to let go. A host without arms leaves it out.
1983
+ */
1984
+ setHandTargets?(source: HandTargetSource | null): () => void;
1542
1985
  /** Asks the tool in hand to do something (see `ToolCommand`). A host without accessories leaves it out. */
1543
1986
  command?(command: ToolCommand): ToolCommandResult;
1544
1987
  /** Lent only to a module that declares controls, layers or metrics. */
@@ -1549,6 +1992,13 @@ interface ModuleHost {
1549
1992
  environment?: EnvironmentBus;
1550
1993
  /** The host's effects (smoke, sparks, blast, impacts): a module asks for them by id instead of drawing its own. Absent when the host has none. */
1551
1994
  effects?: EffectSink;
1995
+ /**
1996
+ * The numbers of the shove a blast gives to a body. A module that moves bodies of its own (people, vehicles) answers the `explosion` host event with `blastShove(event, body, host.blastShove)`
1997
+ * so that it throws things the way the host throws its loose items. Absent when the host keeps the defaults.
1998
+ */
1999
+ blastShove?: BlastShoveOptions;
2000
+ /** The host's loading indicator: a module with a slow job of its own (building a house, laying a district) shows it through this instead of freezing the page. Absent when the host has none. */
2001
+ loading?: BusySink;
1552
2002
  }
1553
2003
  /** What a module hands the test room: its items and, optionally, scenarios that exercise them, its area and its own presentation. */
1554
2004
  interface TestableModule<Context = unknown> {
@@ -1652,6 +2102,12 @@ interface ToolClipPlayer {
1652
2102
  apply(step: ToolAnimationStep): void;
1653
2103
  update(dt: number): void;
1654
2104
  readonly playing: readonly string[];
2105
+ /** The clips being played with the time each has reached and the clip itself (scaled to the duration the rule gave), for a renderer that has to follow what the clip does now (the hands working a part). */
2106
+ readonly running: ReadonlyArray<{
2107
+ readonly name: string;
2108
+ readonly time: number;
2109
+ readonly clip: AnimationClipSpec;
2110
+ }>;
1655
2111
  }
1656
2112
  declare const createToolClipPlayer: (options: ToolClipPlayerOptions) => ToolClipPlayer;
1657
2113
 
@@ -1670,4 +2126,97 @@ declare const mergeById: <TEntry extends Entry>(shipped: readonly TEntry[], extr
1670
2126
  declare const applyPatches: <TEntry extends Entry>(entries: Map<string, TEntry>, patches: Readonly<Record<string, DeepPartial<TEntry> | Partial<TEntry>>> | undefined) => void;
1671
2127
  declare const removeIds: (entries: Map<string, unknown>, ids: readonly string[] | undefined) => void;
1672
2128
 
1673
- export { type ActionControl, type AnimationClipSpec, type AnimationEventSpec, type AnimationKey, type AnimationPose, type AreaPlacement, type AudioListener, type AudioSink, type BenchChange, type BenchDeclaration, type BenchReport, type BenchSheet, type BlastOptions, type BlastReport, type BodyRegion, type BodySlot, type BooleanControl, type ChainDelay, type CheckOptions, type CheckSpecOptions, type ChoiceControl, type ChoiceOption, type ConfinementOptions, type ContainerSpec, type ControlPatch, type ControlValue, type Crack, DEFAULT_ENVIRONMENT, type DamageStage, type DamageType, type DebrisKind, type DeepPartial, type Dent, type DestructibleImpl, type DestructibleSpec, type DestructionEvent, type DestructionEventType, type EffectHandle, type EffectRequest, type EffectSink, type EnvironmentBus, type EnvironmentKey, type EnvironmentState, type ExplosionChain, type FluidKind, type FractureStyle, type Fragment, type FragmentHitOptions, type FragmentMark, type Hit, type HitResult, type Hole, type HostEvent, type HostTool, type HostToolAttachment, IMPACT_CONTRACT, type ImpactContract, type ItemAnimationContract, type ItemUseDef, type JointKind, type JointSpec, type JointState, type LiquidId, type LoopHandle, MISSING_BITS, type MaterialId, type ModuleArea, type ModuleBench, type ModuleControl, type ModuleHost, type ModuleItemFluid, type ModuleLayer, type ModuleMetric, type ModuleScenario, type NumberControl, type ObjectState, type PartBreach, type PartShape, type PartSpec, type PartState, type PartStatus, type PartUnits, type Quat, type RayHit, type Reinforcement, STAGE_EVENT, type SegmentKind, type ShelterOptions, type Shot, type SoundHandle, type SoundRequest, type SpecReport, type StructureRole, type SurfaceLayer, TOOL_CLIP, type TestableItem, type TestableModule, type Thumbnail, type ToolAnimationStep, type ToolAnimator, type ToolClipId, type ToolClipPlayer, type ToolClipPlayerOptions, type ToolClipSet, type ToolCommand, type ToolCommandResult, type ToolKind, type ToolRig, type Use, type Vec3, applyPatches, checkAnimation, checkBench, checkDestructible, checkHit, checkSpec, checkToolClips, createEnvironmentBus, createToolClipPlayer, deepMerge, mergeById, removeIds, sampleClip, scaleClip, shotToHit, toolAnimationStep };
2129
+ /** One category (kind) of items. Defaults and required contracts are inherited from the `extends` chain. */
2130
+ interface CategoryDef<TDefaults extends object = Record<string, unknown>> {
2131
+ readonly id: string;
2132
+ /** Parent category id; the child inherits its defaults and its required contracts. */
2133
+ readonly extends?: string;
2134
+ /** Field values every entry of this kind starts with; objects merge down the chain, arrays replace. */
2135
+ readonly defaults?: DeepPartial<TDefaults>;
2136
+ /** Contract ids (`ContractChecker.id`) every entry of this kind, or of a descendant, must satisfy. */
2137
+ readonly requires?: readonly string[];
2138
+ /** An abstract category only groups: entries cannot declare it directly, only its descendants. */
2139
+ readonly abstract?: boolean;
2140
+ }
2141
+ /** Where a checker is being run: the entry's kind and the chain of categories root first. */
2142
+ interface ContractContext {
2143
+ readonly kind: string;
2144
+ readonly chain: readonly string[];
2145
+ }
2146
+ /** A named contract: returns the problems of an entry, each a short phrase like `missing leftover.despawnSeconds`. Empty means it holds. */
2147
+ interface ContractChecker<TEntry> {
2148
+ readonly id: string;
2149
+ check(entry: TEntry, ctx: ContractContext): string[];
2150
+ }
2151
+ interface CategoryOptions {
2152
+ /** Categories added to the shipped ones; the same id replaces. */
2153
+ readonly extra?: readonly CategoryDef[];
2154
+ /** Partial changes by id, applied after `extra`. */
2155
+ readonly patches?: Readonly<Record<string, DeepPartial<CategoryDef> | Partial<CategoryDef>>>;
2156
+ /** Ids taken out of the tree (their children are then reported by `check()`). */
2157
+ readonly remove?: readonly string[];
2158
+ }
2159
+ interface CategoryRegistry {
2160
+ get(id: string): CategoryDef | undefined;
2161
+ has(id: string): boolean;
2162
+ ids(): string[];
2163
+ /** Root first, ending at `id`. Throws on an unknown id, an unknown parent or a cycle. */
2164
+ chain(id: string): string[];
2165
+ /** `defaults` merged along the chain, root first, so the closest category wins. */
2166
+ defaults(id: string): Record<string, unknown>;
2167
+ /** Union of `requires` along the chain, order kept, without duplicates. */
2168
+ requires(id: string): string[];
2169
+ /** True when `id` is `ancestorId` or descends from it. */
2170
+ isA(id: string, ancestorId: string): boolean;
2171
+ /** Problems in the tree itself: duplicate ids, unknown `extends`, cycles. */
2172
+ check(): string[];
2173
+ }
2174
+ interface CategorizedOptions {
2175
+ /** Field of the entry that names its category. Default `kind`. */
2176
+ readonly kindField?: string;
2177
+ /** Known gaps by entry id: problems starting with one of these texts go to `allowed`, so the list can shrink over time. */
2178
+ readonly allow?: Readonly<Record<string, readonly string[]>>;
2179
+ }
2180
+ interface CategorizedReport {
2181
+ readonly ok: boolean;
2182
+ readonly problems: string[];
2183
+ readonly allowed: string[];
2184
+ }
2185
+ declare const defineCategories: (defs: readonly CategoryDef[], options?: CategoryOptions) => CategoryRegistry;
2186
+ /** The entry with the defaults of its category underneath: the entry wins, objects merge, arrays replace. */
2187
+ declare const resolveEntry: <TEntry extends object>(registry: CategoryRegistry, entry: TEntry, kindField?: string) => TEntry;
2188
+ /** Checks that each entry has a known, concrete kind and satisfies every contract its chain requires. */
2189
+ declare const checkCategorized: <TEntry extends {
2190
+ readonly id: string;
2191
+ }>(entries: readonly TEntry[], registry: CategoryRegistry, checkers: readonly ContractChecker<TEntry>[], options?: CategorizedOptions) => CategorizedReport;
2192
+
2193
+ /**
2194
+ * Where a drawn object comes from. Every builder of the kit that draws a piece (a car of the fleet, a house or a wall, a piece of furniture, a person, an
2195
+ * animal, a plant, an item, a weapon) marks the root it returns, and every renderer that draws for the room (effects, debris, liquids, the room itself)
2196
+ * marks its own roots, so a host can tell a piece of the kit from something drawn on the spot. Duck-typed on three.js objects (`userData`, `parent`,
2197
+ * `children`), so the contracts stay free of three.js.
2198
+ */
2199
+ declare const KIT_ORIGIN_KEY = "kitOrigin";
2200
+ /** What drew an object: the package and the kind of piece (`vehicle`, `structure`, `furniture`, `person`... or `effect`, `room` for what is not a piece). */
2201
+ interface KitOrigin {
2202
+ readonly owner: string;
2203
+ readonly kind: string;
2204
+ /** The catalogue id of the piece, when it has one. */
2205
+ readonly id?: string;
2206
+ /** Drawn as a simple stand-in shape because the kit has no model of the piece yet (an item with no team model): a model still to make. */
2207
+ readonly standIn?: boolean;
2208
+ }
2209
+ /** Marks `object` as drawn by `origin.owner` and returns it. */
2210
+ declare function markKitOrigin<T>(object: T, origin: KitOrigin): T;
2211
+ /** The origin of the object or of its nearest marked ancestor; null when nothing up the tree is marked. */
2212
+ declare function kitOriginOf(object: unknown): KitOrigin | null;
2213
+ /** A drawn thing that no builder of the kit marked: what was drawn on the spot. */
2214
+ interface UnmarkedDrawing {
2215
+ /** The names of the object and its named ancestors, outermost first. */
2216
+ readonly path: string;
2217
+ readonly object: unknown;
2218
+ }
2219
+ /** Every visible mesh, line, point cloud or sprite under `root` with no marked ancestor (`root` itself not counted as one). */
2220
+ declare function unmarkedDrawings(root: unknown): UnmarkedDrawing[];
2221
+
2222
+ export { type ActionControl, type AnimationClipSpec, type AnimationEventSpec, type AnimationKey, type AnimationPose, type AreaPlacement, type AudioListener, type AudioSink, type BallisticExtras, type BenchChange, type BenchDeclaration, type BenchReport, type BenchSheet, type BlastOptions, type BlastReport, type BlastShove, type BlastShoveOptions, type BlastSource, type BodyRegion, type BodySlot, type BooleanControl, type BusyOptions, type BusySink, type BusyTask, type CategorizedOptions, type CategorizedReport, type CategoryDef, type CategoryOptions, type CategoryRegistry, type ChainDelay, type CheckOptions, type CheckSpecOptions, type ChoiceControl, type ChoiceOption, type ConfinementOptions, type ContainerSpec, type ContractChecker, type ContractContext, type ControlPatch, type ControlValue, type Crack, DEFAULT_BLAST_SHOVE, DEFAULT_ENVIRONMENT, DEFAULT_IGNITION_RULES, type DamageStage, type DamageType, type DebrisKind, type DeepPartial, type Dent, type DestructibleImpl, type DestructibleSpec, type DestructionEvent, type DestructionEventType, type EffectHandle, type EffectRequest, type EffectSink, type EnvironmentBus, type EnvironmentKey, type EnvironmentState, type ExplosionChain, type FluidKind, type FractureStyle, type Fragment, type FragmentHitOptions, type FragmentMark, type HandPose, type HandTargetSource, type HandTargets, type Hit, type HitIgnition, type HitResult, type Hole, type HostEvent, type HostTool, type HostToolAttachment, IMPACT_CONTRACT, type IgnitionRules, type ImpactContract, type ItemAnimationContract, type ItemUseDef, type JointKind, type JointSpec, type JointState, KIT_ORIGIN_KEY, type KitOrigin, type LiquidId, type LoopHandle, MISSING_BITS, type MaterialId, type ModuleArea, type ModuleBench, type ModuleControl, type ModuleHost, type ModuleItemFluid, type ModuleLayer, type ModuleMetric, type ModuleScenario, type NumberControl, type ObjectState, type PartBreach, type PartShape, type PartSpec, type PartState, type PartStatus, type PartUnits, type PileSpec, type PlayerState, type Quat, type RayHit, type Reinforcement, STAGE_EVENT, type SegmentKind, type ShelterOptions, type Shot, type SoilLayer, type SoilProfile, type SoilState, type SoundHandle, type SoundRequest, type SpecReport, type StructureRole, type SurfaceLayer, TOOL_CLIP, type TensionRebar, type TestableItem, type TestableModule, type Thumbnail, type ToolAnimationStep, type ToolAnimator, type ToolClipId, type ToolClipPlayer, type ToolClipPlayerOptions, type ToolClipSet, type ToolCommand, type ToolCommandResult, type ToolKind, type ToolRig, type TunedMassDamper, type UnmarkedDrawing, type Use, type Vec3, type WarmUpProbes, type WindExposure, type WindState, applyPatches, blastShove, checkAnimation, checkBench, checkCategorized, checkDestructible, checkHit, checkSpec, checkToolClips, createEnvironmentBus, createToolClipPlayer, deepMerge, defineCategories, fillFactor, ignitionChance, kitOriginOf, markKitOrigin, mergeById, removeIds, resolveEntry, resolveIgnitionRules, sampleClip, scaleClip, shotExtras, shotToHit, sparkTargetFactor, toolAnimationStep, unmarkedDrawings, useToHit };