@downdraft/engine 0.3.0 → 0.4.0-alpha.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 (82) hide show
  1. package/app/src/renderer/bootstrap.ts +0 -6
  2. package/app/src/renderer/feature-log.ts +1 -9
  3. package/app/src/renderer/mcp-harness.ts +8 -11
  4. package/app/src/renderer/standard-automation-tools.ts +8 -145
  5. package/core/src/module/host.ts +3 -6
  6. package/core/src/module/index.ts +1 -1
  7. package/core/src/module/module.ts +4 -47
  8. package/core/src/physics/interface.ts +5 -0
  9. package/core/src/platform/render-surface.ts +13 -0
  10. package/core/src/render/canvas-resize-watcher.ts +1 -10
  11. package/core/src/render/game-renderer.ts +40 -18
  12. package/core/src/render/index.ts +0 -2
  13. package/core/src/render/input-manager.ts +7 -7
  14. package/core/src/render/renderer-module-host.ts +2 -4
  15. package/core/src/ui-font-scale.ts +5 -38
  16. package/core/src/worker/rpc.ts +65 -0
  17. package/dist/.dd-manifest.json +859 -884
  18. package/dist/app/src/renderer/bootstrap.js +0 -4
  19. package/dist/app/src/renderer/feature-log.js +1 -10
  20. package/dist/app/src/renderer/mcp-harness.js +8 -11
  21. package/dist/app/src/renderer/standard-automation-tools.js +6 -138
  22. package/dist/core/src/module/host.js +3 -6
  23. package/dist/core/src/render/canvas-resize-watcher.js +1 -10
  24. package/dist/core/src/render/game-renderer.js +44 -18
  25. package/dist/core/src/render/index.js +0 -1
  26. package/dist/core/src/render/input-manager.js +7 -7
  27. package/dist/core/src/render/renderer-module-host.js +2 -4
  28. package/dist/core/src/ui-font-scale.js +5 -38
  29. package/dist/core/src/worker/rpc.js +59 -0
  30. package/dist/libraries/blitz-ui/src/native-module.js +8 -1
  31. package/dist/libraries/devtools/src/native-providers.js +0 -2
  32. package/dist/libraries/entities/src/model-renderer.js +87 -27
  33. package/dist/libraries/entities/src/shaders/model.wgsl +13 -4
  34. package/dist/libraries/networking/src/index.js +1 -0
  35. package/dist/libraries/networking/src/ws-server.js +387 -0
  36. package/dist/libraries/physics-rapier/src/api.js +15 -0
  37. package/dist/libraries/physics-rapier/src/backend.js +15 -0
  38. package/dist/libraries/physics-rapier/src/rapier-backend.js +5 -0
  39. package/dist/libraries/postfx/src/post-process-stack.js +1 -3
  40. package/dist/libraries/sand/src/materials.js +2 -32
  41. package/dist/libraries/sand/src/sand-world.js +0 -3
  42. package/dist/modules/devtools/src/api.js +8 -23
  43. package/dist/modules/devtools/src/data-bridge.js +0 -11
  44. package/dist/modules/devtools/src/index.js +0 -6
  45. package/dist/modules/devtools/src/init.js +8 -42
  46. package/dist/modules/devtools/src/scene-inspector.js +1 -4
  47. package/dist/modules/devtools/src/worker-sync.js +3 -11
  48. package/dist/test/src/vision-test.js +1 -3
  49. package/libraries/blitz-ui/src/native-module.ts +8 -1
  50. package/libraries/devtools/src/native-providers.ts +0 -2
  51. package/libraries/entities/src/model-renderer.ts +88 -27
  52. package/libraries/entities/src/shaders/model.wgsl +13 -4
  53. package/libraries/networking/src/index.ts +4 -0
  54. package/libraries/networking/src/ws-server.ts +397 -0
  55. package/libraries/physics-rapier/src/api.ts +15 -0
  56. package/libraries/physics-rapier/src/backend.ts +15 -0
  57. package/libraries/physics-rapier/src/rapier-backend.ts +6 -0
  58. package/libraries/postfx/src/post-process-stack.ts +1 -2
  59. package/libraries/sand/src/materials.ts +2 -32
  60. package/libraries/sand/src/sand-world.ts +0 -4
  61. package/modules/devtools/README.md +1 -3
  62. package/modules/devtools/src/api.ts +10 -34
  63. package/modules/devtools/src/data-bridge.ts +0 -16
  64. package/modules/devtools/src/index.ts +1 -11
  65. package/modules/devtools/src/init.ts +8 -51
  66. package/modules/devtools/src/scene-inspector.ts +2 -6
  67. package/modules/devtools/src/types.ts +5 -90
  68. package/modules/devtools/src/worker-sync.ts +3 -13
  69. package/package.json +4 -5
  70. package/test/src/vision-test.ts +2 -4
  71. package/core/src/render/sab-canvas-overlay.ts +0 -122
  72. package/dist/core/src/render/sab-canvas-overlay.js +0 -83
  73. package/dist/modules/devtools/src/debug-overlay.js +0 -181
  74. package/dist/modules/devtools/src/doctor-panel.js +0 -163
  75. package/dist/modules/devtools/src/label-overlay.js +0 -129
  76. package/dist/modules/devtools/src/material-stats-panel.js +0 -171
  77. package/dist/modules/devtools/src/sim-stats-panel.js +0 -250
  78. package/modules/devtools/src/debug-overlay.ts +0 -238
  79. package/modules/devtools/src/doctor-panel.ts +0 -182
  80. package/modules/devtools/src/label-overlay.ts +0 -154
  81. package/modules/devtools/src/material-stats-panel.ts +0 -188
  82. package/modules/devtools/src/sim-stats-panel.ts +0 -272
@@ -3,23 +3,21 @@
3
3
  // engine systems, regardless of which thread they run on.
4
4
  //
5
5
  // Realm detection determines transport:
6
- // - Main realm: panels/feeds/commands registered directly on
6
+ // - Main realm: feeds/commands registered directly on
7
7
  // window.__sceneInspector via DevToolsDataBridge.
8
- // - Worker realm: panels/feeds/commands registered in a worker-side
9
- // registry. Data feeds are written to a devtools SAB region (zero-copy,
10
- // synchronous reads). Commands are forwarded via worker RPC. Panel
11
- // declarations are synced to the renderer via a one-time manifest RPC.
8
+ // - Worker realm: feeds/commands registered in a worker-side registry.
9
+ // Data feeds are written to a devtools SAB region (zero-copy,
10
+ // synchronous reads). Commands are forwarded via worker RPC.
12
11
  //
13
12
  // Plugins import `devtools` from @downdraft/engine/modules/devtools and call
14
- // registerPanel/registerDataFeed/registerCommand/registerSABStat — the same
15
- // API works in both realms.
13
+ // registerDataFeed/registerCommand/registerSABStat — the same API works in
14
+ // both realms.
16
15
  // ============================================================================
17
16
 
18
17
  import { resourceToken } from "@downdraft/engine/ecs/resource";
19
18
  import { createLogger } from "@downdraft/engine/util/logger";
20
19
  import type { DebugViewDescriptor } from "./debug-view-descriptors";
21
20
  import { BUILTIN_VIEW_DESCRIPTORS } from "./debug-view-descriptors";
22
- import type { IDevToolsOverlayToggle, IDevToolsPanelExtension } from "./types";
23
21
 
24
22
  const log = createLogger("info");
25
23
 
@@ -56,7 +54,7 @@ export const DEVTOOLS_REALM = detectRealm();
56
54
  // synchronously. No RPC polling needed.
57
55
  //
58
56
  // Layout:
59
- // [0..3] manifestVersion: Uint32 (bumped when panels/feeds change)
57
+ // [0..3] manifestVersion: Uint32 (bumped when feeds/commands change)
60
58
  // [4..7] feedCount: Uint32
61
59
  // [8..] feed entries: each is [lengthBytes: Uint32][JSON bytes...]
62
60
  // (lengthBytes = 0 means "not yet written" / "unavailable")
@@ -124,11 +122,7 @@ export interface DevToolsAPI {
124
122
  /** Current realm ("main" or "worker"). */
125
123
  readonly realm: "main" | "worker";
126
124
 
127
- // --- Panels & toggles (declarative, realm-transparent) ---
128
- registerPanel(ext: IDevToolsPanelExtension): void;
129
- registerOverlayToggle(toggle: IDevToolsOverlayToggle): void;
130
-
131
- // --- Data feeds (read by panel, realm chooses transport) ---
125
+ // --- Data feeds (read by devtools frontends, realm chooses transport) ---
132
126
  // In main realm: fn is called directly when the panel queries __sceneInspector.
133
127
  // In worker realm: fn is called each tick (or at writeRate), result JSON-serialized
134
128
  // to the devtools SAB. Renderer reads synchronously from SAB.
@@ -165,7 +159,7 @@ export interface DevToolsAPI {
165
159
  getViews(): DebugViewDescriptor[];
166
160
 
167
161
  // --- Manifest (renderer fetches from worker via RPC) ---
168
- /** Get the full manifest: panels, toggles, data feed names, commands, SAB stats. */
162
+ /** Get the full manifest: data feed names, commands, SAB stats. */
169
163
  getManifest(): DevToolsManifest;
170
164
 
171
165
  // --- Worker tick hook ---
@@ -178,8 +172,6 @@ export interface DevToolsAPI {
178
172
  }
179
173
 
180
174
  export interface DevToolsManifest {
181
- panels: IDevToolsPanelExtension[];
182
- toggles: IDevToolsOverlayToggle[];
183
175
  dataFeeds: { name: string; feedIndex: number; writeRateHz: number }[];
184
176
  commands: string[];
185
177
  sabStats: DevToolsSABStat[];
@@ -200,8 +192,6 @@ interface RegisteredDataFeed {
200
192
  class DevToolsAPIImpl implements DevToolsAPI {
201
193
  readonly realm: "main" | "worker";
202
194
 
203
- private panels = new Map<string, IDevToolsPanelExtension>();
204
- private toggles = new Map<string, IDevToolsOverlayToggle>();
205
195
  private dataFeeds = new Map<string, RegisteredDataFeed>();
206
196
  private dataFeedNames: string[] = []; // ordered list for feedIndex assignment
207
197
  private commands = new Map<string, (...args: any[]) => any>();
@@ -223,16 +213,6 @@ class DevToolsAPIImpl implements DevToolsAPI {
223
213
  this.realm = realm;
224
214
  }
225
215
 
226
- registerPanel(ext: IDevToolsPanelExtension): void {
227
- this.panels.set(ext.id, ext);
228
- this.bumpManifest();
229
- }
230
-
231
- registerOverlayToggle(toggle: IDevToolsOverlayToggle): void {
232
- this.toggles.set(toggle.id, toggle);
233
- this.bumpManifest();
234
- }
235
-
236
216
  registerDataFeed(name: string, fn: () => any, writeRateHz: number = 10): void {
237
217
  if (this.dataFeeds.has(name)) {
238
218
  // Update fn/rate, keep feedIndex and hasWritten
@@ -318,8 +298,6 @@ class DevToolsAPIImpl implements DevToolsAPI {
318
298
 
319
299
  getManifest(): DevToolsManifest {
320
300
  return {
321
- panels: Array.from(this.panels.values()),
322
- toggles: Array.from(this.toggles.values()),
323
301
  dataFeeds: this.dataFeedNames.map((name, i) => ({
324
302
  name,
325
303
  feedIndex: i,
@@ -414,8 +392,6 @@ class DevToolsAPIImpl implements DevToolsAPI {
414
392
  }
415
393
 
416
394
  clear(): void {
417
- this.panels.clear();
418
- this.toggles.clear();
419
395
  this.dataFeeds.clear();
420
396
  this.dataFeedNames = [];
421
397
  this.commands.clear();
@@ -443,7 +419,7 @@ const _devtools = new DevToolsAPIImpl(DEVTOOLS_REALM);
443
419
  * the appropriate transport for data feeds (direct call vs SAB) and
444
420
  * commands (direct call vs RPC forwarding).
445
421
  *
446
- * Plugins import this and call registerPanel/registerDataFeed/registerCommand.
422
+ * Plugins import this and call registerDataFeed/registerCommand.
447
423
  * The same code works in both realms.
448
424
  */
449
425
  export const devtools: DevToolsAPI = _devtools;
@@ -15,8 +15,6 @@ import { useDebugStore } from "./debug-store";
15
15
  import type {
16
16
  IDebugModeProvider,
17
17
  IDevToolsDataRenderer,
18
- IDevToolsOverlayToggle,
19
- IDevToolsPanelExtension,
20
18
  IPerformanceMetricsProvider,
21
19
  ISimStatsProvider,
22
20
  } from "./types";
@@ -43,16 +41,6 @@ export class DevToolsDataBridge {
43
41
  return null;
44
42
  }
45
43
 
46
- /** Games override this to declare custom DevTools panel tabs. */
47
- protected getPanelExtensions(): IDevToolsPanelExtension[] {
48
- return [];
49
- }
50
-
51
- /** Games override this to declare custom overlay toggles. */
52
- protected getOverlayToggles(): IDevToolsOverlayToggle[] {
53
- return [];
54
- }
55
-
56
44
  /** Games override this to expose sim stats + controls (pause/step/speed/clear). */
57
45
  protected getSimStatsProvider(): ISimStatsProvider | null {
58
46
  return null;
@@ -243,10 +231,6 @@ export class DevToolsDataBridge {
243
231
  return this.cachedGpuAdapterInfo;
244
232
  },
245
233
 
246
- // --- Panel extensions (game-specific tabs and overlay toggles) ---
247
- getPanelExtensions: (): IDevToolsPanelExtension[] => this.getPanelExtensions(),
248
- getOverlayToggles: (): IDevToolsOverlayToggle[] => this.getOverlayToggles(),
249
-
250
234
  // --- Sim stats & controls (optional — games implement ISimStatsProvider) ---
251
235
  getSimStats: (): any => this.getSimStatsProvider()?.getSimStats() ?? null,
252
236
  pauseSim: (): void => { this.getSimStatsProvider()?.pauseSim(); },
@@ -16,9 +16,7 @@ export { useSceneStore } from "./scene-store";
16
16
  export type { SceneNode, SceneTreeSnapshot, SimEntitySnapshot } from "./scene-store";
17
17
 
18
18
  // Debug overlays (generic rendering, game provides data via interfaces)
19
- export { DebugOverlay } from "./debug-overlay";
20
19
  export { DebugRaycast } from "./debug-raycast";
21
- export { LabelOverlay } from "./label-overlay";
22
20
  export { SceneSync } from "./scene-sync";
23
21
 
24
22
  // Asset utilities
@@ -26,13 +24,9 @@ export { asyncFetchArrayBuffer, bufferCache, evictThumbnailCache, findBinForGLTF
26
24
 
27
25
  // Data bridge (non-abstract, data-feeds only) & base inspector & interfaces
28
26
  export { DevToolsDataBridge } from "./data-bridge";
29
- export { createDoctorPanelExtension } from "./doctor-panel";
30
- export type { DoctorPanelOptions } from "./doctor-panel";
31
27
  export { BaseSceneInspector } from "./scene-inspector";
32
- export { createSimStatsPanelExtension } from "./sim-stats-panel";
33
- export type { SimStatsPanelOptions } from "./sim-stats-panel";
34
28
  export type {
35
- GameDevToolsTab, IAssetResolver, IAssetUrlMaps, IDebugModeProvider, IDebugOverlayData, IDebugOverlayProvider, IDevToolsDataRenderer, IDevToolsOverlayToggle, IDevToolsPanelExtension, IDevToolsRenderer, IGameDevToolsExtension, IGameDevToolsProvider, ILabelEntry, ILabelProvider, IPerformanceMetricsProvider, IRaycastProvider, IRaycastResult, ISceneEntitySnapshot, ISceneSyncProvider, ISimStats, ISimStatsProvider
29
+ IAssetResolver, IAssetUrlMaps, IDebugModeProvider, IDebugOverlayProvider, IDevToolsDataRenderer, IDevToolsRenderer, IGameDevToolsExtension, IPerformanceMetricsProvider, IRaycastProvider, IRaycastResult, ISceneEntitySnapshot, ISceneSyncProvider, ISimStats, ISimStatsProvider
36
30
  } from "./types";
37
31
 
38
32
  // Unified DevTools API — single registration surface for plugins, games, and
@@ -75,10 +69,6 @@ export type {
75
69
  export { BUILTIN_VIEW_DESCRIPTORS } from "./debug-view-descriptors";
76
70
  export type { BuiltinViewKind, DebugViewDescriptor } from "./debug-view-descriptors";
77
71
 
78
- // Material stats panel — reusable DevTools tab for the material system
79
- export { createMaterialStatsPanelExtension } from "./material-stats-panel";
80
- export type { MaterialStatsPanelOptions } from "./material-stats-panel";
81
-
82
72
  // Blitz devtools — docked in-window DevTools UI (F12)
83
73
  export { BlitzDevtoolsHost, createSelfHostedDevtoolsUi } from "./blitz/host";
84
74
  export type { BlitzDevtoolsOptions, DevtoolsUiSurface } from "./blitz/host";
@@ -5,10 +5,10 @@
5
5
  // 1. Creating an IDevToolsDataRenderer adapter
6
6
  // 2. Instantiating DevToolsDataBridge (or BaseSceneInspector)
7
7
  // 3. Calling init()
8
- // 4. Wiring sim stats provider, panel extensions, overlay toggles, etc.
8
+ // 4. Wiring sim stats provider, debug overlay provider, etc.
9
9
  //
10
- // Also merges globally-registered panels/feeds/commands from the `devtools`
11
- // singleton (registered by plugins via ctx.devtools.registerPanel() etc.)
10
+ // Also merges globally-registered feeds/commands from the `devtools`
11
+ // singleton (registered by plugins via ctx.devtools.registerDataFeed() etc.)
12
12
  // and from worker manifests (via syncWorkerManifests).
13
13
  //
14
14
  // Returns the bridge instance for games that need post-init calls
@@ -24,8 +24,6 @@ import type {
24
24
  IAssetResolver,
25
25
  IDebugModeProvider,
26
26
  IDebugOverlayProvider,
27
- IDevToolsOverlayToggle,
28
- IDevToolsPanelExtension,
29
27
  IDevToolsRenderer,
30
28
  IPerformanceMetricsProvider,
31
29
  ISimStatsProvider,
@@ -33,10 +31,6 @@ import type {
33
31
  import { syncWorkerManifests, type WorkerSyncEntry } from "./worker-sync";
34
32
 
35
33
  export interface InitDevToolsOptions {
36
- // --- Panel extensions & toggles (game-declared) ---
37
- panels?: IDevToolsPanelExtension[];
38
- overlayToggles?: IDevToolsOverlayToggle[];
39
-
40
34
  // --- Providers (game-specific) ---
41
35
  simStatsProvider?: ISimStatsProvider & { start?: () => void; stop?: () => void };
42
36
  debugOverlayProvider?: IDebugOverlayProvider;
@@ -67,7 +61,7 @@ export interface InitDevToolsOptions {
67
61
 
68
62
  /**
69
63
  * Initialize DevTools with one call. Creates the bridge, wires all providers,
70
- merges globally-registered panels/feeds/commands, syncs worker manifests,
64
+ * merges globally-registered feeds/commands, syncs worker manifests,
71
65
  * and exposes the API on window.__sceneInspector.
72
66
  *
73
67
  * Returns the bridge instance.
@@ -81,20 +75,7 @@ export async function initDevTools(renderer: any, options: InitDevToolsOptions =
81
75
  || !!options.bridgeClass
82
76
  || isSceneRenderer(renderer);
83
77
 
84
- // 3. Register game-declared panels/toggles into the global registry
85
- // (these merge with plugin-registered ones)
86
- if (options.panels) {
87
- options.panels.forEach((panel) => {
88
- devtools.registerPanel(panel);
89
- });
90
- }
91
- if (options.overlayToggles) {
92
- options.overlayToggles.forEach((toggle) => {
93
- devtools.registerOverlayToggle(toggle);
94
- });
95
- }
96
-
97
- // 4. Sync worker manifests (fetches panels/feeds/commands from sim workers)
78
+ // 4. Sync worker manifests (fetches feeds/commands from sim workers)
98
79
  if (options.workerHosts && options.workerHosts.length > 0) {
99
80
  await syncWorkerManifests(options.workerHosts);
100
81
  }
@@ -136,10 +117,8 @@ export async function initDevTools(renderer: any, options: InitDevToolsOptions =
136
117
  wirePerformanceMetricsProvider(bridge, options.performanceMetricsProvider);
137
118
  }
138
119
 
139
- // 7. Merge globally-registered panels/toggles/feeds/commands into the bridge
140
- // The bridge's getPanelExtensions()/getOverlayToggles() already returns
141
- // game-declared ones; we augment the __sceneInspector API with
142
- // plugin-registered data feeds and commands.
120
+ // 7. Merge globally-registered feeds/commands/SAB stats into the bridge —
121
+ // augments the __sceneInspector API with plugin-registered methods.
143
122
  mergeGlobalRegistrations(bridge);
144
123
 
145
124
  // 8. Initialize the profiling system (if enabled)
@@ -193,10 +172,9 @@ function wirePerformanceMetricsProvider(bridge: DevToolsDataBridge, provider: an
193
172
  }
194
173
 
195
174
  /**
196
- * Merge globally-registered panels, data feeds, and commands from the `devtools`
175
+ * Merge globally-registered data feeds and commands from the `devtools`
197
176
  * singleton into the bridge's __sceneInspector API.
198
177
  *
199
- * - Panels: merged into getPanelExtensions() (game panels + plugin panels)
200
178
  * - Data feeds: added as methods on __sceneInspector (called synchronously)
201
179
  * - Commands: added as methods on __sceneInspector (forwarded to worker or called directly)
202
180
  * - SAB stats: added as methods on __sceneInspector (read from SAB)
@@ -204,27 +182,6 @@ function wirePerformanceMetricsProvider(bridge: DevToolsDataBridge, provider: an
204
182
  function mergeGlobalRegistrations(bridge: DevToolsDataBridge): void {
205
183
  const manifest = devtools.getManifest();
206
184
 
207
- // Augment getPanelExtensions to merge global registry panels
208
- const originalGetPanels = (bridge as any).getPanelExtensions?.bind(bridge);
209
- (bridge as any).getPanelExtensions = (): IDevToolsPanelExtension[] => {
210
- const gamePanels = originalGetPanels?.() ?? [];
211
- // Merge: game panels take precedence on id collisions
212
- const merged = new Map<string, IDevToolsPanelExtension>();
213
- manifest.panels.forEach((p) => { merged.set(p.id, p);; });
214
- gamePanels.forEach((p: any) => { merged.set(p.id, p);; });
215
- return Array.from(merged.values()).sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
216
- };
217
-
218
- // Augment getOverlayToggles to merge global registry toggles
219
- const originalGetToggles = (bridge as any).getOverlayToggles?.bind(bridge);
220
- (bridge as any).getOverlayToggles = (): IDevToolsOverlayToggle[] => {
221
- const gameToggles = originalGetToggles?.() ?? [];
222
- const merged = new Map<string, IDevToolsOverlayToggle>();
223
- manifest.toggles.forEach((t) => { merged.set(t.id, t);; });
224
- gameToggles.forEach((t: any) => { merged.set(t.id, t);; });
225
- return Array.from(merged.values());
226
- };
227
-
228
185
  // Add data feed methods to the __sceneInspector API
229
186
  // These are called synchronously by the panel via callInspector()
230
187
  const api = (window as any).__sceneInspector;
@@ -44,8 +44,6 @@ export abstract class BaseSceneInspector extends DevToolsDataBridge {
44
44
  return null;
45
45
  }
46
46
 
47
- // getPanelExtensions() and getOverlayToggles() inherited from DevToolsDataBridge.
48
-
49
47
  // --- Init ---
50
48
 
51
49
  init(renderer: IDevToolsRenderer): void {
@@ -568,9 +566,7 @@ export abstract class BaseSceneInspector extends DevToolsDataBridge {
568
566
  const cosX = Math.cos(angleX), sinX = Math.sin(angleX);
569
567
 
570
568
  const THUMB_SIZE = 192;
571
- const canvas = document.createElement("canvas");
572
- canvas.width = THUMB_SIZE;
573
- canvas.height = THUMB_SIZE;
569
+ const canvas = new OffscreenCanvas(THUMB_SIZE, THUMB_SIZE);
574
570
  const ctx = canvas.getContext("2d");
575
571
  if (!ctx) return null;
576
572
 
@@ -617,7 +613,7 @@ export abstract class BaseSceneInspector extends DevToolsDataBridge {
617
613
  }
618
614
  }
619
615
 
620
- const dataUrl = canvas.toDataURL("image/png");
616
+ const dataUrl = (canvas as unknown as { toDataURL(type?: string): string }).toDataURL("image/png");
621
617
  this.evictThumbnailCache();
622
618
  this.thumbnailCache.set(path, dataUrl);
623
619
  return dataUrl;
@@ -69,7 +69,9 @@ export interface IAssetResolver {
69
69
  getTextureUrl(uri: string): string | null;
70
70
  }
71
71
 
72
- /** Optional debug overlay toggles — games that support chunk grid / velocity arrows implement this. */
72
+ /** Optional debug draw toggles — games with GPU-side debug overlays
73
+ * (chunk grid, velocity arrows) implement this. Drives the game's own
74
+ * debug rendering, not a DOM overlay. */
73
75
  export interface IDebugOverlayProvider {
74
76
  setShowChunkGrid(show: boolean): void;
75
77
  getShowChunkGrid(): boolean;
@@ -91,73 +93,7 @@ export interface IPerformanceMetricsProvider {
91
93
  getPerformanceMetrics(): any;
92
94
  }
93
95
 
94
- /** Game-specific tab provider — games register custom DevTools tabs via this interface. */
95
- export interface IGameDevToolsProvider {
96
- getTabs(): GameDevToolsTab[];
97
- }
98
-
99
- export interface GameDevToolsTab {
100
- id: string;
101
- label: string;
102
- onActivate(container: HTMLElement): void;
103
- onDeactivate(): void;
104
- }
105
-
106
- /**
107
- * Game-specific DevTools panel extension.
108
- * Games declare tabs with HTML content, CSS, and a JS script that runs
109
- * in the DevTools panel context. The script receives DevToolsPanel helpers
110
- * and returns lifecycle callbacks.
111
- */
112
- export interface IDevToolsPanelExtension {
113
- /** Unique id for this extension (e.g. "debug-info", "game-panel"). */
114
- id: string;
115
- /** Tab label shown in the tab bar. */
116
- tabLabel: string;
117
- /** Tab tooltip. */
118
- tabTooltip?: string;
119
- /** Order/priority for tab placement. Core tabs: 0-100, game tabs: 100+. Default: 100. */
120
- order?: number;
121
- /** __sceneInspector methods that must exist for this tab to be shown. */
122
- requiredMethods?: string[];
123
- /** HTML content for the panel body (inserted into a container div). */
124
- html: string;
125
- /** CSS to inject into the panel document. */
126
- css?: string;
127
- /**
128
- * JS to eval in the panel context. Receives a DevToolsPanelHelpers object
129
- * and returns { onActivate?, onDeactivate?, onRefresh?, onDestroy? }.
130
- */
131
- script?: string;
132
- }
133
-
134
- /**
135
- * Game-specific overlay toggle for the overlays dropdown menu.
136
- */
137
- export interface IDevToolsOverlayToggle {
138
- /** Unique id (e.g. "chunk-grid", "vel-arrows"). */
139
- id: string;
140
- /** Label shown next to the checkbox. */
141
- label: string;
142
- /** __sceneInspector methods that must exist for this toggle to be shown. */
143
- requiredMethods?: string[];
144
- /**
145
- * JS to eval in the panel context. Receives DevToolsPanelHelpers.
146
- * Should set up a checkbox listener on #chk-{id} that calls callInspector.
147
- */
148
- script?: string;
149
- }
150
-
151
- // --- Debug Overlay Data Providers ---
152
-
153
- /** Provides entity data for the 2D debug overlay (chunk grid + velocity arrows). */
154
- export interface IDebugOverlayData {
155
- getEntityCount(): number;
156
- getEntityPosition(i: number): { x: number; y: number; z: number } | null;
157
- getEntityVelocity(i: number): { x: number; y: number; z: number } | null;
158
- getPlayerPosition(): { x: number; z: number } | null;
159
- getChunkGridConfig(): { chunkSize: number; chunksVisible: number };
160
- }
96
+ // --- Debug Raycast Providers ---
161
97
 
162
98
  /** Provides camera state for debug overlays. */
163
99
  export interface IDebugCamera {
@@ -170,8 +106,6 @@ export interface IDebugCamera {
170
106
  far: number;
171
107
  }
172
108
 
173
- // --- Debug Raycast Providers ---
174
-
175
109
  /** Result of a raycast against entities. */
176
110
  export interface IRaycastResult {
177
111
  entityIndex: number;
@@ -196,23 +130,6 @@ export interface IRaycastProvider {
196
130
  ): IRaycastResult | null;
197
131
  }
198
132
 
199
- // --- Label Overlay Providers ---
200
-
201
- /** A single label entry for the HTML label overlay. */
202
- export interface ILabelEntry {
203
- key: string;
204
- text: string;
205
- color: string;
206
- x: number;
207
- y: number;
208
- z: number;
209
- }
210
-
211
- /** Provides label data for the HTML label overlay. */
212
- export interface ILabelProvider {
213
- getLabels(): ILabelEntry[];
214
- }
215
-
216
133
  // --- Scene Sync Providers ---
217
134
 
218
135
  /** Entity snapshot for scene store sync. */
@@ -251,7 +168,6 @@ export interface IGameDevToolsExtension {
251
168
  debugOverlayProvider?: IDebugOverlayProvider;
252
169
  debugModeProvider?: IDebugModeProvider;
253
170
  performanceMetricsProvider?: IPerformanceMetricsProvider;
254
- tabProvider?: IGameDevToolsProvider;
255
171
  }
256
172
 
257
173
  // --- Sim Stats & Controls ---
@@ -274,8 +190,7 @@ export interface ISimStats {
274
190
 
275
191
  /**
276
192
  * Provides sim stats and control methods for the DevTools "Sim" tab.
277
- * Any sim-driven game (2D or 3D) can implement this; the reusable
278
- * `createSimStatsPanelExtension()` factory renders the tab.
193
+ * Any sim-driven game (2D or 3D) can implement this.
279
194
  */
280
195
  export interface ISimStatsProvider {
281
196
  getSimStats(): ISimStats;
@@ -1,16 +1,14 @@
1
1
  // ============================================================================
2
2
  // Renderer-side worker manifest sync — fetches the devtools manifest from
3
- // one or more sim workers via worker RPC, then wires the worker-registered panels,
4
- // data feeds, and commands into the renderer-side __sceneInspector API.
3
+ // one or more sim workers via worker RPC, then wires the worker-registered
4
+ // data feeds and commands into the renderer-side __sceneInspector API.
5
5
  //
6
6
  // Data feeds from workers are read from the devtools SAB (zero-copy).
7
7
  // Commands are forwarded via worker RPC.
8
- // Panel declarations are merged into the global registry.
9
8
  // ============================================================================
10
9
 
11
10
  import { createLogger } from "@downdraft/engine/util/logger";
12
- import { _devtoolsImpl, devtools, type DevToolsManifest } from "./api";
13
- import type { IDevToolsPanelExtension } from "./types";
11
+ import { _devtoolsImpl, type DevToolsManifest } from "./api";
14
12
 
15
13
  const log = createLogger("info");
16
14
 
@@ -79,14 +77,6 @@ async function syncOneWorker(entry: WorkerSyncEntry): Promise<void> {
79
77
  }
80
78
  }
81
79
 
82
- // Register panels (namespaced by prefix to avoid collisions)
83
- manifest.panels.forEach((panel) => {
84
- const namespaced: IDevToolsPanelExtension = prefix
85
- ? { ...panel, id: `${prefix}:${panel.id}` }
86
- : panel;
87
- devtools.registerPanel(namespaced);
88
- });
89
-
90
80
  // Register data feed readers — these read from the SAB synchronously
91
81
  // We register them as main-realm data feeds that read from the worker SAB
92
82
  if (sab) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@downdraft/engine",
3
- "version": "0.3.0",
3
+ "version": "0.4.0-alpha.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/knackstedt/downdraft.git",
@@ -844,13 +844,12 @@
844
844
  },
845
845
  "dependencies": {
846
846
  "@bokuweb/zstd-wasm": "^0.0.27",
847
+ "@dimforge/rapier3d-compat": "^0.19.3",
847
848
  "@gltf-transform/core": "^4.4.2",
848
849
  "@gltf-transform/extensions": "^4.4.2",
849
850
  "@gltf-transform/functions": "^4.4.2",
850
851
  "@h00w/basis-universal-transcoder": "^2.1.0",
851
- "@jitl/quickjs-singlefile-browser-release-sync": "^0.32.0",
852
852
  "acorn": "^8.15.0",
853
- "buffer": "^6.0.3",
854
853
  "comment-json": "^5.0.0",
855
854
  "dns-packet": "^5.6.1",
856
855
  "draco3dgltf": "^1.5.7",
@@ -859,13 +858,13 @@
859
858
  "ktx2-encoder": "^0.6.0",
860
859
  "meshoptimizer": "^1.2.0",
861
860
  "quickjs-emscripten": "^0.32.0",
861
+ "recast-navigation": "^0.43.1",
862
862
  "wgpu-matrix": "^3.4.2",
863
863
  "xxh3-ts": "^2.0.1",
864
- "xxhash-wasm": "^0.4.2",
865
864
  "zustand": "^5.0.2"
866
865
  },
867
866
  "peerDependencies": {
868
- "@downdraft/platform-native": "^0.3.0"
867
+ "@downdraft/platform-native": "^0.4.0-alpha.0"
869
868
  },
870
869
  "peerDependenciesMeta": {
871
870
  "@downdraft/platform-native": {
@@ -251,14 +251,12 @@ export class VisionTest {
251
251
  height: number,
252
252
  ): Promise<string> {
253
253
  const data = await this.captureTexture(texture, width, height);
254
- const canvas = document.createElement("canvas");
255
- canvas.width = width;
256
- canvas.height = height;
254
+ const canvas = new OffscreenCanvas(width, height);
257
255
  const ctx = canvas.getContext("2d")!;
258
256
  const imageData = ctx.createImageData(width, height);
259
257
  imageData.data.set(data);
260
258
  ctx.putImageData(imageData, 0, 0);
261
- return canvas.toDataURL("image/png");
259
+ return (canvas as unknown as { toDataURL(type?: string): string }).toDataURL("image/png");
262
260
  }
263
261
 
264
262
  destroy(): void {