From 04fa5e0834ee20c8e9ae1f29eed21cbb73a6aecb Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Fri, 25 Sep 2026 16:56:18 -0700 Subject: [PATCH] oskiewar: bring structuredClone to the console's QuickJS v155 crashed every sim tick on the Xbox (replay capture called structuredClone, which QuickJS lacks); the LAN test override used to supply it. The piece now carries its own. Co-Authored-By: Claude Opus 5.5 --- xbox/live/oskiewar.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/xbox/live/oskiewar.js b/xbox/live/oskiewar.js index ea5ea83b88..7c76489665 100644 --- a/xbox/live/oskiewar.js +++ b/xbox/live/oskiewar.js @@ -8,6 +8,23 @@ // front of a palette. Rebase once, here, so time starts at zero whatever the // host reports. The host builds a fresh object per call, so this rewrites // that copy rather than allocating another. +// QuickJS on the console has no structuredClone, and replay capture and +// rollback both lean on it. Typed arrays, aliases, cycles, Sets and Maps +// survive; JSON would corrupt them. +globalThis.structuredClone ||= function clone(value, seen = new Map()) { + if (value === null || typeof value !== "object") return value; + if (seen.has(value)) return seen.get(value); + if (value instanceof ArrayBuffer) return value.slice(0); + if (ArrayBuffer.isView(value)) return new value.constructor(value); + const copy = Array.isArray(value) ? [] : value instanceof Set ? new Set() + : value instanceof Map ? new Map() : {}; + seen.set(value, copy); + if (value instanceof Set) for (const entry of value) copy.add(clone(entry, seen)); + else if (value instanceof Map) for (const [key, entry] of value) + copy.set(clone(key, seen), clone(entry, seen)); + else for (const key of Object.keys(value)) copy[key] = clone(value[key], seen); + return copy; +}; const hostRuntime = runtime; let clockEpoch = null; // Rollback netplay's hooks into the clock and the side effects. The session -- 2.51.2