fix: KAPLAY scene init robustness — wait for layout, catch errors

- FightViewer: wrap createFightScene in try/catch so scene failures
  don't crash every subsequent playRound call
- FightViewer: wait for container to have non-zero dimensions before
  creating canvas (prevents 0x0 canvas causing sprite load failures)
- FightViewer: graceful log-only fallback when scene init fails
- FightPage: same dimension-wait and try/catch for initLiveScene
- Fallback canvas dimensions (800x500) when container not yet laid out

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-08 00:46:50 +00:00
co-authored by Claude Opus 4.6
parent a254a77151
commit 6b139a076a
2 changed files with 24 additions and 10 deletions
+7 -2
View File
@@ -112,12 +112,17 @@ async function initScene() {
const container = canvasContainer.value
if (!container) return
// Wait for container to have dimensions (layout may not be complete yet)
for (let i = 0; i < 10 && (!container.clientWidth || !container.clientHeight); i++) {
await new Promise(r => requestAnimationFrame(r))
}
// Replace canvas element so Kaplay gets a fresh context
const oldCanvas = canvasRef.value
const newCanvas = document.createElement('canvas')
newCanvas.className = 'w-full h-full block'
newCanvas.width = container.clientWidth
newCanvas.height = container.clientHeight
newCanvas.width = container.clientWidth || 800
newCanvas.height = container.clientHeight || 500
if (oldCanvas) {
oldCanvas.replaceWith(newCanvas)
} else {
+17 -8
View File
@@ -305,21 +305,30 @@ async function initLiveScene() {
const container = liveCanvas.value.parentElement
if (container) {
// Wait for container to have dimensions
for (let i = 0; i < 10 && (!container.clientWidth || !container.clientHeight); i++) {
await new Promise(r => requestAnimationFrame(r))
}
const oldCanvas = liveCanvas.value
const newCanvas = document.createElement('canvas')
newCanvas.className = oldCanvas.className
newCanvas.width = container.clientWidth
newCanvas.height = container.clientHeight
newCanvas.width = container.clientWidth || 800
newCanvas.height = container.clientHeight || 500
oldCanvas.replaceWith(newCanvas)
liveCanvas.value = newCanvas
}
liveScene = await createFightScene({
canvas: liveCanvas.value,
botA: { name: data.botA.name, seed: data.botA.avatarSeed || data.botA.name, tier: data.botA.tier, archetype: data.botA.archetype, customization: data.botA.customization, wins: data.botA.wins, losses: data.botA.losses },
botB: { name: data.botB.name, seed: data.botB.avatarSeed || data.botB.name, tier: data.botB.tier, archetype: data.botB.archetype, customization: data.botB.customization, wins: data.botB.wins, losses: data.botB.losses },
arena: data.arena,
})
try {
liveScene = await createFightScene({
canvas: liveCanvas.value,
botA: { name: data.botA.name, seed: data.botA.avatarSeed || data.botA.name, tier: data.botA.tier, archetype: data.botA.archetype, customization: data.botA.customization, wins: data.botA.wins, losses: data.botA.losses },
botB: { name: data.botB.name, seed: data.botB.avatarSeed || data.botB.name, tier: data.botB.tier, archetype: data.botB.archetype, customization: data.botB.customization, wins: data.botB.wins, losses: data.botB.losses },
arena: data.arena,
})
} catch (err) {
console.error('[FightPage] createFightScene failed:', err)
liveScene = null
}
liveSceneReady.value = true