@downdraft/engine 0.4.2 → 0.4.3

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.
@@ -162,7 +162,7 @@ export async function startGame(module) {
162
162
  // Event kinds emitted by the engine itself (sim-worker-base lifecycle)
163
163
  // that games are not required to handle — suppress the dev warning for
164
164
  // these so autosave doesn't spam the console when no handler is wired.
165
- const ENGINE_EMITTED_EVENT_KINDS = new Set(["ready", "saved", "loaded", "error"]);
165
+ const ENGINE_EMITTED_EVENT_KINDS = new Set(["ready", "saved", "loaded", "error", ...(module.silentEvents ?? [])]);
166
166
  // 4. Wire event routing from the declarative events map (sim-worker only).
167
167
  // Supports both GameSimWorker.onEvent(cb) and SimWorkerHost's
168
168
  // subscribeEvents(cb) (renderer-owned worker hosts).
@@ -239,6 +239,10 @@ export function createStandardAutomationTools(ctx) {
239
239
  code: { type: "string", description: "Key code (e.g. 'KeyI', 'Tab', 'Escape')" },
240
240
  type: { type: "string", enum: ["keydown", "keyup"], default: "keydown" },
241
241
  repeat: { type: "boolean", default: false },
242
+ ctrlKey: { type: "boolean", default: false },
243
+ shiftKey: { type: "boolean", default: false },
244
+ altKey: { type: "boolean", default: false },
245
+ metaKey: { type: "boolean", default: false },
242
246
  },
243
247
  required: ["key"],
244
248
  },
@@ -250,6 +254,8 @@ export function createStandardAutomationTools(ctx) {
250
254
  const ev = new KeyboardEvent(type, {
251
255
  key, code, keyCode: domKeyCodeFor(key),
252
256
  bubbles: true, cancelable: true, repeat: !!params.repeat,
257
+ ctrlKey: !!params.ctrlKey, shiftKey: !!params.shiftKey,
258
+ altKey: !!params.altKey, metaKey: !!params.metaKey,
253
259
  });
254
260
  // Real KeyboardEvent ignores keyCode in the init dict — force it.
255
261
  try {
@@ -12,7 +12,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
12
12
  // embedded — package-native.mjs stages them at <execDir>/dd-assets/
13
13
  // <repo-rel>, so a $bunfs callerDir maps onto the staged tree. The keys
14
14
  // stay identical because both trees share the same relative structure.
15
- const BUNFS_ROOT_RE = /^\/\$bunfs\/root\/|^B:\\~BUN\\root\\/i;
15
+ const BUNFS_ROOT_RE = /^\/\$bunfs\/root\/?|^B:\\~BUN\\root\\?/i;
16
16
  function mapCallerDir(callerDir) {
17
17
  if (!BUNFS_ROOT_RE.test(callerDir))
18
18
  return callerDir;
@@ -2,6 +2,8 @@ export class CanvasResizeWatcher {
2
2
  canvas;
3
3
  handler;
4
4
  dpr = 1;
5
+ /** Explicit override via setDpr — 0 means "track the host's live ratio". */
6
+ dprOverride = 0;
5
7
  onSurfaceResize = () => this.resize();
6
8
  constructor(canvas, handler) {
7
9
  this.canvas = canvas;
@@ -12,10 +14,20 @@ export class CanvasResizeWatcher {
12
14
  this.resize();
13
15
  }
14
16
  resize() {
17
+ // Re-read devicePixelRatio on every resize — on the native host it's a
18
+ // live query (the current monitor's scale factor), so this self-heals
19
+ // when the window crosses between differently-scaled monitors. A cached
20
+ // ratio silently diverges from the surface's clientWidth (which divides
21
+ // the physical extent by the live factor), sizing the swapchain to the
22
+ // wrong extent — wgpu then reports Outdated on every acquire forever.
23
+ const live = (typeof window !== "undefined" ? window.devicePixelRatio : 0) || 0;
24
+ this.dpr = this.dprOverride > 0 ? this.dprOverride : (live > 0 ? live : this.dpr);
15
25
  this.handler.onResize(this.canvas.clientWidth, this.canvas.clientHeight, this.dpr);
16
26
  }
27
+ /** Pin the ratio explicitly (tests, forced-DPR harnesses). 0 resumes
28
+ * live tracking. */
17
29
  setDpr(dpr) {
18
- this.dpr = dpr;
30
+ this.dprOverride = dpr;
19
31
  this.resize();
20
32
  }
21
33
  getDpr() {
@@ -56,8 +56,10 @@ export function createHtmlUi(options) {
56
56
  source: (typeof navCfg === "object" ? navCfg.source : undefined)
57
57
  ?? ctx.injectOptional(GamepadSourceTok)
58
58
  ?? null,
59
- screenW: ctx.getSurface().clientWidth,
60
- screenH: ctx.getSurface().clientHeight,
59
+ // Input space is backing-buffer px (NativeWindow.mapX/Y) — not
60
+ // CSS px (clientWidth diverges at scaleFactor ≠ 1).
61
+ screenW: ctx.getSurface().width,
62
+ screenH: ctx.getSurface().height,
61
63
  })
62
64
  : null;
63
65
  if (nav) {
@@ -122,8 +122,10 @@ export function createHtmlUi(options: HtmlUiOptions): RendererModule {
122
122
  source: (typeof navCfg === "object" ? navCfg.source : undefined)
123
123
  ?? ctx.injectOptional(GamepadSourceTok)
124
124
  ?? null,
125
- screenW: ctx.getSurface().clientWidth,
126
- screenH: ctx.getSurface().clientHeight,
125
+ // Input space is backing-buffer px (NativeWindow.mapX/Y) — not
126
+ // CSS px (clientWidth diverges at scaleFactor ≠ 1).
127
+ screenW: ctx.getSurface().width,
128
+ screenH: ctx.getSurface().height,
127
129
  })
128
130
  : null;
129
131
  if (nav) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@downdraft/engine",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/knackstedt/downdraft.git",
@@ -864,7 +864,7 @@
864
864
  "zustand": "^5.0.2"
865
865
  },
866
866
  "peerDependencies": {
867
- "@downdraft/platform-native": "^0.4.2"
867
+ "@downdraft/platform-native": "^0.4.3"
868
868
  },
869
869
  "peerDependenciesMeta": {
870
870
  "@downdraft/platform-native": {