import { resolveGameAssets } from '../data/assetManifest.js'; // Lazy per-game asset loading. PreloadScene only loads shared assets at // startup; each game's own art (see data/assetManifest.js) is loaded here, // from GameRoomScene, the first time the user enters that game. function isLoaded(scene, d) { if (d.type === 'audio') return scene.cache.audio.exists(d.key); if (d.type === 'json') return scene.cache.json.exists(d.key); // Video lives in its own cache, not the texture manager. if (d.type === 'video') return !!scene.cache.video?.exists(d.key); return scene.textures.exists(d.key); } export function missingGameAssets(scene, slug) { return resolveGameAssets(scene, slug).filter((d) => !isLoaded(scene, d)); } function queueDescriptor(scene, d) { if (d.type === 'spritesheet') { scene.load.spritesheet(d.key, d.path, { frameWidth: d.frameWidth, frameHeight: d.frameHeight }); } else if (d.type === 'audio') { scene.load.audio(d.key, d.path); } else if (d.type === 'json') { scene.load.json(d.key, d.path); } else if (d.type === 'video') { // noAudio: true — these are ambient portrait loops. It also lets them // autoplay, which browsers refuse for anything with an audio track. scene.load.video(d.key, d.path, true); } else { scene.load.image(d.key, d.path); } } // Queue every missing asset for `slug` on the scene's loader without waiting // for the load to finish. For use from a Scene's own preload() — a level // editor booting straight out of PreloadScene, say — where Phaser starts the // queued load automatically once preload() returns, so there's no need for // the completion Promise below. export function queueGameAssets(scene, slug) { missingGameAssets(scene, slug).forEach((d) => queueDescriptor(scene, d)); } // Queue and load every missing asset for `slug` on the scene's loader. Call // from create() only (the loader is idle there). Resolves once the load pass // completes; a failed file logs a warning and the game's usual // textures.exists fallback applies. export function ensureGameAssets(scene, slug, { onProgress } = {}) { const missing = missingGameAssets(scene, slug); if (missing.length === 0) return Promise.resolve(false); for (const d of missing) queueDescriptor(scene, d); return new Promise((resolve) => { const onError = (file) => console.warn(`[assets] failed to load ${file.key} (${file.src})`); if (onProgress) scene.load.on('progress', onProgress); scene.load.on('loaderror', onError); scene.load.once('complete', () => { if (onProgress) scene.load.off('progress', onProgress); scene.load.off('loaderror', onError); resolve(true); }); scene.load.start(); }); }