import { Assets, Texture } from 'pixi.js'; import { fetchGameTextureManifest, tryResolveGameAssetFile, type GameTextureManifest, } from './resolveGameAssetUrl'; import { getRequiredSpriteKeys } from './spriteMapping'; export class GameSpriteRegistry { private _manifest: GameTextureManifest | null = null; private _textures = new Map(); private _ready = false; private _buildFallbackManifest(keys: string[]): GameTextureManifest { const textures: Record = {}; for (const key of keys) { let file: string | null = null; if (key.startsWith('terrain.')) file = `tiles/${key}.png`; else if (key.startsWith('prop.')) file = `prop/${key}.png`; else if (key.startsWith('building.')) file = `building/${key}.png`; else if (key.startsWith('enemy.')) file = `enemies/${key}.png`; else if (key.startsWith('npc.') || key.startsWith('hero.')) file = `characters/${key}.png`; if (!file) continue; textures[key] = { file, kind: 'fallback' }; } return { version: 0, note: 'Fallback manifest (generated at runtime).', textures, }; } get ready(): boolean { return this._ready; } get manifest(): GameTextureManifest | null { return this._manifest; } async loadAll(): Promise { const requiredKeys = getRequiredSpriteKeys(); try { this._manifest = await fetchGameTextureManifest(); } catch (error) { console.warn('[Assets] Manifest load failed, using fallback manifest.', error); this._manifest = this._buildFallbackManifest(requiredKeys); } for (const key of requiredKeys) { if (!this._manifest.textures[key]) { console.warn(`[Assets] Missing manifest entry for sprite key: ${key}`); } } const entries = Object.entries(this._manifest.textures); await Promise.all( entries.map(async ([key, entry]) => { const url = tryResolveGameAssetFile(entry.file); if (!url) { console.warn(`[Assets] Missing sprite file in bundle: ${entry.file}`); return; } const texture = await Assets.load(url); // Pixel-art tiles/props: nearest filtering avoids subpixel seam artifacts on tile borders. texture.source.scaleMode = 'nearest'; this._textures.set(key, texture); }), ); this._ready = true; } getTexture(key: string): Texture | null { return this._textures.get(key) ?? null; } }