From 7bbe36c29ea00d97980b03bad15563db50b79ade Mon Sep 17 00:00:00 2001 From: Tim Evans Date: Thu, 16 Jul 2026 22:27:50 +0100 Subject: [PATCH] =?UTF-8?q?Deterministic=20pause=20overlay=20via=20GamePau?= =?UTF-8?q?se=20subclass=20=E2=80=94=20v2.0.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v2.0.3 pauseGame-hook re-injection raced Foundry's own pause re-render: on slower clients the default GAME PAUSED markup landed after our overlay, so pressing Space after an unpause showed the stock screen. Register a DG2GamePause subclass (CONFIG.ui.pause) that applies the radar-scope overlay inside _onRender - part of every render, no timing window. Hook fallbacks retained (with retries) for cores lacking the AppV2 GamePause. Verified with five rapid unpause/pause cycles at 150ms settle. Co-Authored-By: Claude Fable 5 --- module/deltagreen.js | 25 +++++++++++++++++++++++-- system.json | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/module/deltagreen.js b/module/deltagreen.js index b19f2a4..4681db1 100644 --- a/module/deltagreen.js +++ b/module/deltagreen.js @@ -37,6 +37,24 @@ import RitualItemData from "./data/item/ritual.js"; const { Actors, Items } = foundry.documents.collections; Hooks.once("init", async () => { + // Own the pause UI: applying our overlay inside _onRender means it is part + // of EVERY render of the pause application - no hook/timing races. + try { + const BasePause = foundry.applications?.ui?.GamePause; + if (BasePause) { + class DG2GamePause extends BasePause { + /** @override */ + async _onRender(context, options) { + await super._onRender?.(context, options); + applyDG2PauseOverlay(this.element); + } + } + CONFIG.ui.pause = DG2GamePause; + } + } catch (ex) { + console.warn("Delta Green 2 | could not register pause subclass", ex); + } + Object.assign(CONFIG.Actor.dataModels, { // The keys are the types defined in system.json documentTypes.Actor agent: AgentData, @@ -266,8 +284,11 @@ Hooks.on("renderGamePause", (_app, html) => { }); Hooks.on("pauseGame", () => { - // Run after Foundry finishes its own pause render/toggle. - setTimeout(() => applyDG2PauseOverlay(), 60); + // Fallback for cores where the pause subclass isn't registered: re-apply + // after Foundry's own render, with retries to outlast a slow re-render. + for (const delay of [50, 250, 700]) { + setTimeout(() => applyDG2PauseOverlay(), delay); + } }); Hooks.once("ready", () => applyDG2PauseOverlay()); diff --git a/system.json b/system.json index 1411ac3..82a8f20 100644 --- a/system.json +++ b/system.json @@ -15,7 +15,7 @@ "discord": "jalensailin" } ], - "version": "2.0.3", + "version": "2.0.4", "compatibility": { "minimum": "13", "verified": "14",