Huge world size, and saves are gzip-compressed (about 60x smaller) (t3)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 17:51:42 -04:00
co-authored by Claude Opus 5.5
parent 06f8f90f19
commit 282e9ce9ab
4 changed files with 65 additions and 10 deletions
+35 -4
View File
@@ -782,12 +782,42 @@ with sync_playwright() as p:
pg.keyboard.press('Escape'); settle(100)
check('pause opens', ev("!$('m-pause').hidden"))
pg.click('#pm-save'); settle(800)
check('saved buffers are compressed and smaller than raw buffers', ev("""async () => {
const sv = await DB.get(`${GAME.worldId}:main`), raw = serializeWorld().buffers;
return Object.values(sv.buffers).every(b => b.gz === true) &&
Object.values(sv.buffers).reduce((n, b) => n + b.bytes.byteLength, 0) <
Object.values(raw).reduce((n, b) => n + b.byteLength, 0);
}"""))
check('buffer packing preserves types and subarray bounds', ev("""async () => {
for (const C of [Uint8Array, Uint8ClampedArray, Int8Array, Uint16Array, Int16Array, Uint32Array, Int32Array, Float32Array, Float64Array, BigInt64Array, BigUint64Array]) {
const a = new C(4); a[1] = C === BigInt64Array || C === BigUint64Array ? 17n : 17;
const b = (await unpackBuffers(await packBuffers({a: a.subarray(1, 3)}))).a;
if (b.constructor !== C || b.length !== 2 || b[0] !== a[1] || b[1] !== a[2]) return false;
}
try { await unpackBuffers({a: {gz: true, type: 'constructor'}}); return false; }
catch (e) { return e.message.includes('Unknown saved buffer type'); }
}"""))
check('packing falls back to raw arrays without CompressionStream', ev("""async () => {
const cs = window.CompressionStream, a = new Uint16Array([7, 42]);
try { window.CompressionStream = undefined; return (await unpackBuffers(await packBuffers({a}))).a === a; }
finally { window.CompressionStream = cs; }
}"""))
bag_before = ev('bagTotal'); blocks_before = ev('blockP.reduce((a,v)=>a+(v>0),0)')
pg.click('#pm-title'); settle(1200)
check('back at title with continue', ev("!$('title').hidden && !$('btn-continue').hidden"))
pg.click('#btn-continue'); pg.wait_for_function('GAME.running === true', timeout=10000); settle(500)
check('continue restores bag and blocks', ev('bagTotal') == bag_before and ev('blockP.reduce((a,v)=>a+(v>0),0)') == blocks_before, f"{bag_before}->{ev('bagTotal')}")
check('normal load still restores an old raw save', ev("""async () => {
GAME.paused = true;
const s = serializeWorld(), id = GAME.worldId;
await DB.op('readwrite', st => st.put({...s, savedAt: Date.now() + 1000, playTime: 4567}, `${id}:main`));
const sv = await worldNewest(id);
bagTotal = 0; worldSeed = 0;
return startFromSave(sv) && worldSeed === s.meta.seed && GAME.playTime === 4567 &&
bagTotal === s.meta.bag.reduce((n, v) => n + v, 0);
}"""))
# 9b. selling: goods sell the moment they drop into the dock; orders pay a lump sum and send a truck
ev("SET.cardSeconds = 9; orders = []; nextOrderT = 1e12; R.floaters = [];")
bot_home = ev('[bot.x, bot.y]')
@@ -868,7 +898,7 @@ with sync_playwright() as p:
pg3.wait_for_function('GAME.running === true', timeout=60000)
got = pg3.evaluate('JSON.stringify([W, H, Math.round(money), Math.round(debt), bagTotal])')
check('importing it on the title screen brings the same world back', got == want, f'{want} -> {got}')
pg3.wait_for_function("async () => (await listWorlds()).length === " + str(worlds_before_import + 1))
pg3.wait_for_function("[...$('toasts').children].some(e => e.textContent === 'World imported.')")
check('import adds an independent saved world', pg3.evaluate('GAME.worldId') != ev('GAME.worldId') and pg3.evaluate('listWorlds().then(w => w.length)') == worlds_before_import + 1)
check('world file keeps fog bytes', pg3.evaluate('Array.from(fog)') == fog_want)
pg3.close()
@@ -921,10 +951,11 @@ with sync_playwright() as p:
pg2 = ctx.new_page()
pg2.on('pageerror', lambda e: logs.append(f'PAGEERROR(large): {e}'))
pg2.goto(url); pg2.evaluate('SET.fog = false'); pg2.wait_for_timeout(300)
check('the size menu offers small, medium and large, and no deep world', pg2.evaluate("[...document.querySelectorAll('#nw-size option')].map(o => o.value).join(',')") == '2048x1024,3072x1280,4096x1536', pg2.evaluate("[...document.querySelectorAll('#nw-size option')].map(o => o.value).join(',')"))
pg2.click('#btn-new'); pg2.fill('#nw-seed', '4242'); pg2.select_option('#nw-size', '4096x1536'); pg2.click('#btn-generate')
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.running === true', timeout=90000)
check('large world generates', pg2.evaluate('W === 4096 && H === 1536'), pg2.evaluate('[W, H]'))
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)
pg2.screenshot(path=str(out / '11-deep-magma.png'))
pg2.close()