@adatechnology/game-contracts 0.3.0 → 0.5.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/README.md CHANGED
@@ -100,6 +100,27 @@ room.loadModule(RENTAL_CARS) // items join the catalogue, scenarios become butto
100
100
  `build` receives the host's three.js namespace and returns its `Object3D` (both are `unknown` here: this package has no dependency on three.js).
101
101
  `impl` receives the object id the host gives the item and `DestructibleImpl.id` must equal it.
102
102
 
103
+ ### A bench for the module
104
+
105
+ A module can also declare a bench as data: `controls` (number, boolean, choice, action), `layers` (things the viewer turns on or off) and
106
+ `metrics` (counters the host pulls with `read()` a few times a second). The host keeps the values, draws them, and lends the module a
107
+ `ModuleBench` in `attach` (`host.bench`): `value(id)`, `layer(id)`, `onChange(listener)` (right after `attach` it gets one change per control and
108
+ layer, in order), `patch(id, { hidden, disabled, options, value })` (no echo) and `look(eye, target)`. `checkBench({ controls, layers, metrics })`
109
+ checks the declaration (snake_case ids unique across the three, `min < max`, `step > 0`, defaults in range and among the options, `max > 0`).
110
+
111
+ ```ts
112
+ controls: () => [
113
+ { kind: 'choice', id: 'distance', name: 'Distance', options: [{ id: 'near', name: 'Near' }, { id: 'far', name: 'Far' }], default: 'near' },
114
+ { kind: 'action', id: 'replay', name: 'Replay' },
115
+ ],
116
+ layers: () => [{ id: 'smoke', name: 'Smoke' }],
117
+ metrics: () => [{ id: 'particles', name: 'Particles', max: 400, read: () => fx.particles }],
118
+ ```
119
+
120
+ Tool events are named after a tool's cycle, not a firearm: `mode`, `fault`, `clear` (start / end) and `safety`, and `shot` carries `rounds`
121
+ (cartridges spent) next to `shots` (projectiles, always 1 or more) and the `mode`; a dud round is its own `misfire` event, not a `shot` of zero. `HostTool` may report `mode`, `fault`, `safety` and `heat` (0..1).
122
+ `host.configureTool(settings)` takes a `Record<string, string>` keyed by the id of the module's own control; the test room applies `condition` and `ammo_quality` and ignores other ids.
123
+
103
124
  ## API
104
125
 
105
126
  Everything is exported from the package root; see `src/*.ts` for the doc comments. Units: metres, seconds, joules, millimetres (calibre), degrees Celsius.
@@ -119,3 +140,5 @@ antes definiam, então `import { Hit } from '@adatechnology/game-destruction'` c
119
140
  - **Animações**: `AnimationClipSpec` e `checkAnimation(clipe, idsDasPeças)` (uma porta `open`, uma pistola `reload`).
120
141
  - **Módulo**: `TestableModule` entrega itens, animações e cenários à sala de testes; `room.loadModule(modulo)` roda as verificações e escreve linhas
121
142
  ✓ / ✗ no log. Assim o módulo de um carro de aluguel já nasce com as suas animações e o seu jeito de quebrar.
143
+ - **Bancada**: o módulo declara `controls`, `layers` e `metrics` como dados; a sala guarda os valores, desenha e empresta `host.bench`
144
+ (`ModuleBench`). `checkBench` valida a declaração. Eventos de ciclo da ferramenta: `mode`, `fault`, `clear`, `safety`, e `rounds` no `shot`.
package/dist/index.d.ts CHANGED
@@ -37,6 +37,16 @@ type PartShape = {
37
37
  radius: number;
38
38
  };
39
39
  type FluidKind = 'water' | 'fuel' | 'oil' | 'gas' | 'sap' | 'acid' | 'blood' | string;
40
+ /** Seconds from a trigger to the blast: fixed, or `[min, max]` drawn from the world seed. */
41
+ type ChainDelay = number | readonly [number, number];
42
+ /** How an explosive part is set off by what happens around it. See `PartSpec.explodes`. */
43
+ interface ExplosionChain {
44
+ shot?: ChainDelay;
45
+ fire?: ChainDelay;
46
+ explosion?: ChainDelay;
47
+ /** Fraction of the part's hit points a shot must have taken off before it sets the part off (default 0: any hit). */
48
+ shotDamageFraction?: number;
49
+ }
40
50
  interface PartSpec {
41
51
  /** Unique inside the object. */
42
52
  id: string;
@@ -67,6 +77,12 @@ interface PartSpec {
67
77
  energy: number;
68
78
  radius: number;
69
79
  atC?: number;
80
+ /**
81
+ * 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
82
+ * from the world seed). `shot`: a bullet hit; `fire`: the part gets to `atC` (default 300 °C) or burns; `explosion`: a blast reaches it.
83
+ * Each part goes off once. Without `chain`, it explodes only when destroyed (or at `atC`).
84
+ */
85
+ chain?: ExplosionChain;
70
86
  };
71
87
  /** Fixed to the world (a wall-mounted cabinet, a tree trunk in the ground). Groups that keep an anchored part stay in place. */
72
88
  anchored?: boolean;
@@ -360,6 +376,14 @@ type DestructionEvent = (EventBase & {
360
376
  energy: number;
361
377
  radius: number;
362
378
  })
379
+ /** An explosive part was set off by a bullet, fire or a nearby blast and will explode `delay` seconds from now (`explodes.chain`). */
380
+ | (EventBase & {
381
+ type: 'primed';
382
+ part: string;
383
+ point: Vec3;
384
+ trigger: 'shot' | 'fire' | 'explosion';
385
+ delay: number;
386
+ })
363
387
  /** A structural part is overloaded (`stress` > 1); throttled to once per 0.5 s per part. Brittle parts also `crack` at stress > 0.8. */
364
388
  | (EventBase & {
365
389
  type: 'stress';
@@ -532,6 +556,53 @@ type Use = {
532
556
  radius: number;
533
557
  seconds: number;
534
558
  };
559
+ /** Explosive id (`m67`, `molotov`, `pg7v`...): the host looks the numbers up in the arsenal. Absent on a plain thrown object. */
560
+ explosive?: string;
561
+ /** What sets it off: `timer` after `fuse` seconds, `impact` on the first hit once armed. */
562
+ trigger?: 'timer' | 'impact';
563
+ /** Metres the projectile must fly before an impact sets it off; closer, it hits without exploding (rocket launchers). */
564
+ armDistance?: number;
565
+ /** Radius in metres of the wounding area (`radius` is the lethal one). */
566
+ injuryRadius?: number;
567
+ /** Seconds the blast stuns whoever is inside the injury radius (flashbang). */
568
+ stunSeconds?: number;
569
+ /** Seconds the thrower held it after pulling the pin: `fuse` is what was left of the full fuse when it left the hand. */
570
+ cooked?: number;
571
+ /** Went off in the thrower's hand (held past the fuse): no velocity, `fuse` is 0 and the blast is at `origin`. */
572
+ inHand?: boolean;
573
+ }
574
+ /** An explosive set down where the trigger is pulled (mine, C4, charge): it waits for its trigger instead of flying. */
575
+ | {
576
+ kind: 'place';
577
+ explosive: string;
578
+ /** `wire`: something trips it; `remote`: the player fires it; `timer`: after `fuse` seconds. */
579
+ triggers: readonly ('timer' | 'wire' | 'remote')[];
580
+ energy: number;
581
+ /** Lethal radius in metres. */
582
+ radius: number;
583
+ injuryRadius: number;
584
+ /** Cone the blast goes through, in front of `direction` (mine); absent for a blast in every direction. */
585
+ cone?: {
586
+ halfAngleDeg: number;
587
+ length: number;
588
+ };
589
+ /** The wire a `wire` charge stretches from where it is set down: metres out, degrees from its facing (counter-clockwise from above) and metres above it. */
590
+ tripwire?: {
591
+ length: number;
592
+ angleDeg: number;
593
+ height: number;
594
+ };
595
+ fuse?: number;
596
+ origin: Vec3;
597
+ direction: Vec3;
598
+ }
599
+ /** The blast behind a rocket launcher: dangerous inside `radius` metres, in the cone around `direction` (pointing away from the target). */
600
+ | {
601
+ kind: 'backblast';
602
+ radius: number;
603
+ halfAngleDeg: number;
604
+ origin: Vec3;
605
+ direction: Vec3;
535
606
  } | {
536
607
  kind: 'tool';
537
608
  tool: string;
@@ -656,6 +727,103 @@ declare const checkAnimation: (clip: AnimationClipSpec, partIds: Iterable<string
656
727
  problems: string[];
657
728
  };
658
729
 
730
+ /**
731
+ * 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
732
+ * every change back through `ModuleHost.bench`. Nothing here is specific to a kind of module.
733
+ */
734
+ type ControlValue = number | boolean | string;
735
+ interface ChoiceOption {
736
+ readonly id: string;
737
+ readonly name: string;
738
+ }
739
+ interface ControlBase {
740
+ /** snake_case, unique across the module's controls, layers and metrics. */
741
+ readonly id: string;
742
+ /** Display name, already translated for the locale the host asked for. */
743
+ readonly name: string;
744
+ readonly hint?: string;
745
+ readonly hidden?: boolean;
746
+ }
747
+ interface NumberControl extends ControlBase {
748
+ readonly kind: 'number';
749
+ readonly min: number;
750
+ readonly max: number;
751
+ readonly step?: number;
752
+ readonly unit?: string;
753
+ readonly default: number;
754
+ }
755
+ interface BooleanControl extends ControlBase {
756
+ readonly kind: 'boolean';
757
+ readonly default: boolean;
758
+ }
759
+ interface ChoiceControl extends ControlBase {
760
+ readonly kind: 'choice';
761
+ readonly options: readonly ChoiceOption[];
762
+ readonly default: string;
763
+ }
764
+ /** A button: no value, only the press. */
765
+ interface ActionControl extends ControlBase {
766
+ readonly kind: 'action';
767
+ }
768
+ type ModuleControl = NumberControl | BooleanControl | ChoiceControl | ActionControl;
769
+ /** Something of the module the viewer turns on or off (smoke, flash, casings). */
770
+ interface ModuleLayer {
771
+ readonly id: string;
772
+ readonly name: string;
773
+ /** On unless `false`. */
774
+ readonly default?: boolean;
775
+ }
776
+ /** Pulled: the room calls read only when it samples (~4 Hz, or on TestRoom.metrics()). */
777
+ interface ModuleMetric {
778
+ readonly id: string;
779
+ readonly name: string;
780
+ readonly unit?: string;
781
+ /** Budget: the host shows a bar and warns past it. */
782
+ readonly max?: number;
783
+ readonly digits?: number;
784
+ read(): number | string;
785
+ }
786
+ type BenchChange = {
787
+ readonly kind: 'control';
788
+ readonly id: string;
789
+ readonly value: ControlValue;
790
+ } | {
791
+ readonly kind: 'layer';
792
+ readonly id: string;
793
+ readonly on: boolean;
794
+ } | {
795
+ readonly kind: 'action';
796
+ readonly id: string;
797
+ };
798
+ interface ControlPatch {
799
+ readonly hidden?: boolean;
800
+ readonly disabled?: boolean;
801
+ readonly options?: readonly ChoiceOption[];
802
+ readonly value?: ControlValue;
803
+ }
804
+ /** What the host lends a module that declares a bench: the current values and the changes. */
805
+ interface ModuleBench {
806
+ value(id: string): ControlValue | undefined;
807
+ layer(id: string): boolean;
808
+ /** Right after attach returns, the host sends one change per control (not actions) and per layer, in declaration order. */
809
+ onChange(listener: (change: BenchChange) => void): () => void;
810
+ /** `value` sets without emitting (no echo loops); `options` falls back to the first option if the value is no longer offered. */
811
+ patch(id: string, patch: ControlPatch): void;
812
+ /** Move the host camera (a near / middle / far choice). */
813
+ look(eye: Vec3, target: Vec3): void;
814
+ }
815
+ interface BenchReport {
816
+ readonly ok: boolean;
817
+ readonly problems: readonly string[];
818
+ }
819
+ interface BenchDeclaration {
820
+ readonly controls?: readonly ModuleControl[];
821
+ readonly layers?: readonly ModuleLayer[];
822
+ readonly metrics?: readonly ModuleMetric[];
823
+ }
824
+ /** snake_case ids unique across controls, layers and metrics; min < max; step > 0; default in range; options non-empty, unique, default among them; metric max > 0. */
825
+ declare function checkBench(declared: BenchDeclaration): BenchReport;
826
+
659
827
  /** An item that holds a liquid (a cup, a bottle, a fuel tank). `part` is the destruction part that is the container; a hole in it makes it leak. */
660
828
  interface ModuleItemFluid {
661
829
  container: ContainerSpec;
@@ -716,22 +884,96 @@ interface ModuleArea {
716
884
  target: Vec3;
717
885
  };
718
886
  }
719
- /** What the player did with the tool in hand, as the host reports it. Hosts emit what they support; modules ignore what they do not need. */
720
- type HostEvent = {
887
+ /**
888
+ * What the player did with the tool in hand, as the host reports it. Hosts emit what they support; modules ignore what they do not need. The
889
+ * names are of a tool's cycle, not of a firearm: a nail gun, a chainsaw or a hose has modes, faults and a safety too.
890
+ */
891
+ type HostEvent =
892
+ /** The tool is put in hand; `duration` is the seconds the rule takes to ready it (absent: no draw time). */
893
+ {
721
894
  type: 'tool';
722
895
  weapon: string;
723
- } | {
896
+ duration?: number;
897
+ }
898
+ /** `shots` are projectiles (a shotgun shell is many), `rounds` the cartridges spent (a burst is several). */
899
+ | {
724
900
  type: 'shot';
725
901
  weapon: string;
726
902
  shots: number;
727
903
  recoil: [number, number];
728
- } | {
904
+ rounds?: number;
905
+ mode?: string;
906
+ }
907
+ /** The trigger was pulled, the round was spent and nothing left the tool (a dud cartridge): no projectile, no recoil. */
908
+ | {
909
+ type: 'misfire';
910
+ weapon: string;
911
+ }
912
+ /** `kind` is how the rule reloads (`tactical`, `empty`, `one_by_one`); `duration` the seconds of the whole reload, on `start`. */
913
+ | {
729
914
  type: 'reload';
730
915
  weapon: string;
731
916
  phase: 'start' | 'end';
917
+ kind?: string;
918
+ duration?: number;
732
919
  } | {
733
920
  type: 'empty';
734
921
  weapon: string;
922
+ } | {
923
+ type: 'mode';
924
+ weapon: string;
925
+ mode: string;
926
+ } | {
927
+ type: 'fault';
928
+ weapon: string;
929
+ fault: string;
930
+ } | {
931
+ type: 'clear';
932
+ weapon: string;
933
+ fault: string;
934
+ phase: 'start' | 'end';
935
+ duration?: number;
936
+ } | {
937
+ type: 'safety';
938
+ weapon: string;
939
+ on: boolean;
940
+ }
941
+ /** The action works between shots (a pump, a bolt); `duration` is the seconds of the cycle, on `start`. */
942
+ | {
943
+ type: 'cycle';
944
+ weapon: string;
945
+ phase: 'start' | 'end';
946
+ duration?: number;
947
+ }
948
+ /** A step of a longer phase (a reload's magazine out, magazine in, charge), at the moment the rule reaches it. */
949
+ | {
950
+ type: 'stage';
951
+ weapon: string;
952
+ stage: string;
953
+ }
954
+ /** One more round went into the tool while it loads round by round. */
955
+ | {
956
+ type: 'feed';
957
+ weapon: string;
958
+ }
959
+ /**
960
+ * A throwable with a timer fuse is cooked: the trigger pulls the pin (`start`, `fuse` is the whole fuse), releasing throws it with what is left of
961
+ * the fuse (`throw`), and holding past the fuse sets it off in the hand (`burst`, `fuse` 0).
962
+ */
963
+ | {
964
+ type: 'cook';
965
+ weapon: string;
966
+ phase: 'start' | 'throw' | 'burst';
967
+ fuse: number;
968
+ }
969
+ /** Something blew up: a thrown or launched explosive, a charge, or a part of the world (a fuel barrel); `source` is the weapon or the object, `cause` what set it off. */
970
+ | {
971
+ type: 'explosion';
972
+ source: string;
973
+ point: Vec3;
974
+ energy: number;
975
+ radius: number;
976
+ cause: string;
735
977
  };
736
978
  /** The tool in hand as the host sees it. */
737
979
  interface HostTool {
@@ -741,6 +983,12 @@ interface HostTool {
741
983
  capacity: number;
742
984
  reserve: number;
743
985
  reloading: boolean;
986
+ mode?: string;
987
+ /** The fault the tool is stuck with, if any. */
988
+ fault?: string;
989
+ safety?: boolean;
990
+ /** 0..1 */
991
+ heat?: number;
744
992
  }
745
993
  /**
746
994
  * What the host lends a module that brings its own presentation (a weapon in the hands, sounds, ejected casings). `THREE`, `scene` and `camera`
@@ -760,6 +1008,13 @@ interface ModuleHost {
760
1008
  onFrame(update: (dt: number) => void): () => void;
761
1009
  /** Write a line to the host's behaviour log. */
762
1010
  log(text: string, data?: Record<string, unknown>): void;
1011
+ /**
1012
+ * 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
1013
+ * 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).
1014
+ */
1015
+ configureTool?(settings: Readonly<Record<string, string>>): void;
1016
+ /** Lent only to a module that declares controls, layers or metrics. */
1017
+ bench?: ModuleBench;
763
1018
  }
764
1019
  /** What a module hands the test room: its items and, optionally, scenarios that exercise them, its area and its own presentation. */
765
1020
  interface TestableModule<Context = unknown> {
@@ -772,8 +1027,94 @@ interface TestableModule<Context = unknown> {
772
1027
  scenarios?(locale: string): Array<ModuleScenario<Context>>;
773
1028
  /** How to set the area up when the host opens the module's group. Without it the host lays the items in rows. */
774
1029
  area?(locale: string): ModuleArea;
1030
+ /** The bench: what the viewer can set (controls), turn on or off (layers) and watch (metrics). Names already translated for `locale`. */
1031
+ controls?(locale: string): ModuleControl[];
1032
+ layers?(locale: string): ModuleLayer[];
1033
+ metrics?(locale: string): ModuleMetric[];
775
1034
  /** Called once when the module is loaded, with what the host lends. Returns the function that undoes it. */
776
1035
  attach?(host: ModuleHost): () => void;
777
1036
  }
778
1037
 
779
- export { type AnimationClipSpec, type AnimationEventSpec, type AnimationKey, type AnimationPose, type AreaPlacement, type CheckOptions, type CheckSpecOptions, type ContainerSpec, type Crack, type DamageType, type DebrisKind, type Dent, type DestructibleImpl, type DestructibleSpec, type DestructionEvent, type DestructionEventType, type FluidKind, type FractureStyle, type Fragment, type Hit, type HitResult, type Hole, type HostEvent, type HostTool, IMPACT_CONTRACT, type ImpactContract, type ItemAnimationContract, type ItemUseDef, type JointKind, type JointSpec, type JointState, type LiquidId, type MaterialId, type ModuleArea, type ModuleHost, type ModuleItemFluid, type ModuleScenario, type ObjectState, type PartShape, type PartSpec, type PartState, type PartStatus, type Quat, type RayHit, type Shot, type SpecReport, type StructureRole, type TestableItem, type TestableModule, type ToolKind, type Use, type Vec3, checkAnimation, checkDestructible, checkHit, checkSpec, shotToHit };
1038
+ /** Clips a tool can bring, one per move of its cycle. A tool brings the ones it has; a missing clip is simply not played. */
1039
+ declare const TOOL_CLIP: {
1040
+ readonly DRAW: "draw";
1041
+ readonly SHOT: "shot";
1042
+ readonly MISFIRE: "misfire";
1043
+ readonly EMPTY: "empty";
1044
+ readonly CYCLE: "cycle";
1045
+ readonly RELOAD: "reload";
1046
+ readonly FEED: "feed";
1047
+ readonly FAULT: "fault";
1048
+ readonly CLEAR: "clear";
1049
+ readonly SAFETY_ON: "safety_on";
1050
+ readonly SAFETY_OFF: "safety_off";
1051
+ readonly MODE: "mode";
1052
+ /** A throwable with the pin out, held until it is thrown. */
1053
+ readonly COOK: "cook";
1054
+ };
1055
+ type ToolClipId = (typeof TOOL_CLIP)[keyof typeof TOOL_CLIP];
1056
+ /** What a renderer does when a rule event arrives. `variant` picks `<clip>_<variant>` when the tool has it, else `<clip>`. */
1057
+ type ToolAnimationStep = {
1058
+ readonly type: 'play';
1059
+ readonly clip: ToolClipId;
1060
+ readonly variant?: string;
1061
+ readonly duration?: number;
1062
+ readonly repeat?: number;
1063
+ }
1064
+ /** Move the clip that is playing to the marker (a clip event `stage` with `data.stage`) the rule just reached. */
1065
+ | {
1066
+ readonly type: 'sync';
1067
+ readonly stage: string;
1068
+ }
1069
+ /** The rule says the phase is over: the clip jumps to its end if it is still running. */
1070
+ | {
1071
+ readonly type: 'finish';
1072
+ readonly clip: ToolClipId;
1073
+ };
1074
+ /** The move a host event asks of the tool in hand, or null when it has no motion. */
1075
+ declare const toolAnimationStep: (event: HostEvent) => ToolAnimationStep | null;
1076
+ /** Where a renderer puts the poses: every part of the tool by id (the ids the clips move), and the whole tool. Poses are offsets from rest. */
1077
+ interface ToolRig {
1078
+ setPartPose(partId: string, pose: AnimationPose): void;
1079
+ setRootPose?(pose: AnimationPose): void;
1080
+ }
1081
+ /** Clips by id, with the variants as `<clip>_<variant>`. */
1082
+ type ToolClipSet = Readonly<Record<string, AnimationClipSpec>>;
1083
+ /** A renderer's tool animator: feed it the host events and the frame time. */
1084
+ interface ToolAnimator {
1085
+ handle(event: HostEvent): void;
1086
+ update(dt: number): void;
1087
+ /** Ids of the clips playing now. */
1088
+ readonly playing: readonly string[];
1089
+ dispose(): void;
1090
+ }
1091
+ declare const STAGE_EVENT = "stage";
1092
+ /** The clip with its times (keys and events) scaled so that it lasts `duration` seconds. */
1093
+ declare const scaleClip: (clip: AnimationClipSpec, duration: number) => AnimationClipSpec;
1094
+ /** Pose of the whole tool (`partId` undefined) or of one part at `time`, linear between keys; a key that does not name it means rest. */
1095
+ declare const sampleClip: (clip: AnimationClipSpec, partId: string | undefined, time: number) => {
1096
+ position: [number, number, number];
1097
+ rotation: [number, number, number];
1098
+ };
1099
+ /** Problems with a clip set (empty when valid): each key is the clip id (or `<clip>_<variant>`), every clip passes `checkAnimation`, and a `stage` event names its stage. */
1100
+ declare const checkToolClips: (clips: ToolClipSet, partIds: Iterable<string>) => {
1101
+ ok: boolean;
1102
+ problems: string[];
1103
+ };
1104
+ interface ToolClipPlayerOptions {
1105
+ clips: ToolClipSet;
1106
+ rig: ToolRig;
1107
+ /** Called for each clip event as its time passes (`eject_casing`, `drop_magazine`, `stage`...). */
1108
+ onEvent?(event: AnimationEventSpec, clip: string): void;
1109
+ /** Seconds between the rounds of a `repeat` (a burst): default 0.1. */
1110
+ repeatInterval?(): number;
1111
+ }
1112
+ /** The default player of a tool's clips: runs the steps of `toolAnimationStep` against a rig, scaled to the duration the rule gives. */
1113
+ interface ToolClipPlayer {
1114
+ apply(step: ToolAnimationStep): void;
1115
+ update(dt: number): void;
1116
+ readonly playing: readonly string[];
1117
+ }
1118
+ declare const createToolClipPlayer: (options: ToolClipPlayerOptions) => ToolClipPlayer;
1119
+
1120
+ export { type ActionControl, type AnimationClipSpec, type AnimationEventSpec, type AnimationKey, type AnimationPose, type AreaPlacement, type BenchChange, type BenchDeclaration, type BenchReport, type BooleanControl, type ChainDelay, type CheckOptions, type CheckSpecOptions, type ChoiceControl, type ChoiceOption, type ContainerSpec, type ControlPatch, type ControlValue, type Crack, type DamageType, type DebrisKind, type Dent, type DestructibleImpl, type DestructibleSpec, type DestructionEvent, type DestructionEventType, type ExplosionChain, type FluidKind, type FractureStyle, type Fragment, type Hit, type HitResult, type Hole, type HostEvent, type HostTool, IMPACT_CONTRACT, type ImpactContract, type ItemAnimationContract, type ItemUseDef, type JointKind, type JointSpec, type JointState, type LiquidId, type MaterialId, type ModuleArea, type ModuleBench, type ModuleControl, type ModuleHost, type ModuleItemFluid, type ModuleLayer, type ModuleMetric, type ModuleScenario, type NumberControl, type ObjectState, type PartShape, type PartSpec, type PartState, type PartStatus, type Quat, type RayHit, STAGE_EVENT, type Shot, type SpecReport, type StructureRole, TOOL_CLIP, type TestableItem, type TestableModule, type ToolAnimationStep, type ToolAnimator, type ToolClipId, type ToolClipPlayer, type ToolClipPlayerOptions, type ToolClipSet, type ToolKind, type ToolRig, type Use, type Vec3, checkAnimation, checkBench, checkDestructible, checkHit, checkSpec, checkToolClips, createToolClipPlayer, sampleClip, scaleClip, shotToHit, toolAnimationStep };