@defold-typescript/types 0.50.1 → 0.51.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.
Files changed (88) hide show
  1. package/api-signatures.json +286 -232
  2. package/examples/translations.json +15 -15
  3. package/fixtures/messages_doc.json +20 -39
  4. package/generated/builtin-messages.d.ts +16 -14
  5. package/generated/collectionfactory.d.ts +1 -1
  6. package/generated/collectionproxy.d.ts +2 -2
  7. package/generated/factory.d.ts +4 -2
  8. package/generated/graphics.d.ts +4 -0
  9. package/generated/gui.d.ts +2 -2
  10. package/generated/http.d.ts +3 -1
  11. package/generated/image.d.ts +1 -1
  12. package/generated/kinds/gui-script.d.ts +1 -0
  13. package/generated/kinds/render-script.d.ts +1 -0
  14. package/generated/kinds/script.d.ts +1 -0
  15. package/generated/model.d.ts +4 -5
  16. package/generated/physics.d.ts +3 -3
  17. package/generated/render.d.ts +41 -13
  18. package/generated/sys.d.ts +8 -4
  19. package/generated/tilemap.d.ts +4 -4
  20. package/generated/versions/defold-1.12.4/collectionfactory.d.ts +1 -1
  21. package/generated/versions/defold-1.12.4/collectionproxy.d.ts +1 -1
  22. package/generated/versions/defold-1.12.4/factory.d.ts +4 -2
  23. package/generated/versions/defold-1.12.4/gui.d.ts +2 -2
  24. package/generated/versions/defold-1.12.4/http.d.ts +3 -1
  25. package/generated/versions/defold-1.12.4/image.d.ts +1 -1
  26. package/generated/versions/defold-1.12.4/index.d.ts +1 -0
  27. package/generated/versions/defold-1.12.4/model.d.ts +4 -5
  28. package/generated/versions/defold-1.12.4/physics.d.ts +2 -2
  29. package/generated/versions/defold-1.12.4/render.d.ts +41 -13
  30. package/generated/versions/defold-1.12.4/sys.d.ts +1 -1
  31. package/generated/versions/defold-1.12.4/tilemap.d.ts +4 -4
  32. package/generated/versions/defold-1.13.0/collectionfactory.d.ts +1 -1
  33. package/generated/versions/defold-1.13.0/collectionproxy.d.ts +1 -1
  34. package/generated/versions/defold-1.13.0/factory.d.ts +4 -2
  35. package/generated/versions/defold-1.13.0/gui.d.ts +2 -2
  36. package/generated/versions/defold-1.13.0/http.d.ts +3 -1
  37. package/generated/versions/defold-1.13.0/image.d.ts +1 -1
  38. package/generated/versions/defold-1.13.0/index.d.ts +1 -0
  39. package/generated/versions/defold-1.13.0/model.d.ts +4 -5
  40. package/generated/versions/defold-1.13.0/physics.d.ts +2 -2
  41. package/generated/versions/defold-1.13.0/render.d.ts +41 -13
  42. package/generated/versions/defold-1.13.0/sys.d.ts +1 -1
  43. package/generated/versions/defold-1.13.0/tilemap.d.ts +4 -4
  44. package/generated/versions/defold-1.13.1/collectionfactory.d.ts +1 -1
  45. package/generated/versions/defold-1.13.1/collectionproxy.d.ts +1 -1
  46. package/generated/versions/defold-1.13.1/factory.d.ts +4 -2
  47. package/generated/versions/defold-1.13.1/gui.d.ts +2 -2
  48. package/generated/versions/defold-1.13.1/http.d.ts +3 -1
  49. package/generated/versions/defold-1.13.1/image.d.ts +1 -1
  50. package/generated/versions/defold-1.13.1/index.d.ts +1 -0
  51. package/generated/versions/defold-1.13.1/model.d.ts +4 -5
  52. package/generated/versions/defold-1.13.1/physics.d.ts +2 -2
  53. package/generated/versions/defold-1.13.1/render.d.ts +41 -13
  54. package/generated/versions/defold-1.13.1/sys.d.ts +1 -1
  55. package/generated/versions/defold-1.13.1/tilemap.d.ts +4 -4
  56. package/generated/versions/defold-1.13.2/collectionfactory.d.ts +1 -1
  57. package/generated/versions/defold-1.13.2/collectionproxy.d.ts +2 -2
  58. package/generated/versions/defold-1.13.2/factory.d.ts +4 -2
  59. package/generated/versions/defold-1.13.2/gui.d.ts +2 -2
  60. package/generated/versions/defold-1.13.2/http.d.ts +3 -1
  61. package/generated/versions/defold-1.13.2/image.d.ts +1 -1
  62. package/generated/versions/defold-1.13.2/index.d.ts +1 -0
  63. package/generated/versions/defold-1.13.2/model.d.ts +4 -5
  64. package/generated/versions/defold-1.13.2/physics.d.ts +3 -3
  65. package/generated/versions/defold-1.13.2/render.d.ts +41 -13
  66. package/generated/versions/defold-1.13.2/sys.d.ts +8 -4
  67. package/generated/versions/defold-1.13.2/tilemap.d.ts +4 -4
  68. package/generated/versions/defold-1.13.2/window.d.ts +1 -1
  69. package/generated/window.d.ts +1 -1
  70. package/identity-vocabulary.json +46 -0
  71. package/index.d.ts +1 -0
  72. package/package.json +2 -1
  73. package/scripts/generate-api-availability.ts +5 -1
  74. package/scripts/generate-api-signatures.ts +16 -11
  75. package/scripts/materialize-version.ts +7 -1
  76. package/scripts/regen.ts +42 -25
  77. package/src/component-properties.d.ts +137 -6
  78. package/src/core-types.ts +46 -11
  79. package/src/emit-dts.ts +555 -84
  80. package/src/emit-messages.ts +289 -0
  81. package/src/engine-globals.d.ts +3 -1
  82. package/src/go-overloads.d.ts +13 -3
  83. package/src/lifecycle.ts +16 -16
  84. package/src/luals-type-expr.ts +6 -1
  85. package/src/physics-event-guard.d.ts +39 -0
  86. package/src/render-overloads.d.ts +2 -2
  87. package/src/return-correction-provenance.ts +36 -6
  88. package/src/window-event-guard.d.ts +5 -3
@@ -161,7 +161,7 @@ declare global {
161
161
  * });
162
162
  * ```
163
163
  */
164
- function set_listener(callback: ((self: unknown, event: (typeof window)[Extract<keyof typeof window, `WINDOW_EVENT_${string}`>], data: Record<string | number, unknown>) => void) | undefined): void;
164
+ function set_listener(callback: ((self: unknown, event: (typeof window)[Extract<keyof typeof window, `WINDOW_EVENT_${string}`>], data: window.event_data) => void) | undefined): void;
165
165
  /**
166
166
  * Set the locking state for current mouse cursor on a PC platform.
167
167
  * This function locks or unlocks the mouse cursor to the center point of the window. While the cursor is locked,
@@ -539,11 +539,48 @@
539
539
  "undefined"
540
540
  ]
541
541
  },
542
+ "collectionfactory.create": {
543
+ "pins": [["table"], ["table<hash, hash>"]],
544
+ "replaces": ["LuaTable<Hash, Hash> & { get: LuaTableGetMethod<string, Hash> }"]
545
+ },
546
+ "collectionproxy.set_collection": {
547
+ "pins": [["number"], ["collectionproxy.RESULT"]],
548
+ "adds": ["nil"],
549
+ "slot": "code"
550
+ },
551
+ "factory.create": { "pins": [["hash"]], "adds": ["nil"] },
552
+ "gui.clone_tree": {
553
+ "pins": [["table"], ["table<hash, node>"]],
554
+ "replaces": [
555
+ "LuaTable<Hash, Opaque<\"node\">> & { get: LuaTableGetMethod<string, Opaque<\"node\">> }"
556
+ ]
557
+ },
558
+ "gui.get_tree": {
559
+ "pins": [["table"], ["table<hash, node>"]],
560
+ "replaces": [
561
+ "LuaTable<Hash, Opaque<\"node\">> & { get: LuaTableGetMethod<string, Opaque<\"node\">> }"
562
+ ]
563
+ },
542
564
  "gui.new_texture": {
543
565
  "pins": [["number"]],
544
566
  "replaces": ["number", "undefined"],
545
567
  "slot": "code"
546
568
  },
569
+ "image.get_astc_header": {
570
+ "pins": [["table", "nil"], ["image.astc_header", "nil"]],
571
+ "removes": ["nil"]
572
+ },
573
+ "physics.raycast": {
574
+ "pins": [
575
+ ["table", "nil"],
576
+ ["message.physics.ray_cast_response[]", "message.physics.ray_cast_response", "nil"]
577
+ ],
578
+ "replaces": [
579
+ "Omit<BuiltinMessages[\"ray_cast_response\"], \"request_id\">[]",
580
+ "Omit<BuiltinMessages[\"ray_cast_response\"], \"request_id\">",
581
+ "undefined"
582
+ ]
583
+ },
547
584
  "render.predicate": {
548
585
  "pins": [["number"], ["render_predicate"]],
549
586
  "replaces": ["Opaque<\"render_predicate\">"]
@@ -557,6 +594,15 @@
557
594
  "socket.protect": {
558
595
  "pins": [["function(function())"], ["fun(...:any):any"]],
559
596
  "replaces": ["(...args: unknown[]) => LuaMultiReturn<[unknown, string | undefined]>"]
597
+ },
598
+ "tilemap.get_tile": { "pins": [["number"], ["integer"]], "adds": ["nil"] },
599
+ "tilemap.get_tile_info": {
600
+ "pins": [["table"], ["{ index:integer, h_flip:boolean, v_flip:boolean, rotate_90:boolean }"]],
601
+ "adds": ["nil"]
602
+ },
603
+ "tilemap.get_tiles": {
604
+ "pins": [["table"], ["table<integer, table<integer, integer>>"]],
605
+ "adds": ["nil"]
560
606
  }
561
607
  }
562
608
  }
package/index.d.ts CHANGED
@@ -5,6 +5,7 @@ import "./src/custom-messages";
5
5
  import "./src/msg-overloads";
6
6
  import "./src/message-guard";
7
7
  import "./src/window-event-guard";
8
+ import "./src/physics-event-guard";
8
9
  import "./src/message-dispatch";
9
10
  import "./src/scene-addresses";
10
11
  import "./src/engine-globals";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defold-typescript/types",
3
- "version": "0.50.1",
3
+ "version": "0.51.0",
4
4
  "description": "TypeScript types for the Defold engine's Lua APIs.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -93,6 +93,7 @@
93
93
  "!scripts/example-typecheck.ts",
94
94
  "!scripts/example-variant-drift.ts",
95
95
  "!scripts/engine-binding-extract.ts",
96
+ "!scripts/binding-pin.ts",
96
97
  "!scripts/sync-engine-bindings.ts",
97
98
  "!scripts/engine-binding-diff.ts",
98
99
  "!scripts/engine-binding-verdicts.ts",
@@ -108,7 +108,11 @@ export function identityCorrections(): IdentityCorrections {
108
108
  element,
109
109
  {
110
110
  pins: correctionPins(correction),
111
- replaces: union(correction.ts),
111
+ ...(correction.ts !== undefined
112
+ ? { replaces: union(correction.ts) }
113
+ : correction.nullable
114
+ ? { adds: ["nil"] }
115
+ : { removes: ["nil"] }),
112
116
  ...(correction.slot === undefined ? {} : { slot: correction.slot }),
113
117
  },
114
118
  ]),
@@ -4,6 +4,7 @@ import type { SlotTypes } from "../src/emit-dts";
4
4
  import { selectCompleteVersionSurfaces, versionOf } from "./generate-api-availability";
5
5
  import {
6
6
  type ApiTarget,
7
+ type GenerateOptions,
7
8
  generateModuleSignatures,
8
9
  loadApiTargets,
9
10
  loadTargetModules,
@@ -28,10 +29,15 @@ export interface SignaturesArtifact {
28
29
  export interface BuildSignaturesOptions {
29
30
  readonly packageRoot?: string;
30
31
  readonly registryPath?: string;
31
- // The constants each target's engine registers, which gate the undocumented
32
- // constant back-fill. Omitted, every target is emitted ungated. Supplied by the
33
- // in-repo callers only: the vendored bindings it reads are not published.
34
- readonly registeredConstantsOf?: (target: ApiTarget) => ReadonlySet<string> | undefined;
32
+ // What each target's engine source decides for its emit (`targetBindingOptions`):
33
+ // the constants it registers, which gate the undocumented constant back-fill,
34
+ // and the binding-pinned return corrections whose pin holds there. Omitted,
35
+ // every target is emitted ungated and with no binding-pinned correction.
36
+ // Supplied by the in-repo callers only: the vendored bindings it reads are not
37
+ // published.
38
+ readonly emitOptionsOf?: (
39
+ target: ApiTarget,
40
+ ) => Pick<GenerateOptions, "registeredConstants" | "bindingEvidence">;
35
41
  }
36
42
 
37
43
  // The authored replacement for a symbol the skip filter withheld, read from the
@@ -79,12 +85,9 @@ export function buildSignaturesArtifact(options: BuildSignaturesOptions = {}): S
79
85
  const version = versionOf(target);
80
86
  const perSymbol: Record<string, string> = {};
81
87
  const perSymbolSlots: Record<string, SlotTypes> = {};
82
- const registeredConstants = options.registeredConstantsOf?.(target);
88
+ const emitOptions = options.emitOptionsOf?.(target);
83
89
  for (const entry of loadTargetModules(target, packageRoot)) {
84
- for (const signature of generateModuleSignatures(
85
- entry,
86
- registeredConstants ? { registeredConstants } : undefined,
87
- )) {
90
+ for (const signature of generateModuleSignatures(entry, emitOptions)) {
88
91
  const key = symbolIdentityKey(signature.identity);
89
92
  perSymbol[key] = signature.tsSignature;
90
93
  if (Object.keys(signature.slotTypes).length > 0) {
@@ -129,8 +132,10 @@ export function serializeSignaturesArtifact(artifact: SignaturesArtifact): strin
129
132
  }
130
133
 
131
134
  if (import.meta.main) {
132
- const { registeredConstantFqns } = await import("./engine-binding-extract");
133
- const artifact = buildSignaturesArtifact({ registeredConstantsOf: registeredConstantFqns });
135
+ const { targetBindingOptions } = await import("./binding-pin");
136
+ const artifact = buildSignaturesArtifact({
137
+ emitOptionsOf: (target) => targetBindingOptions(target),
138
+ });
134
139
  if (process.argv.includes("--write")) {
135
140
  Bun.write(SIGNATURES_PATH, serializeSignaturesArtifact(artifact));
136
141
  const count = Object.values(artifact.versions).reduce((n, v) => n + Object.keys(v).length, 0);
@@ -2,6 +2,7 @@ import { mkdirSync, writeFileSync } from "node:fs";
2
2
  import { dirname, resolve } from "node:path";
3
3
  import {
4
4
  type ApiTarget,
5
+ type GenerateOptions,
5
6
  generateBuiltinMessagesDeclaration,
6
7
  generateModuleDeclaration,
7
8
  generateVersionIndex,
@@ -91,6 +92,11 @@ export interface BuildVersionedSurfaceOptions {
91
92
  // Defaults to reading them from the types package on disk; a caller with no
92
93
  // filesystem (a Worker) supplies the bytes and gets an identical file map.
93
94
  readonly augmentations?: readonly VersionedSurfaceFile[];
95
+ // What the target's own engine source decides for its emit
96
+ // (`targetBindingOptions`). Only an in-repo caller rebuilding a vendored
97
+ // target's committed surface passes it; a published install vendors no engine
98
+ // source, and the ref-doc targets it materializes have none to read.
99
+ readonly emitOptions?: Pick<GenerateOptions, "registeredConstants" | "bindingEvidence">;
94
100
  }
95
101
 
96
102
  export interface MaterializeVersionedSurfaceOptions extends BuildVersionedSurfaceOptions {
@@ -148,7 +154,7 @@ export async function buildVersionedSurfaceFiles(
148
154
  (surface) =>
149
155
  surface.map((entry) => ({
150
156
  path: entry.outFile,
151
- contents: generateModuleDeclaration(entry, { surface }).contents,
157
+ contents: generateModuleDeclaration(entry, { ...opts.emitOptions, surface }).contents,
152
158
  })),
153
159
  );
154
160
 
package/scripts/regen.ts CHANGED
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname, resolve } from "node:path";
3
3
  import messagesDoc from "../fixtures/messages_doc.json" with { type: "json" };
4
4
  import {
5
+ type ApiFunction,
5
6
  type ApiModule,
6
7
  parseDefoldApiDoc,
7
8
  type SkipOverloadRule,
@@ -15,10 +16,10 @@ import {
15
16
  type SymbolSignature,
16
17
  } from "../src/emit-dts";
17
18
  import {
18
- applyMessageDeprecations,
19
- applyMessageFieldCorrections,
19
+ applyMessageOverlays,
20
20
  type EmitBuiltinMessagesOptions,
21
21
  emitBuiltinMessages,
22
+ type MessageCatalog,
22
23
  parseMessagesDoc,
23
24
  } from "../src/emit-messages";
24
25
  import type { TranslationStore } from "../src/example-store";
@@ -399,21 +400,24 @@ export interface MessagesManifestEntry {
399
400
 
400
401
  // Unlike MODULE_MANIFEST, this surface is hand-maintained: Defold ships no
401
402
  // machine-readable export for built-in message ids, so refresh fixtures/
402
- // messages_doc.json by hand from the Defold API reference. The
403
- // message-payload-drift test guards the payload shapes against drift.
403
+ // messages_doc.json by hand from the default target's API reference. The
404
+ // message-payload-drift test holds its message ids, field names and optionality
405
+ // to that reference in both directions; what only the engine states is
406
+ // MESSAGE_ENGINE_CORRECTIONS.
404
407
  export const MESSAGES_MANIFEST: MessagesManifestEntry = {
405
408
  doc: messagesDoc,
406
409
  outFile: "builtin-messages.d.ts",
407
410
  };
408
411
 
412
+ export function builtinMessagesCatalog(entry: MessagesManifestEntry): MessageCatalog {
413
+ return applyMessageOverlays(parseMessagesDoc(entry.doc));
414
+ }
415
+
409
416
  export function generateBuiltinMessagesDeclaration(
410
417
  entry: MessagesManifestEntry,
411
418
  opts: EmitBuiltinMessagesOptions = {},
412
419
  ): string {
413
- return emitBuiltinMessages(
414
- applyMessageFieldCorrections(applyMessageDeprecations(parseMessagesDoc(entry.doc))),
415
- opts,
416
- );
420
+ return emitBuiltinMessages(builtinMessagesCatalog(entry), opts);
417
421
  }
418
422
 
419
423
  export interface GenerateResult {
@@ -456,6 +460,7 @@ export interface GenerateOptions {
456
460
  translations?: TranslationStore;
457
461
  urlParameters?: UrlParameterTable;
458
462
  registeredConstants?: ReadonlySet<string>;
463
+ bindingEvidence?: ReadonlySet<string>;
459
464
  // The modules the entry is emitted beside, the entry among them. Routing
460
465
  // reads this set instead of looking the entry up in a committed manifest, so
461
466
  // a surface built with its own import root still routes as a whole.
@@ -468,9 +473,11 @@ interface PreparedGeneratedModule {
468
473
  translations: TranslationStore;
469
474
  urlParameters: UrlParameterTable;
470
475
  registeredConstants: ReadonlySet<string> | undefined;
476
+ bindingEvidence: ReadonlySet<string> | undefined;
471
477
  typeLeaves: Readonly<Record<string, string>> | undefined;
472
478
  declaredTypes: ReadonlyMap<string, string> | undefined;
473
479
  dropped: string[];
480
+ withheldFunctions: ApiFunction[];
474
481
  }
475
482
 
476
483
  // Parse a manifest entry, apply its `skipFunctions` and `skipOverloads` filters, and resolve the
@@ -482,7 +489,7 @@ function prepareGeneratedModule(
482
489
  options?: GenerateOptions,
483
490
  ): PreparedGeneratedModule {
484
491
  const routed = routedModuleOf(entry, options?.surface);
485
- const { module, dropped } = routed?.prepared ?? withheldApiModule(entry);
492
+ const { module, dropped, withheldFunctions } = routed?.prepared ?? withheldApiModule(entry);
486
493
  const knownConstantFqns = options?.knownConstantFqns ?? collectConstantFqns();
487
494
  const translations = options?.translations ?? loadTranslations();
488
495
  const urlParameters = options?.urlParameters ?? committedUrlParameters();
@@ -492,14 +499,16 @@ function prepareGeneratedModule(
492
499
  translations,
493
500
  urlParameters,
494
501
  registeredConstants: options?.registeredConstants,
502
+ bindingEvidence: options?.bindingEvidence,
495
503
  typeLeaves: entry.typeLeaves,
496
504
  declaredTypes: routed?.declaredTypes,
497
505
  dropped,
506
+ withheldFunctions,
498
507
  };
499
508
  }
500
509
 
501
510
  interface RoutedSurface {
502
- readonly modules: ReadonlyMap<ModuleManifestEntry, { module: ApiModule; dropped: string[] }>;
511
+ readonly modules: ReadonlyMap<ModuleManifestEntry, WithheldModule>;
503
512
  readonly declaredTypes: ReadonlyMap<string, string>;
504
513
  }
505
514
 
@@ -513,10 +522,7 @@ function routeSurface(entries: readonly ModuleManifestEntry[]): RoutedSurface {
513
522
  modules: new Map(
514
523
  entries.map((member, index) => [
515
524
  member,
516
- {
517
- module: routed[index] as ApiModule,
518
- dropped: (withheld[index] as { dropped: string[] }).dropped,
519
- },
525
+ { ...(withheld[index] as WithheldModule), module: routed[index] as ApiModule },
520
526
  ]),
521
527
  ),
522
528
  declaredTypes: declaredTypePaths(routed),
@@ -534,7 +540,7 @@ function routedModuleOf(
534
540
  callerSurface?: readonly ModuleManifestEntry[],
535
541
  ):
536
542
  | {
537
- prepared: { module: ApiModule; dropped: string[] };
543
+ prepared: WithheldModule;
538
544
  declaredTypes: ReadonlyMap<string, string>;
539
545
  }
540
546
  | undefined {
@@ -622,8 +628,14 @@ function committedSurfaceOf(
622
628
  };
623
629
  }
624
630
 
631
+ interface WithheldModule {
632
+ module: ApiModule;
633
+ dropped: string[];
634
+ withheldFunctions: ApiFunction[];
635
+ }
636
+
625
637
  // The parsed module with the entry's `skipFunctions` and `skipOverloads` applied.
626
- function withheldApiModule(entry: ModuleManifestEntry): { module: ApiModule; dropped: string[] } {
638
+ function withheldApiModule(entry: ModuleManifestEntry): WithheldModule {
627
639
  let module = parseDefoldApiDoc(entry.doc);
628
640
  const prefix = `${module.namespace}.`;
629
641
  const dropped: string[] = [];
@@ -651,7 +663,8 @@ function withheldApiModule(entry: ModuleManifestEntry): { module: ApiModule; dro
651
663
  }
652
664
  return withheld(name);
653
665
  };
654
- module.functions = module.functions.filter((fn) => !withheld(fn.name));
666
+ const withheldFunctions = module.functions.filter((fn) => withheld(fn.name));
667
+ module.functions = module.functions.filter((fn) => !withheldFunctions.includes(fn));
655
668
  module.variables = module.variables.filter((v) => !withheld(v.name));
656
669
  const withheldConstants = new Set<string>();
657
670
  module.constants = module.constants.filter((c) => {
@@ -667,7 +680,7 @@ function withheldApiModule(entry: ModuleManifestEntry): { module: ApiModule; dro
667
680
  if (module.structs) module.structs = module.structs.filter((s) => !withheldType(s.name));
668
681
  module.typedefs = module.typedefs.filter((t) => t.aliasOf === undefined || !withheldType(t.name));
669
682
  module = withholdOverloads(module, entry.skipOverloads ?? []);
670
- return { module, dropped };
683
+ return { module, dropped, withheldFunctions };
671
684
  }
672
685
 
673
686
  // The field corrections one target's runtime entries leave inert: every entry is
@@ -739,15 +752,19 @@ export function generateModuleDeclaration(
739
752
  translations,
740
753
  urlParameters,
741
754
  registeredConstants,
755
+ bindingEvidence,
742
756
  typeLeaves,
743
757
  declaredTypes,
744
758
  dropped,
759
+ withheldFunctions,
745
760
  } = prepareGeneratedModule(entry, options);
746
761
  const emitted = emitDeclarations(module, {
747
762
  knownConstantFqns,
748
763
  translations,
749
764
  urlParameters,
765
+ withheldFunctions,
750
766
  ...(registeredConstants ? { registeredConstants } : {}),
767
+ ...(bindingEvidence ? { bindingEvidence } : {}),
751
768
  ...(typeLeaves ? { typeLeaves } : {}),
752
769
  ...(declaredTypes ? { declaredTypes } : {}),
753
770
  ...(entry.indexBaseSource ? { indexBaseSource: entry.indexBaseSource } : {}),
@@ -772,6 +789,7 @@ export function generateModuleSignatures(
772
789
  knownConstantFqns,
773
790
  urlParameters,
774
791
  registeredConstants,
792
+ bindingEvidence,
775
793
  typeLeaves,
776
794
  declaredTypes,
777
795
  } = prepareGeneratedModule(entry, options);
@@ -779,6 +797,7 @@ export function generateModuleSignatures(
779
797
  knownConstantFqns,
780
798
  urlParameters,
781
799
  ...(registeredConstants ? { registeredConstants } : {}),
800
+ ...(bindingEvidence ? { bindingEvidence } : {}),
782
801
  ...(typeLeaves ? { typeLeaves } : {}),
783
802
  ...(declaredTypes ? { declaredTypes } : {}),
784
803
  });
@@ -857,6 +876,7 @@ const UNIVERSAL_EXTRA_IMPORTS: readonly UniversalExtraImport[] = [
857
876
  { specifier: "../../src/msg-overloads" },
858
877
  { specifier: "../../src/message-guard" },
859
878
  { specifier: "../../src/window-event-guard" },
879
+ { specifier: "../../src/physics-event-guard" },
860
880
  { specifier: "../../src/scene-addresses" },
861
881
  { specifier: "../../src/go-overloads" },
862
882
  { specifier: "../../src/component-properties" },
@@ -1127,14 +1147,12 @@ export async function regenerate(
1127
1147
 
1128
1148
  // Imported here rather than at module scope: the vendored engine bindings are
1129
1149
  // not published, and `resolve` loads this module from an installed package.
1130
- const { registeredConstantFqns } = await import("./engine-binding-extract");
1150
+ const { targetBindingOptions } = await import("./binding-pin");
1131
1151
  const generated = resolve(import.meta.dir, "..", "generated");
1132
1152
  io.mkdir(resolve(generated, "editor-vm"));
1133
- const defaultRegistered = registeredConstantFqns(DEFAULT_TARGET);
1153
+ const defaultBinding = targetBindingOptions(DEFAULT_TARGET);
1134
1154
  for (const entry of MODULE_MANIFEST) {
1135
- const { contents, dropped } = generateModuleDeclaration(entry, {
1136
- ...(defaultRegistered ? { registeredConstants: defaultRegistered } : {}),
1137
- });
1155
+ const { contents, dropped } = generateModuleDeclaration(entry, defaultBinding);
1138
1156
  if (dropped.length > 0) {
1139
1157
  io.log(`note: dropped skipped member(s) from ${entry.namespace}: ${dropped.join(", ")}`);
1140
1158
  }
@@ -1183,10 +1201,9 @@ export async function regenerate(
1183
1201
  };
1184
1202
  for (const entry of VERSIONED_MODULE_MANIFEST) {
1185
1203
  const target = versionedTargets.find((t) => t.id === entry.versionId);
1186
- const registeredConstants = target ? registeredConstantFqns(target) : undefined;
1187
1204
  const { contents, dropped } = generateModuleDeclaration(
1188
1205
  entry,
1189
- registeredConstants ? { registeredConstants } : undefined,
1206
+ target ? targetBindingOptions(target) : undefined,
1190
1207
  );
1191
1208
  if (dropped.length > 0) {
1192
1209
  io.log(
@@ -1,24 +1,121 @@
1
1
  /** @noSelfInFile */
2
2
 
3
- import type { Hash } from "./core-types";
3
+ import type { Hash, Vector3 } from "./core-types";
4
4
 
5
- // Component property keys upstream examples read through `go.get` while no
6
- // ref-doc catalog declares them. Only evidenced keys belong here.
5
+ // Property keys the engine handles while no ref-doc catalog declares them. Each
6
+ // key comes from the component's `GetProperty` / `SetProperty` branches in the
7
+ // engine source, or from an upstream example that reads it, and cites that
8
+ // evidence. A key the engine reads but never writes is `readonly`.
7
9
  declare global {
10
+ namespace go {
11
+ interface properties {
12
+ /** The position's x component. `gameobject.cpp:GetProperty` reads one float. */
13
+ "position.x": number;
14
+ /** The position's y component. `gameobject.cpp:GetProperty` reads one float. */
15
+ "position.y": number;
16
+ /** The position's z component. `gameobject.cpp:GetProperty` reads one float. */
17
+ "position.z": number;
18
+ /** The rotation quaternion's x component. `gameobject.cpp:GetProperty` reads one float. */
19
+ "rotation.x": number;
20
+ /** The rotation quaternion's y component. `gameobject.cpp:GetProperty` reads one float. */
21
+ "rotation.y": number;
22
+ /** The rotation quaternion's z component. `gameobject.cpp:GetProperty` reads one float. */
23
+ "rotation.z": number;
24
+ /** The rotation quaternion's w component. `gameobject.cpp:GetProperty` reads one float. */
25
+ "rotation.w": number;
26
+ /** The euler rotation's x angle, in degrees. `gameobject.cpp:GetProperty` reads one float. */
27
+ "euler.x": number;
28
+ /** The euler rotation's y angle, in degrees. `gameobject.cpp:GetProperty` reads one float. */
29
+ "euler.y": number;
30
+ /** The euler rotation's z angle, in degrees. `gameobject.cpp:GetProperty` reads one float. */
31
+ "euler.z": number;
32
+ /** The scale's x component. `gameobject.cpp:GetProperty` reads one float. */
33
+ "scale.x": number;
34
+ /** The scale's y component. `gameobject.cpp:GetProperty` reads one float. */
35
+ "scale.y": number;
36
+ /** The scale's z component. `gameobject.cpp:GetProperty` reads one float. */
37
+ "scale.z": number;
38
+ /**
39
+ * The scale's x and y components. `gameobject.cpp:GetProperty` reads a
40
+ * vector3 whose z is always 1. `go.set` also takes a number, which it
41
+ * applies to both x and y.
42
+ */
43
+ "scale.xy": Vector3;
44
+ }
45
+ }
46
+
8
47
  namespace sprite {
9
48
  interface properties {
10
49
  /**
11
50
  * The texture bound to the sprite's first sampler. Not in the sprite
12
51
  * ref-doc; `resource.set`'s example reads it with
13
- * `go.get("#sprite", "texture0")`.
52
+ * `go.get("#sprite", "texture0")`. Read-only:
53
+ * `comp_sprite.cpp:CompSpriteSetProperty` has no branch for it.
14
54
  */
15
- texture0: Hash;
55
+ readonly texture0: Hash;
56
+ }
57
+ }
58
+
59
+ namespace model {
60
+ interface properties {
61
+ /**
62
+ * The material resource the model renders with.
63
+ * `comp_model.cpp:CompModelGetProperty` and `CompModelSetProperty` read
64
+ * and write it as a resource path hash.
65
+ */
66
+ material: Hash;
67
+ /**
68
+ * The skin the model's rig uses. `comp_model.cpp:CompModelGetProperty` and
69
+ * `CompModelSetProperty` read and write it as a hash.
70
+ */
71
+ skin: Hash;
72
+ }
73
+ }
74
+
75
+ namespace physics {
76
+ interface properties {
77
+ /**
78
+ * Whether the body runs continuous collision detection as a fast-moving
79
+ * bullet. Box2D only: `comp_collision_object_box2d.cpp` reads and writes
80
+ * it, while Bullet3D logs a warning and reports the property as not found.
81
+ */
82
+ bullet: boolean;
83
+ }
84
+ }
85
+
86
+ namespace factory {
87
+ /**
88
+ * Factory component properties. Upstream's factory reference declares none.
89
+ */
90
+ interface properties {
91
+ /**
92
+ * The path hash of the prototype the factory spawns. Read-only:
93
+ * `comp_factory.cpp:CompFactoryGetProperty` reads it and the component
94
+ * registers no set handler.
95
+ */
96
+ readonly prototype: Hash;
97
+ }
98
+ }
99
+
100
+ namespace collectionfactory {
101
+ /**
102
+ * Collection factory component properties. Upstream's collectionfactory
103
+ * reference declares none.
104
+ */
105
+ interface properties {
106
+ /**
107
+ * The path hash of the collection prototype the factory spawns.
108
+ * Read-only: `comp_collection_factory.cpp:CompCollectionFactoryGetProperty`
109
+ * reads it and the component registers no set handler.
110
+ */
111
+ readonly prototype: Hash;
16
112
  }
17
113
  }
18
114
 
19
115
  /**
20
116
  * Mesh component properties. Upstream ships no mesh API module, so this
21
- * catalog holds only the keys upstream examples read.
117
+ * catalog holds the keys `comp_mesh.cpp:CompMeshGetProperty` and
118
+ * `CompMeshSetProperty` handle.
22
119
  */
23
120
  namespace mesh {
24
121
  interface properties {
@@ -28,6 +125,40 @@ declare global {
28
125
  * `go.get("#mesh", "vertices")`.
29
126
  */
30
127
  vertices: Hash;
128
+ /** The material resource the mesh renders with, as a resource path hash. */
129
+ material: Hash;
130
+ /** The texture on unit 0, as a resource path hash. The engine holds units 0-15. */
131
+ texture0: Hash;
132
+ /** The texture on unit 1, as a resource path hash. */
133
+ texture1: Hash;
134
+ /** The texture on unit 2, as a resource path hash. */
135
+ texture2: Hash;
136
+ /** The texture on unit 3, as a resource path hash. */
137
+ texture3: Hash;
138
+ /** The texture on unit 4, as a resource path hash. */
139
+ texture4: Hash;
140
+ /** The texture on unit 5, as a resource path hash. */
141
+ texture5: Hash;
142
+ /** The texture on unit 6, as a resource path hash. */
143
+ texture6: Hash;
144
+ /** The texture on unit 7, as a resource path hash. */
145
+ texture7: Hash;
146
+ /** The texture on unit 8, as a resource path hash. */
147
+ texture8: Hash;
148
+ /** The texture on unit 9, as a resource path hash. */
149
+ texture9: Hash;
150
+ /** The texture on unit 10, as a resource path hash. */
151
+ texture10: Hash;
152
+ /** The texture on unit 11, as a resource path hash. */
153
+ texture11: Hash;
154
+ /** The texture on unit 12, as a resource path hash. */
155
+ texture12: Hash;
156
+ /** The texture on unit 13, as a resource path hash. */
157
+ texture13: Hash;
158
+ /** The texture on unit 14, as a resource path hash. */
159
+ texture14: Hash;
160
+ /** The texture on unit 15, as a resource path hash. */
161
+ texture15: Hash;
31
162
  }
32
163
  }
33
164
  }