@defold-typescript/types 0.5.5 → 0.6.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 (53) hide show
  1. package/api-targets.json +1 -1
  2. package/generated/b2d.d.ts +3 -0
  3. package/generated/buffer.d.ts +44 -38
  4. package/generated/builtin-messages.d.ts +1 -1
  5. package/generated/camera.d.ts +3 -0
  6. package/generated/collectionfactory.d.ts +47 -40
  7. package/generated/collectionproxy.d.ts +23 -18
  8. package/generated/crash.d.ts +3 -0
  9. package/generated/factory.d.ts +32 -24
  10. package/generated/go.d.ts +123 -124
  11. package/generated/graphics.d.ts +3 -0
  12. package/generated/gui.d.ts +303 -283
  13. package/generated/http.d.ts +26 -16
  14. package/generated/iac.d.ts +3 -0
  15. package/generated/iap.d.ts +6 -3
  16. package/generated/image.d.ts +30 -26
  17. package/generated/json.d.ts +36 -32
  18. package/generated/kinds/gui-script.d.ts +7 -5
  19. package/generated/kinds/render-script.d.ts +7 -5
  20. package/generated/kinds/script.d.ts +7 -5
  21. package/generated/label.d.ts +16 -9
  22. package/generated/liveupdate.d.ts +29 -26
  23. package/generated/model.d.ts +57 -45
  24. package/generated/msg.d.ts +3 -0
  25. package/generated/particlefx.d.ts +50 -34
  26. package/generated/physics.d.ts +153 -133
  27. package/generated/profiler.d.ts +45 -41
  28. package/generated/push.d.ts +5 -2
  29. package/generated/render.d.ts +410 -349
  30. package/generated/resource.d.ts +619 -572
  31. package/generated/socket.d.ts +49 -33
  32. package/generated/sound.d.ts +83 -72
  33. package/generated/sprite.d.ts +3 -0
  34. package/generated/sys.d.ts +198 -189
  35. package/generated/tilemap.d.ts +43 -39
  36. package/generated/timer.d.ts +42 -36
  37. package/generated/vmath.d.ts +22 -0
  38. package/generated/webview.d.ts +3 -0
  39. package/generated/window.d.ts +23 -17
  40. package/generated/zlib.d.ts +15 -12
  41. package/index.d.ts +3 -1
  42. package/package.json +6 -2
  43. package/scripts/fidelity-audit.ts +61 -1
  44. package/scripts/fidelity-baseline.json +10 -10
  45. package/scripts/ref-doc-delta.ts +143 -0
  46. package/scripts/regen.ts +18 -9
  47. package/src/core-types.ts +14 -0
  48. package/src/emit-dts.ts +219 -13
  49. package/src/engine-globals.d.ts +2 -0
  50. package/src/go-overloads.d.ts +43 -0
  51. package/src/index.ts +5 -0
  52. package/src/lifecycle.ts +157 -16
  53. package/src/publish-dts.ts +1 -1
@@ -2,6 +2,9 @@
2
2
  import type { Hash, Url } from "../src/core-types";
3
3
 
4
4
  declare global {
5
+ /**
6
+ * Functions and messages used to manipulate tile map components.
7
+ */
5
8
  namespace tilemap {
6
9
  /**
7
10
  * flip tile horizontally
@@ -32,9 +35,9 @@ declare global {
32
35
  *
33
36
  * @param url - the tile map
34
37
  * @example
35
- * ```lua
36
- * -- get the level bounds.
37
- * local x, y, w, h = tilemap.get_bounds("/level#tilemap")
38
+ * ```ts
39
+ * // get the level bounds.
40
+ * const [x, y, w, h] = tilemap.get_bounds("/level#tilemap");
38
41
  * ```
39
42
  */
40
43
  function get_bounds(url: string | Hash | Url): LuaMultiReturn<[number, number, number, number]>;
@@ -51,9 +54,9 @@ declare global {
51
54
  * @param y - y-coordinate of the tile
52
55
  * @returns index of the tile
53
56
  * @example
54
- * ```lua
55
- * -- get the tile under the player.
56
- * local tileno = tilemap.get_tile("/level#tilemap", "foreground", self.player_x, self.player_y)
57
+ * ```ts
58
+ * // get the tile under the player.
59
+ * const tileno = tilemap.get_tile("/level#tilemap", "foreground", self.player_x, self.player_y);
57
60
  * ```
58
61
  */
59
62
  function get_tile(url: string | Hash | Url, layer: string | Hash, x: number, y: number): number;
@@ -70,19 +73,19 @@ declare global {
70
73
  * @param y - y-coordinate of the tile
71
74
  * @returns index of the tile
72
75
  * @example
73
- * ```lua
74
- * -- get the tile under the player.
75
- * local tile_info = tilemap.get_tile_info("/level#tilemap", "foreground", self.player_x, self.player_y)
76
- * pprint(tile_info)
77
- * -- {
78
- * -- index = 0,
79
- * -- h_flip = false,
80
- * -- v_flip = true,
81
- * -- rotate_90 = false
82
- * -- }
76
+ * ```ts
77
+ * // get the tile under the player.
78
+ * const tile_info = tilemap.get_tile_info("/level#tilemap", "foreground", self.player_x, self.player_y);
79
+ * pprint(tile_info);
80
+ * // {
81
+ * // index = 0,
82
+ * // h_flip = false,
83
+ * // v_flip = true,
84
+ * // rotate_90 = false
85
+ * // }
83
86
  * ```
84
87
  */
85
- function get_tile_info(url: string | Hash | Url, layer: string | Hash, x: number, y: number): Record<string | number, unknown>;
88
+ function get_tile_info(url: string | Hash | Url, layer: string | Hash, x: number, y: number): { index: number; h_flip: boolean; v_flip: boolean; rotate_90: boolean };
86
89
  /**
87
90
  * Retrieves all the tiles for the specified layer in the tilemap.
88
91
  * It returns a table of rows where the keys are the
@@ -93,19 +96,20 @@ declare global {
93
96
  * @param layer - the name of the layer for the tiles
94
97
  * @returns a table of rows representing the layer
95
98
  * @example
96
- * ```lua
97
- * local left, bottom, columns_count, rows_count = tilemap.get_bounds("#tilemap")
98
- * local tiles = tilemap.get_tiles("#tilemap", "layer")
99
- * local tile, count = 0, 0
100
- * for row_index = bottom, bottom + rows_count - 1 do
101
- * for column_index = left, left + columns_count - 1 do
102
- * tile = tiles[row_index][column_index]
103
- * count = count + 1
104
- * end
105
- * end
99
+ * ```ts
100
+ * const [left, bottom, columns_count, rows_count] = tilemap.get_bounds("#tilemap");
101
+ * const tiles = tilemap.get_tiles("#tilemap", "layer");
102
+ * let tile = 0;
103
+ * let count = 0;
104
+ * for (let row_index = bottom; row_index <= bottom + rows_count - 1; row_index++) {
105
+ * for (let column_index = left; column_index <= left + columns_count - 1; column_index++) {
106
+ * tile = tiles[row_index][column_index];
107
+ * count = count + 1;
108
+ * }
109
+ * }
106
110
  * ```
107
111
  */
108
- function get_tiles(url: string | Hash | Url, layer: string | Hash): Record<string | number, unknown>;
112
+ function get_tiles(url: string | Hash | Url, layer: string | Hash): LuaMap<number, LuaMap<number, number>>;
109
113
  /**
110
114
  * Replace a tile in a tile map with a new tile.
111
115
  * The coordinates of the tiles are indexed so that the "first" tile just
@@ -134,15 +138,15 @@ declare global {
134
138
  * @param tile - index of new tile to set. 0 resets the cell
135
139
  * @param transform_bitmask - optional flip and/or rotation should be applied to the tile
136
140
  * @example
137
- * ```lua
138
- * -- Clear the tile under the player.
139
- * tilemap.set_tile("/level#tilemap", "foreground", self.player_x, self.player_y, 0)
141
+ * ```ts
142
+ * // Clear the tile under the player.
143
+ * tilemap.set_tile("/level#tilemap", "foreground", self.player_x, self.player_y, 0);
140
144
  *
141
- * -- Set tile with different combination of flip and rotation
142
- * tilemap.set_tile("#tilemap", "layer1", x, y, 0, tilemap.H_FLIP + tilemap.V_FLIP + tilemap.ROTATE_90)
143
- * tilemap.set_tile("#tilemap", "layer1", x, y, 0, tilemap.H_FLIP + tilemap.ROTATE_270)
144
- * tilemap.set_tile("#tilemap", "layer1", x, y, 0, tilemap.V_FLIP + tilemap.H_FLIP)
145
- * tilemap.set_tile("#tilemap", "layer1", x, y, 0, tilemap.ROTATE_180)
145
+ * // Set tile with different combination of flip and rotation
146
+ * tilemap.set_tile("#tilemap", "layer1", x, y, 0, tilemap.H_FLIP + tilemap.V_FLIP + tilemap.ROTATE_90);
147
+ * tilemap.set_tile("#tilemap", "layer1", x, y, 0, tilemap.H_FLIP + tilemap.ROTATE_270);
148
+ * tilemap.set_tile("#tilemap", "layer1", x, y, 0, tilemap.V_FLIP + tilemap.H_FLIP);
149
+ * tilemap.set_tile("#tilemap", "layer1", x, y, 0, tilemap.ROTATE_180);
146
150
  * ```
147
151
  */
148
152
  function set_tile(url: string | Hash | Url, layer: string | Hash, x: number, y: number, tile: number, transform_bitmask?: number): void;
@@ -153,9 +157,9 @@ declare global {
153
157
  * @param layer - name of the layer for the tile
154
158
  * @param visible - should the layer be visible
155
159
  * @example
156
- * ```lua
157
- * -- Disable rendering of the layer
158
- * tilemap.set_visible("/level#tilemap", "foreground", false)
160
+ * ```ts
161
+ * // Disable rendering of the layer
162
+ * tilemap.set_visible("/level#tilemap", "foreground", false);
159
163
  * ```
160
164
  */
161
165
  function set_visible(url: string | Hash | Url, layer: string | Hash, visible: boolean): void;
@@ -1,5 +1,11 @@
1
1
  /** @noSelfInFile */
2
2
  declare global {
3
+ /**
4
+ * Timers allow you to set a delay and a callback to be called when the timer completes.
5
+ * The timers created with this API are updated with the collection timer where they
6
+ * are created. If you pause or speed up the collection (using `set_time_step`) it will
7
+ * also affect the new timer.
8
+ */
3
9
  namespace timer {
4
10
  /**
5
11
  * Indicates an invalid timer handle
@@ -12,13 +18,13 @@ declare global {
12
18
  * @param handle - the timer handle returned by timer.delay()
13
19
  * @returns if the timer was active, false if the timer is already cancelled / complete
14
20
  * @example
15
- * ```lua
16
- * self.handle = timer.delay(1, true, function() print("print every second") end)
17
- * ...
18
- * local result = timer.cancel(self.handle)
19
- * if not result then
20
- * print("the timer is already cancelled")
21
- * end
21
+ * ```ts
22
+ * self.handle = timer.delay(1, true, () => print("print every second"));
23
+ * // ...
24
+ * const result = timer.cancel(self.handle);
25
+ * if (!result) {
26
+ * print("the timer is already cancelled");
27
+ * }
22
28
  * ```
23
29
  */
24
30
  function cancel(handle: number): boolean;
@@ -41,21 +47,21 @@ declare global {
41
47
  * number The elapsed time - on first trigger it is time since timer.delay call, otherwise time since last trigger
42
48
  * @returns identifier for the create timer, returns timer.INVALID_TIMER_HANDLE if the timer can not be created
43
49
  * @example
44
- * ```lua
45
- * A simple one-shot timer
46
- * timer.delay(1, false, function() print("print in one second") end)
50
+ * ```ts
51
+ * // A simple one-shot timer
52
+ * timer.delay(1, false, () => print("print in one second"));
47
53
  *
48
- * Repetitive timer which canceled after 10 calls
49
- * local function call_every_second(self, handle, time_elapsed)
50
- * self.counter = self.counter + 1
51
- * print("Call #", self.counter)
52
- * if self.counter == 10 then
53
- * timer.cancel(handle) -- cancel timer after 10 calls
54
- * end
55
- * end
54
+ * // Repetitive timer which canceled after 10 calls
55
+ * function call_every_second(self, handle, time_elapsed) {
56
+ * self.counter = self.counter + 1;
57
+ * print("Call #", self.counter);
58
+ * if (self.counter === 10) {
59
+ * timer.cancel(handle); // cancel timer after 10 calls
60
+ * }
61
+ * }
56
62
  *
57
- * self.counter = 0
58
- * timer.delay(1, true, call_every_second)
63
+ * self.counter = 0;
64
+ * timer.delay(1, true, call_every_second);
59
65
  * ```
60
66
  */
61
67
  function delay(delay: number, repeating: boolean, callback: (self: unknown, handle: unknown, time_elapsed: unknown) => void): number;
@@ -71,15 +77,15 @@ declare global {
71
77
  * `repeating`
72
78
  * boolean true = repeat timer until cancel, false = one-shot timer.
73
79
  * @example
74
- * ```lua
75
- * self.handle = timer.delay(1, true, function() print("print every second") end)
76
- * ...
77
- * local result = timer.get_info(self.handle)
78
- * if not result then
79
- * print("the timer is already cancelled or complete")
80
- * else
81
- * pprint(result) -- delay, time_remaining, repeating
82
- * end
80
+ * ```ts
81
+ * self.handle = timer.delay(1, true, () => print("print every second"));
82
+ * // ...
83
+ * const result = timer.get_info(self.handle);
84
+ * if (!result) {
85
+ * print("the timer is already cancelled or complete");
86
+ * } else {
87
+ * pprint(result); // delay, time_remaining, repeating
88
+ * }
83
89
  * ```
84
90
  */
85
91
  function get_info(handle: number): { time_remaining: number; delay: number; repeating: boolean } | unknown;
@@ -89,13 +95,13 @@ declare global {
89
95
  * @param handle - the timer handle returned by timer.delay()
90
96
  * @returns if the timer was active, false if the timer is already cancelled / complete
91
97
  * @example
92
- * ```lua
93
- * self.handle = timer.delay(1, true, function() print("print every second or manually by timer.trigger") end)
94
- * ...
95
- * local result = timer.trigger(self.handle)
96
- * if not result then
97
- * print("the timer is already cancelled or complete")
98
- * end
98
+ * ```ts
99
+ * self.handle = timer.delay(1, true, () => print("print every second or manually by timer.trigger"));
100
+ * // ...
101
+ * const result = timer.trigger(self.handle);
102
+ * if (!result) {
103
+ * print("the timer is already cancelled or complete");
104
+ * }
99
105
  * ```
100
106
  */
101
107
  function trigger(handle: number): boolean;
@@ -2,6 +2,28 @@
2
2
  import type { Matrix4, Quaternion, Vector, Vector3, Vector4 } from "../src/core-types";
3
3
 
4
4
  declare global {
5
+ /**
6
+ * Functions for mathematical operations on vectors, matrices and quaternions.
7
+ * - The vector types (`vmath.vector3` and `vmath.vector4`) supports addition and subtraction
8
+ * with vectors of the same type. Vectors can be negated and multiplied (scaled) or divided by numbers.
9
+ * - The quaternion type (`vmath.quat`) supports multiplication with other quaternions.
10
+ * - The matrix type (`vmath.matrix4`) can be multiplied with numbers, other matrices
11
+ * and `vmath.vector4` values.
12
+ * - All types performs equality comparison by each component value.
13
+ * The following components are available for the various types:
14
+ * vector3
15
+ * : `x`, `y` and `z`. Example: `v.y`
16
+ * vector4
17
+ * : `x`, `y`, `z`, and `w`. Example: `v.w`
18
+ * quaternion
19
+ * : `x`, `y`, `z`, and `w`. Example: `q.w`
20
+ * matrix4
21
+ * : `m00` to `m33` where the first number is the row (starting from 0) and the second
22
+ * number is the column. Columns can be accessed with `c0` to `c3`, returning a `vector4`.
23
+ * Example: `m.m21` which is equal to `m.c1.z`
24
+ * vector
25
+ * : indexed by number 1 to the vector length. Example: `v[3]`
26
+ */
5
27
  namespace vmath {
6
28
  /**
7
29
  * Clamp input value to be in range of [min, max]. In case if input value has vector3|vector4 type
@@ -1,5 +1,8 @@
1
1
  /** @noSelfInFile */
2
2
  declare global {
3
+ /**
4
+ * Functions and constants for interacting with webview APIs
5
+ */
3
6
  namespace webview {
4
7
  /**
5
8
  * Creates a webview instance. It can show HTML pages as well as evaluate Javascript. The view remains hidden until the first call. There can exist a maximum of 4 webviews at the same time.
@@ -2,6 +2,10 @@
2
2
  import type { Opaque } from "../src/core-types";
3
3
 
4
4
  declare global {
5
+ /**
6
+ * Functions and constants to access the window, window event listeners
7
+ * and screen dimming.
8
+ */
5
9
  namespace window {
6
10
  /**
7
11
  * Dimming mode is used to control whether or not a mobile device should dim the screen after a period without user interaction.
@@ -114,24 +118,26 @@ declare global {
114
118
  * - number `width`: The width of a resize event. nil otherwise.
115
119
  * - number `height`: The height of a resize event. nil otherwise.
116
120
  * @example
117
- * ```lua
118
- * function window_callback(self, event, data)
119
- * if event == window.WINDOW_EVENT_FOCUS_LOST then
120
- * print("window.WINDOW_EVENT_FOCUS_LOST")
121
- * elseif event == window.WINDOW_EVENT_FOCUS_GAINED then
122
- * print("window.WINDOW_EVENT_FOCUS_GAINED")
123
- * elseif event == window.WINDOW_EVENT_ICONFIED then
124
- * print("window.WINDOW_EVENT_ICONFIED")
125
- * elseif event == window.WINDOW_EVENT_DEICONIFIED then
126
- * print("window.WINDOW_EVENT_DEICONIFIED")
127
- * elseif event == window.WINDOW_EVENT_RESIZED then
128
- * print("Window resized: ", data.width, data.height)
129
- * end
130
- * end
121
+ * ```ts
122
+ * function window_callback(self, event, data) {
123
+ * if (event === window.WINDOW_EVENT_FOCUS_LOST) {
124
+ * print("window.WINDOW_EVENT_FOCUS_LOST");
125
+ * } else if (event === window.WINDOW_EVENT_FOCUS_GAINED) {
126
+ * print("window.WINDOW_EVENT_FOCUS_GAINED");
127
+ * } else if (event === window.WINDOW_EVENT_ICONFIED) {
128
+ * print("window.WINDOW_EVENT_ICONFIED");
129
+ * } else if (event === window.WINDOW_EVENT_DEICONIFIED) {
130
+ * print("window.WINDOW_EVENT_DEICONIFIED");
131
+ * } else if (event === window.WINDOW_EVENT_RESIZED) {
132
+ * print("Window resized: ", data.width, data.height);
133
+ * }
134
+ * }
131
135
  *
132
- * function init(self)
133
- * window.set_listener(window_callback)
134
- * end
136
+ * export default defineScript({
137
+ * init() {
138
+ * window.set_listener(window_callback);
139
+ * },
140
+ * });
135
141
  * ```
136
142
  */
137
143
  function set_listener(callback?: (self: unknown, event: unknown, data: unknown) => void): void;
@@ -1,5 +1,8 @@
1
1
  /** @noSelfInFile */
2
2
  declare global {
3
+ /**
4
+ * Functions for compression and decompression of string buffers.
5
+ */
3
6
  namespace zlib {
4
7
  /**
5
8
  * A lua error is raised is on error
@@ -7,14 +10,14 @@ declare global {
7
10
  * @param buf - buffer to deflate
8
11
  * @returns deflated buffer
9
12
  * @example
10
- * ```lua
11
- * local data = "This is a string with uncompressed data."
12
- * local compressed_data = zlib.deflate(data)
13
- * local s = ""
14
- * for c in string.gmatch(compressed_data, ".") do
15
- * s = s .. '\\' .. string.byte(c)
16
- * end
17
- * print(s) --> \120\94\11\201\200\44\86\0\162\68\133\226\146\162 ...
13
+ * ```ts
14
+ * const data = "This is a string with uncompressed data.";
15
+ * const compressed_data = zlib.deflate(data);
16
+ * let s = "";
17
+ * for (const c of compressed_data) {
18
+ * s = s + "\\" + c.charCodeAt(0);
19
+ * }
20
+ * print(s); //> \120\94\11\201\200\44\86\0\162\68\133\226\146\162 ...
18
21
  * ```
19
22
  */
20
23
  function deflate(buf: string): string;
@@ -24,10 +27,10 @@ declare global {
24
27
  * @param buf - buffer to inflate
25
28
  * @returns inflated buffer
26
29
  * @example
27
- * ```lua
28
- * local data = "\120\94\11\201\200\44\86\0\162\68\133\226\146\162\204\188\116\133\242\204\146\12\133\210\188\228\252\220\130\162\212\226\226\212\20\133\148\196\146\68\61\0\44\67\14\201"
29
- * local uncompressed_data = zlib.inflate(data)
30
- * print(uncompressed_data) --> This is a string with uncompressed data.
30
+ * ```ts
31
+ * const data = "\120\94\11\201\200\44\86\0\162\68\133\226\146\162\204\188\116\133\242\204\146\12\133\210\188\228\252\220\130\162\212\226\226\212\20\133\148\196\146\68\61\0\44\67\14\201";
32
+ * const uncompressed_data = zlib.inflate(data);
33
+ * print(uncompressed_data); //> This is a string with uncompressed data.
31
34
  * ```
32
35
  */
33
36
  function inflate(buf: string): string;
package/index.d.ts CHANGED
@@ -2,7 +2,6 @@ import "./generated/builtin-messages";
2
2
  import "./src/msg-overloads";
3
3
  import "./src/message-guard";
4
4
  import "./src/message-dispatch";
5
- import "./src/go-overloads";
6
5
  import "./src/engine-globals";
7
6
  import "./generated/b2d";
8
7
  import "./generated/buffer";
@@ -12,6 +11,7 @@ import "./generated/collectionproxy";
12
11
  import "./generated/crash";
13
12
  import "./generated/factory";
14
13
  import "./generated/go";
14
+ import "./src/go-overloads";
15
15
  import "./generated/graphics";
16
16
  import "./generated/gui";
17
17
  import "./generated/http";
@@ -64,5 +64,7 @@ export {
64
64
  SCRIPT_HOOK_NAMES,
65
65
  type ScriptHookName,
66
66
  type ScriptHooks,
67
+ type ScriptProperties,
68
+ type ScriptProperty,
67
69
  } from "./src/lifecycle";
68
70
  export { type WrapOptions, wrapAsAmbientGlobal } from "./src/publish-dts";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defold-typescript/types",
3
- "version": "0.5.5",
3
+ "version": "0.6.0",
4
4
  "description": "TypeScript types for the Defold engine's Lua APIs.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,6 +20,9 @@
20
20
  "./render-script": {
21
21
  "types": "./generated/kinds/render-script.d.ts"
22
22
  },
23
+ "./core-types": {
24
+ "types": "./src/core-types.ts"
25
+ },
23
26
  "./package.json": "./package.json"
24
27
  },
25
28
  "files": [
@@ -39,7 +42,8 @@
39
42
  "build": "tsc -p tsconfig.build.json",
40
43
  "typecheck": "tsc -p tsconfig.json --noEmit",
41
44
  "regen": "bun scripts/regen.ts",
42
- "sync-api-docs": "bun scripts/sync-api-docs.ts"
45
+ "sync-api-docs": "bun scripts/sync-api-docs.ts",
46
+ "ref-doc-delta": "bun scripts/ref-doc-delta.ts --target defold-1.9.8 --namespace label --present label.get_text --absent label.set_text"
43
47
  },
44
48
  "devDependencies": {
45
49
  "@typescript-to-lua/language-extensions": "1.19.0"
@@ -5,8 +5,11 @@ import {
5
5
  buildTableDocResolver,
6
6
  HOMOGENEOUS_ARRAY_SLOTS,
7
7
  MAPPING_TABLE_SLOTS,
8
+ type NestedMapping,
8
9
  parseTableFields,
9
10
  recoverCallbackSignature,
11
+ TABLE_SLOT_CURATIONS,
12
+ type TableSlotCuration,
10
13
  TS_IDENTIFIER,
11
14
  } from "../src/emit-dts";
12
15
  import { parseMessagesDoc } from "../src/emit-messages";
@@ -113,6 +116,7 @@ function auditEntry(
113
116
  arbitraryTable = false,
114
117
  mappingSlot?: { key: string; value: string },
115
118
  homogeneousElement?: string | readonly string[],
119
+ tableSlotCuration?: TableSlotCuration,
116
120
  ) => {
117
121
  for (const token of types) {
118
122
  // A `table` slot whose doc carries a parseable `<dl>` field list is
@@ -127,6 +131,29 @@ function auditEntry(
127
131
  // the curated key/value tokens — not a `Record`, so don't count it.
128
132
  // Feed the curated tokens back through considerTypes so an unmapped one
129
133
  // still surfaces under unknownTokens (none today: hash/node/vector3 map).
134
+ if (tableSlotCuration?.kind === "mapping") {
135
+ // A single-token value feeds straight back; an object-valued mapping
136
+ // (`LuaMap<K, { … }>`) feeds the key plus each curated field type, the
137
+ // same way the object branch does; a nested-mapping value
138
+ // (`LuaMap<K, LuaMap<K, V>>`) feeds the outer key plus the inner
139
+ // key/value tokens — so an unmapped token in any arm still surfaces.
140
+ if (typeof tableSlotCuration.value === "string") {
141
+ considerTypes([tableSlotCuration.key, tableSlotCuration.value]);
142
+ } else if (Array.isArray(tableSlotCuration.value)) {
143
+ considerTypes([tableSlotCuration.key]);
144
+ for (const field of tableSlotCuration.value) {
145
+ if (field.fields !== undefined) {
146
+ for (const nested of field.fields) considerTypes(nested.types);
147
+ } else if (field.numberList !== true) {
148
+ considerTypes(field.types);
149
+ }
150
+ }
151
+ } else {
152
+ const nested = tableSlotCuration.value as NestedMapping;
153
+ considerTypes([tableSlotCuration.key, nested.key, nested.value]);
154
+ }
155
+ continue;
156
+ }
130
157
  if (mappingSlot !== undefined) {
131
158
  considerTypes([mappingSlot.key, mappingSlot.value]);
132
159
  continue;
@@ -136,6 +163,24 @@ function auditEntry(
136
163
  // `Record`, so don't count it. Feed the curated token(s) back through
137
164
  // considerTypes so an unmapped one still surfaces under unknownTokens
138
165
  // (none today: number/hash/string/url map).
166
+ if (tableSlotCuration?.kind === "array") {
167
+ considerTypes(
168
+ typeof tableSlotCuration.element === "string"
169
+ ? [tableSlotCuration.element]
170
+ : tableSlotCuration.element,
171
+ );
172
+ continue;
173
+ }
174
+ if (tableSlotCuration?.kind === "object" || tableSlotCuration?.kind === "array-object") {
175
+ for (const field of tableSlotCuration.fields) {
176
+ if (field.fields !== undefined) {
177
+ for (const nested of field.fields) considerTypes(nested.types);
178
+ } else if (field.numberList !== true) {
179
+ considerTypes(field.types);
180
+ }
181
+ }
182
+ continue;
183
+ }
139
184
  if (homogeneousElement !== undefined) {
140
185
  considerTypes(
141
186
  typeof homogeneousElement === "string" ? [homogeneousElement] : homogeneousElement,
@@ -236,26 +281,37 @@ function auditEntry(
236
281
  const homogeneousElement =
237
282
  typeof element.name === "string" ? HOMOGENEOUS_ARRAY_SLOTS.get(element.name) : undefined;
238
283
  params.forEach((param, index) => {
284
+ const tableSlotCuration =
285
+ typeof element.name === "string" && typeof param.name === "string"
286
+ ? TABLE_SLOT_CURATIONS.get(tableSlotKey(element.name, "param", param.name))
287
+ : undefined;
239
288
  considerTypes(
240
289
  stringArray(param.types),
241
290
  docString(param.doc),
242
291
  arbitraryTable,
243
292
  mappingSlot,
244
293
  homogeneousElement,
294
+ tableSlotCuration,
245
295
  );
246
296
  // Residual: a doc-optional param the emitter cannot mark `?` because a
247
297
  // required param follows it. The trailing-run cutoff must match
248
298
  // emit-dts so the gate and the emitted surface agree.
249
299
  if (isDocOptional(param) && index < cutoff) optionalAsRequired += 1;
250
300
  });
251
- for (const ret of returns)
301
+ for (const ret of returns) {
302
+ const tableSlotCuration =
303
+ typeof element.name === "string" && typeof ret.name === "string"
304
+ ? TABLE_SLOT_CURATIONS.get(tableSlotKey(element.name, "return", ret.name))
305
+ : undefined;
252
306
  considerTypes(
253
307
  stringArray(ret.types),
254
308
  docString(ret.doc),
255
309
  arbitraryTable,
256
310
  mappingSlot,
257
311
  homogeneousElement,
312
+ tableSlotCuration,
258
313
  );
314
+ }
259
315
  }
260
316
 
261
317
  return {
@@ -274,6 +330,10 @@ function stripNamespace(name: string): string {
274
330
  return index === -1 ? name : name.slice(index + 1);
275
331
  }
276
332
 
333
+ function tableSlotKey(elementName: string, slotKind: "param" | "return", slotName: string): string {
334
+ return `${elementName}:${slotKind}:${slotName}`;
335
+ }
336
+
277
337
  export function buildFidelityReport(
278
338
  manifest: readonly ModuleManifestEntry[] = MODULE_MANIFEST,
279
339
  ): Record<string, FidelityEntry> {
@@ -26,7 +26,7 @@
26
26
  "collectionfactory": {
27
27
  "droppedElements": 0,
28
28
  "unknownTokens": [],
29
- "recordTables": 2,
29
+ "recordTables": 1,
30
30
  "multiReturn": 0,
31
31
  "droppedMembers": 0,
32
32
  "optionalAsRequired": 0
@@ -60,7 +60,7 @@
60
60
  "unknownTokens": [],
61
61
  "recordTables": 2,
62
62
  "multiReturn": 0,
63
- "droppedMembers": 2,
63
+ "droppedMembers": 3,
64
64
  "optionalAsRequired": 0
65
65
  },
66
66
  "graphics": {
@@ -90,7 +90,7 @@
90
90
  "iac": {
91
91
  "droppedElements": 0,
92
92
  "unknownTokens": [],
93
- "recordTables": 1,
93
+ "recordTables": 0,
94
94
  "multiReturn": 0,
95
95
  "droppedMembers": 0,
96
96
  "optionalAsRequired": 0
@@ -98,7 +98,7 @@
98
98
  "iap": {
99
99
  "droppedElements": 0,
100
100
  "unknownTokens": [],
101
- "recordTables": 3,
101
+ "recordTables": 0,
102
102
  "multiReturn": 0,
103
103
  "droppedMembers": 0,
104
104
  "optionalAsRequired": 0
@@ -130,7 +130,7 @@
130
130
  "liveupdate": {
131
131
  "droppedElements": 0,
132
132
  "unknownTokens": [],
133
- "recordTables": 1,
133
+ "recordTables": 0,
134
134
  "multiReturn": 0,
135
135
  "droppedMembers": 0,
136
136
  "optionalAsRequired": 0
@@ -138,7 +138,7 @@
138
138
  "model": {
139
139
  "droppedElements": 0,
140
140
  "unknownTokens": [],
141
- "recordTables": 2,
141
+ "recordTables": 0,
142
142
  "multiReturn": 0,
143
143
  "droppedMembers": 0,
144
144
  "optionalAsRequired": 0
@@ -162,7 +162,7 @@
162
162
  "physics": {
163
163
  "droppedElements": 0,
164
164
  "unknownTokens": [],
165
- "recordTables": 5,
165
+ "recordTables": 3,
166
166
  "multiReturn": 0,
167
167
  "droppedMembers": 0,
168
168
  "optionalAsRequired": 0
@@ -178,7 +178,7 @@
178
178
  "push": {
179
179
  "droppedElements": 0,
180
180
  "unknownTokens": [],
181
- "recordTables": 4,
181
+ "recordTables": 0,
182
182
  "multiReturn": 0,
183
183
  "droppedMembers": 0,
184
184
  "optionalAsRequired": 0
@@ -202,7 +202,7 @@
202
202
  "socket": {
203
203
  "droppedElements": 0,
204
204
  "unknownTokens": [],
205
- "recordTables": 8,
205
+ "recordTables": 4,
206
206
  "multiReturn": 0,
207
207
  "droppedMembers": 0,
208
208
  "optionalAsRequired": 0
@@ -234,7 +234,7 @@
234
234
  "tilemap": {
235
235
  "droppedElements": 0,
236
236
  "unknownTokens": [],
237
- "recordTables": 2,
237
+ "recordTables": 0,
238
238
  "multiReturn": 0,
239
239
  "droppedMembers": 0,
240
240
  "optionalAsRequired": 0