Fog of war: underground is black until the bot has seen it (t8)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+49
-3
@@ -20,7 +20,7 @@ with sync_playwright() as p:
|
||||
logs = []
|
||||
pg.on('pageerror', lambda e: logs.append(f'PAGEERROR: {e}'))
|
||||
pg.on('console', lambda m: logs.append(f'{m.type}: {m.text}') if m.type == 'error' else None)
|
||||
pg.goto(url); pg.wait_for_timeout(300)
|
||||
pg.goto(url); pg.evaluate("SET.fog = false"); pg.wait_for_timeout(300)
|
||||
check('storage transactions roll back when a write throws', pg.evaluate("""async () => {
|
||||
try { await DB.op('readwrite', st => { st.put('partial', 'abort-test'); throw new Error('test abort'); }); }
|
||||
catch (e) { return await DB.get('abort-test') === undefined; }
|
||||
@@ -669,10 +669,12 @@ with sync_playwright() as p:
|
||||
dl = dl_info.value
|
||||
wf = json.loads(pathlib.Path(dl.path()).read_text())
|
||||
check('Export world file downloads a world file', wf.get('format') == 'deepgrain-world' and wf['meta']['W'] == ev('W'), dl.suggested_filename)
|
||||
fog_want = ev('Array.from(fog)')
|
||||
check('world export includes fog bytes', wf['buffers']['fog']['type'] == 'Uint8Array')
|
||||
want = ev('JSON.stringify([W, H, Math.round(money), Math.round(debt), bagTotal])')
|
||||
pg3 = ctx.new_page()
|
||||
pg3.on('pageerror', lambda e: logs.append(f'PAGEERROR(import): {e}'))
|
||||
pg3.goto(url); pg3.wait_for_timeout(300)
|
||||
pg3.goto(url); pg3.evaluate('SET.fog = false'); pg3.wait_for_timeout(300)
|
||||
worlds_before_import = ev('listWorlds().then(w => w.length)')
|
||||
pg3.set_input_files('#importfile', dl.path())
|
||||
pg3.wait_for_function('GAME.running === true', timeout=60000)
|
||||
@@ -680,13 +682,57 @@ with sync_playwright() as p:
|
||||
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))
|
||||
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()
|
||||
pg.keyboard.press('Escape'); settle(150)
|
||||
|
||||
# Fog has its own paused scene; existing play checks keep the whole world visible.
|
||||
fb = p.chromium.launch(args=['--use-gl=angle', '--use-angle=swiftshader', '--enable-unsafe-swiftshader'])
|
||||
fp = fb.new_page(viewport={'width': 1280, 'height': 800})
|
||||
fp.on('pageerror', lambda e: logs.append(f'PAGEERROR(fog): {e}'))
|
||||
fp.add_init_script('window.__allowSoftwareGL = true')
|
||||
fp.goto(url)
|
||||
fp.evaluate('startNewWorld(4242, 512, 384)')
|
||||
fp.wait_for_function('GAME.running')
|
||||
fp.evaluate("""() => {
|
||||
GAME.paused = true; SET.fog = true; SET.look = 'pixel'; SET.zoom = 6; SET.lighting = 'off';
|
||||
SET.cameraLead = false; SET.cameraSmooth = 0; resizeRender();
|
||||
for (let y = 130; y < 280; y++) for (let x = 160; x < 350; x++) setCell(y * W + x, STONE, 20, F_NAT);
|
||||
for (let y = 140; y < 205; y++) for (let x = 240; x < 252; x++) setCell(y * W + x, EMPTY, 20, 0);
|
||||
for (let y = 192; y < 205; y++) for (let x = 240; x < 280; x++) setCell(y * W + x, EMPTY, 20, 0);
|
||||
bot.x = 243; bot.y = 192; fog.fill(0); fogInit(); fogLook(bot.x + 2.5, bot.y + 2.5);
|
||||
snapCamera(); GAME.hidePreviews = true; $('cards').replaceChildren();
|
||||
}""")
|
||||
fp.wait_for_timeout(300)
|
||||
sample = "(() => { drawWorld(); const k = (235 - R.vy0) * R.bw + 300 - R.vx0; return R.px[k] & 0xffffff; })()"
|
||||
check('unexplored pixel is out-of-world black', fp.evaluate(sample) == 0x0a0a0c)
|
||||
check('sky starts seen and draws colour', fp.evaluate("(() => { const cy=R.camY; R.camY=0; drawWorld(); const c=R.px[20*R.bw+20]&0xffffff; R.camY=cy; drawWorld(); return fogSeen(300,0)===255 && c!==0x0a0a0c; })()"))
|
||||
check('unexplored canvas pixel is black', fp.evaluate("(() => {const s=worldToScreenPx(300.5,235.5);return Array.from(R.ctx.getImageData(s.x,s.y,1,1).data).slice(0,3).every(v=>v<=12)})()"))
|
||||
check('hover and cursor share only Unexplored', fp.evaluate("JSON.stringify(hoverInfo(300,235)) === JSON.stringify({t1:'Unexplored',t2:[],t3:[]})"))
|
||||
fp.evaluate("GAME.aim = {x:300,y:235}; renderInfo()")
|
||||
check('info box says only Unexplored', fp.locator('#info').inner_text() == 'Unexplored')
|
||||
check('cursor draws only Unexplored', fp.evaluate("""() => {
|
||||
const old=R.ctx.fillText, inside=GAME.mouse.in, texts=[];
|
||||
R.ctx.fillText=function(t) { texts.push(t); }; GAME.mouse.in=true;
|
||||
drawCursorLabel(500,400,1); R.ctx.fillText=old; GAME.mouse.in=inside;
|
||||
return texts.length===1 && texts[0]==='Unexplored';
|
||||
}"""))
|
||||
fp.screenshot(path=str(out / 'fog-pixel.png'))
|
||||
fp.evaluate('R.lens = true')
|
||||
check('thermal lens hides unexplored grains', fp.evaluate(sample) == 0x0a0a0c)
|
||||
fp.evaluate('R.lens = false; SET.fog = false')
|
||||
check('fog toggle shows the same rock', fp.evaluate(sample) != 0x0a0a0c)
|
||||
fp.evaluate("SET.fog = true; SET.look = 'smooth'; SM.t0 = performance.now() + 100000")
|
||||
fp.wait_for_timeout(500)
|
||||
check('fog draws in the smooth look', fp.evaluate('R.smoothOn && SM.ok'))
|
||||
check('unseen smooth grains have no terrain shape', fp.evaluate("(() => {const k=(235-R.vy0)*R.bw+300-R.vx0;return R.px[k]===0x040a0a0c && R.backPx[k]===0x000a0a0c && R.treePx[k]===0 && R.fieldPx[k]===255})()"))
|
||||
fp.screenshot(path=str(out / 'fog-smooth.png'))
|
||||
fb.close()
|
||||
|
||||
# 11. the largest world from the title screen
|
||||
pg2 = ctx.new_page()
|
||||
pg2.on('pageerror', lambda e: logs.append(f'PAGEERROR(large): {e}'))
|
||||
pg2.goto(url); pg2.wait_for_timeout(300)
|
||||
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')
|
||||
pg2.wait_for_function('GAME.running === true', timeout=90000)
|
||||
|
||||
Reference in New Issue
Block a user