@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.
- package/app/src/renderer/bootstrap.ts +0 -6
- package/app/src/renderer/feature-log.ts +1 -9
- package/app/src/renderer/mcp-harness.ts +8 -11
- package/app/src/renderer/standard-automation-tools.ts +8 -145
- package/core/src/module/host.ts +3 -6
- package/core/src/module/index.ts +1 -1
- package/core/src/module/module.ts +4 -47
- package/core/src/physics/interface.ts +5 -0
- package/core/src/platform/render-surface.ts +13 -0
- package/core/src/render/canvas-resize-watcher.ts +1 -10
- package/core/src/render/game-renderer.ts +40 -18
- package/core/src/render/index.ts +0 -2
- package/core/src/render/input-manager.ts +7 -7
- package/core/src/render/renderer-module-host.ts +2 -4
- package/core/src/ui-font-scale.ts +5 -38
- package/core/src/worker/rpc.ts +65 -0
- package/dist/.dd-manifest.json +859 -884
- package/dist/app/src/renderer/bootstrap.js +0 -4
- package/dist/app/src/renderer/feature-log.js +1 -10
- package/dist/app/src/renderer/mcp-harness.js +8 -11
- package/dist/app/src/renderer/standard-automation-tools.js +6 -138
- package/dist/core/src/module/host.js +3 -6
- package/dist/core/src/render/canvas-resize-watcher.js +1 -10
- package/dist/core/src/render/game-renderer.js +44 -18
- package/dist/core/src/render/index.js +0 -1
- package/dist/core/src/render/input-manager.js +7 -7
- package/dist/core/src/render/renderer-module-host.js +2 -4
- package/dist/core/src/ui-font-scale.js +5 -38
- package/dist/core/src/worker/rpc.js +59 -0
- package/dist/libraries/blitz-ui/src/native-module.js +8 -1
- package/dist/libraries/devtools/src/native-providers.js +0 -2
- package/dist/libraries/entities/src/model-renderer.js +87 -27
- package/dist/libraries/entities/src/shaders/model.wgsl +13 -4
- package/dist/libraries/networking/src/index.js +1 -0
- package/dist/libraries/networking/src/ws-server.js +387 -0
- package/dist/libraries/physics-rapier/src/api.js +15 -0
- package/dist/libraries/physics-rapier/src/backend.js +15 -0
- package/dist/libraries/physics-rapier/src/rapier-backend.js +5 -0
- package/dist/libraries/postfx/src/post-process-stack.js +1 -3
- package/dist/libraries/sand/src/materials.js +2 -32
- package/dist/libraries/sand/src/sand-world.js +0 -3
- package/dist/modules/devtools/src/api.js +8 -23
- package/dist/modules/devtools/src/data-bridge.js +0 -11
- package/dist/modules/devtools/src/index.js +0 -6
- package/dist/modules/devtools/src/init.js +8 -42
- package/dist/modules/devtools/src/scene-inspector.js +1 -4
- package/dist/modules/devtools/src/worker-sync.js +3 -11
- package/dist/test/src/vision-test.js +1 -3
- package/libraries/blitz-ui/src/native-module.ts +8 -1
- package/libraries/devtools/src/native-providers.ts +0 -2
- package/libraries/entities/src/model-renderer.ts +88 -27
- package/libraries/entities/src/shaders/model.wgsl +13 -4
- package/libraries/networking/src/index.ts +4 -0
- package/libraries/networking/src/ws-server.ts +397 -0
- package/libraries/physics-rapier/src/api.ts +15 -0
- package/libraries/physics-rapier/src/backend.ts +15 -0
- package/libraries/physics-rapier/src/rapier-backend.ts +6 -0
- package/libraries/postfx/src/post-process-stack.ts +1 -2
- package/libraries/sand/src/materials.ts +2 -32
- package/libraries/sand/src/sand-world.ts +0 -4
- package/modules/devtools/README.md +1 -3
- package/modules/devtools/src/api.ts +10 -34
- package/modules/devtools/src/data-bridge.ts +0 -16
- package/modules/devtools/src/index.ts +1 -11
- package/modules/devtools/src/init.ts +8 -51
- package/modules/devtools/src/scene-inspector.ts +2 -6
- package/modules/devtools/src/types.ts +5 -90
- package/modules/devtools/src/worker-sync.ts +3 -13
- package/package.json +4 -5
- package/test/src/vision-test.ts +2 -4
- package/core/src/render/sab-canvas-overlay.ts +0 -122
- package/dist/core/src/render/sab-canvas-overlay.js +0 -83
- package/dist/modules/devtools/src/debug-overlay.js +0 -181
- package/dist/modules/devtools/src/doctor-panel.js +0 -163
- package/dist/modules/devtools/src/label-overlay.js +0 -129
- package/dist/modules/devtools/src/material-stats-panel.js +0 -171
- package/dist/modules/devtools/src/sim-stats-panel.js +0 -250
- package/modules/devtools/src/debug-overlay.ts +0 -238
- package/modules/devtools/src/doctor-panel.ts +0 -182
- package/modules/devtools/src/label-overlay.ts +0 -154
- package/modules/devtools/src/material-stats-panel.ts +0 -188
- 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:
|
|
6
|
+
// - Main realm: feeds/commands registered directly on
|
|
7
7
|
// window.__sceneInspector via DevToolsDataBridge.
|
|
8
|
-
// - Worker realm:
|
|
9
|
-
//
|
|
10
|
-
// synchronous reads). Commands are forwarded via worker RPC.
|
|
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
|
-
//
|
|
15
|
-
//
|
|
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
|
|
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
|
-
// ---
|
|
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:
|
|
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
|
|
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
|
-
|
|
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,
|
|
8
|
+
// 4. Wiring sim stats provider, debug overlay provider, etc.
|
|
9
9
|
//
|
|
10
|
-
// Also merges globally-registered
|
|
11
|
-
// singleton (registered by plugins via ctx.devtools.
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
|
140
|
-
//
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
4
|
-
// data feeds
|
|
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,
|
|
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
|
+
"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.
|
|
867
|
+
"@downdraft/platform-native": "^0.4.0-alpha.0"
|
|
869
868
|
},
|
|
870
869
|
"peerDependenciesMeta": {
|
|
871
870
|
"@downdraft/platform-native": {
|
package/test/src/vision-test.ts
CHANGED
|
@@ -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 =
|
|
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 {
|