From 10b413c0f0a31bc9476eed86812b6bb90f82caed Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 1 Apr 2026 13:59:13 +0200 Subject: Add asset preloading system for IC message rendering Fix rendering race conditions where character sprites, pre-animations, and paired character assets were displayed before being downloaded. All assets referenced in an MS packet are now resolved and preloaded into the browser cache before the animation timeline starts. - Add unified assetCache module with session-wide promise caching - Add preloadMessageAssets orchestrator for parallel asset resolution - Cache fileExists HEAD requests so missing files aren't re-probed - Preload all SFX (emote, shout, realization, stab) alongside sprites - Use synchronous setEmoteFromUrl at all render transition points - Graceful fallback to legacy setEmote if preloading times out Co-Authored-By: Claude Opus 4.6 (1M context) --- webAO/utils/fileExists.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'webAO/utils/fileExists.ts') diff --git a/webAO/utils/fileExists.ts b/webAO/utils/fileExists.ts index 1dceb72..748bc1f 100644 --- a/webAO/utils/fileExists.ts +++ b/webAO/utils/fileExists.ts @@ -1,14 +1,15 @@ -export default async function fileExists(url: string): Promise { - return new Promise((resolve) => { +const cache = new Map>(); + +export default function fileExists(url: string): Promise { + const cached = cache.get(url); + if (cached !== undefined) return cached; + + const promise = new Promise((resolve) => { const xhr = new XMLHttpRequest(); xhr.open("HEAD", url); xhr.onload = function checkLoad() { if (xhr.readyState === 4) { - if (xhr.status === 200) { - resolve(true); - } else { - resolve(false); - } + resolve(xhr.status === 200); } }; xhr.onerror = function checkError() { @@ -16,4 +17,7 @@ export default async function fileExists(url: string): Promise { }; xhr.send(null); }); + + cache.set(url, promise); + return promise; } -- cgit