Progress bar and steps while generating, loading, opening claims and travelling; saving chip (t30)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 18:54:06 -04:00
co-authored by Claude Opus 5.5
parent e3280b7b1e
commit 54af0e51ad
14 changed files with 174 additions and 39 deletions
+32
View File
@@ -26,6 +26,24 @@ with sync_playwright() as p:
catch (e) { return await DB.get('abort-test') === undefined; }
return false;
}"""))
check('async generation preserves the world and yields frames with labels', pg.evaluate("""async () => {
const hash = a => { let h = 2166136261; for (const v of a) h = Math.imul(h ^ v, 16777619); return h; };
generateWorld(424242, 2048, 1024); const want = hash(mat);
let frames = 0, active = true, labels = [];
const frameCount = () => { if (active) { frames++; requestAnimationFrame(frameCount); } };
requestAnimationFrame(frameCount);
showLoading(true, 0, '', 'Generating world');
try {
await generateWorldAsync(424242, 2048, 1024, (f, s) => { showLoading(true, f, s); labels.push($('loadstep').textContent); });
return hash(mat) === want && frames > 1 && labels.includes('Settling loose ground') && labels.every(Boolean);
} finally { active = false; showLoading(false); }
}"""))
# Record progress at the browser's own frame boundaries, without slowing the operation.
pg.add_init_script("""
window.__loads = [];
const watch = () => { if (typeof GAME !== 'undefined' && GAME.loading) __loads.push([$('loading').querySelector('.label').textContent, $('loadstep').textContent, $('loadbar').style.width]); requestAnimationFrame(watch); };
requestAnimationFrame(watch);
""")
# Migrate a real legacy save before starting the play-through.
pg.evaluate("generateWorld(12345, 512, 384, null)")
pg.evaluate("async () => { const s = serializeWorld(); await DB.put('main', { ...s, savedAt: Date.now(), playTime: 3661 }); }")
@@ -39,7 +57,18 @@ with sync_playwright() as p:
pg.reload(); pg.wait_for_function("!$('title').hidden && !$('btn-continue').hidden")
check('legacy save becomes World 1 and retires its old key', pg.evaluate("async () => { const w = await listWorlds(); return w.length === 1 && w[0].name === 'World 1' && await DB.get('main') === undefined; }"))
pg.click('#btn-continue'); pg.wait_for_function('GAME.running')
check('Continue paints loading steps', pg.evaluate("__loads.some(([t, s]) => t === 'Loading world' && s === 'Building the world') && !GAME.loading && $('loading').hidden"))
check('Continue loads the migrated seed and playtime', pg.evaluate('worldSeed === 12345 && GAME.playTime >= 3661 && !!GAME.worldId'))
pg.evaluate("""() => {
window.__pack = packBuffers;
packBuffers = async b => { await new Promise(r => setTimeout(r, 600)); return __pack(b); };
window.__saving = saveWorld('main', true);
}""")
pg.locator('#saving').wait_for(state='visible')
pg.screenshot(path=str(out / 'saving-progress.png'))
check('slow save shows the saving chip', pg.is_visible('#saving'))
pg.evaluate('async () => { await __saving; packBuffers = __pack; }')
check('saving chip hides when the save ends', not pg.is_visible('#saving'))
pg.evaluate('quitToTitle()')
names = {}
for seed in [222, 333]:
@@ -53,6 +82,7 @@ with sync_playwright() as p:
pg.screenshot(path=str(out / 'new-world.png'))
pg.fill('#nw-seed', str(seed)); pg.press('#nw-name' if seed == 222 else '#nw-seed', 'Enter')
pg.wait_for_function('GAME.running', timeout=20000)
check(f'new world {seed} paints a moving generation bar', pg.evaluate("__loads.some(([t, s, w]) => t === 'Generating world' && parseFloat(w) > 0 && parseFloat(w) < 90) && !GAME.loading"))
check(f'new world {seed} shows the Welcome card', pg.evaluate("[...$('cards').children].some(c => c.textContent.includes('Welcome'))"))
check(f'pause menu shows world {seed} name', names[seed] in pg.evaluate("() => { openPause(); return $('pause-meta').textContent; }"))
pg.evaluate('quitToTitle()')
@@ -1058,6 +1088,8 @@ with sync_playwright() as p:
check('the size menu offers small, medium, large and huge', pg2.evaluate("[...document.querySelectorAll('#nw-size option')].map(o => o.value).join(',')") == '2048x1024,3072x1280,4096x1536,6144x2048', pg2.evaluate("[...document.querySelectorAll('#nw-size option')].map(o => o.value).join(',')"))
check('Medium remains the default size', pg2.input_value('#nw-size') == '3072x1280')
pg2.click('#btn-new'); pg2.fill('#nw-seed', '4242'); pg2.select_option('#nw-size', '6144x2048'); pg2.click('#btn-generate')
pg2.wait_for_function("GAME.loading && parseFloat($('loadbar').style.width) > 10 && parseFloat($('loadbar').style.width) < 85", timeout=30000)
pg2.screenshot(path=str(out / 'generation-progress.png'))
pg2.wait_for_function('GAME.running === true', timeout=90000)
check('huge world generates', pg2.evaluate('W === 6144 && H === 2048'), pg2.evaluate('[W, H]'))
pg2.evaluate("bot.x = 2000; bot.y = magmaY[2000] - 60; snapCamera();"); pg2.wait_for_timeout(800)