Files
deepgrain-foundry/test/t_lakes.py
T
44r0n7andClaude Opus 5.5 80668a4baf Lakes fill only to their lower rim and keep clear of spawn and the dock (t96)
The lake lip was Math.min(surfY), the highest ground (y grows downward), so water was poured
above the lower rim and, once levelled, ran up to the trade dock on 4 of 12 seeds. The lip is
now the lower rim edge minus one, and each lake stays 80 grains from spawn. Seed hashes and
the shallow-ore hash re-baselined (changes only under lake basins); golden fixtures also
freeze surfY/dirtY/AMB from the previous generator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 19:45:51 -04:00

56 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""t96: flat generated lakes, fresh and reloaded, in the real pixel frame loop."""
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / 'tools'))
from use_venv import ensure_playwright
ensure_playwright()
from browser import launch
errors = []
with launch(viewport={'width':1280,'height':760}) as (_, pg, url):
pg.on('pageerror', lambda e: errors.append(str(e)))
pg.goto(url)
pg.evaluate('CAPS_CHECK')
pg.evaluate('''() => { SET.workerCap=2; SET.fog=false; SET.look='pixel'; SET.autosave=0; SET.cameraLead=false;
const enter=enterGame; enterGame=function(){enter();GAME.paused=true;}; }''')
pg.evaluate('startNewWorld(7,2048,1024)')
pg.wait_for_function('GAME.running',timeout=60000)
pg.evaluate('''() => { weather.next=1e15; SET.zoom=3; resizeRender(); bot.x=880;bot.y=275; snapCamera();
document.querySelectorAll('.card,.toast').forEach(e=>e.remove());$('hud').hidden=true;
globalThis.lakeSave=serializeWorld(); }''')
assert pg.evaluate('treeBases.every(i=>!treeHeld(i)||mat[i]!==WATER)')
assert pg.evaluate('mat.every((m,i)=>m!==WATER||awake[((i/W)>>5)*CW+((i%W)>>5)]>0)')
measure = '''() => { const pools=[]; let p=null;
for(let x=0;x<W;x++){let y=0;while(y<H&&mat[y*W+x]===EMPTY)y++;
if(mat[y*W+x]!==WATER){p=null;continue;}
if(!p){p={width:0,min:y,max:y};pools.push(p);}
p.width++;p.min=Math.min(p.min,y);p.max=Math.max(p.max,y);}
return pools.filter(p=>p.width>20); }'''
pools=pg.evaluate(measure)
print('fresh startup',pools,flush=True)
assert pools and all(p['max']-p['min']<=1 for p in pools)
pg.wait_for_timeout(300)
(ROOT/'shots').mkdir(exist_ok=True)
pg.screenshot(path=str(ROOT/'shots/t96-level.png'))
for state in ('fresh','reloaded'):
if state=='reloaded':
pg.evaluate('''() => {deserializeWorld(lakeSave.meta,lakeSave.buffers);weather.next=1e15;}''')
pg.evaluate('startThreads()')
for batch in range(3):
pg.evaluate('for(let k=0;k<200;k++)simTick();')
result=pg.evaluate('''() => {let lo=H,hi=0,n=0,wet=0;
for(let x=650;x<1100;x++){let y=0;while(y<H&&mat[y*W+x]===EMPTY)y++;
if(mat[y*W+x]===WATER){lo=Math.min(lo,y);hi=Math.max(hi,y);n++;}}
for(const i of treeBases)if(i%W>=650&&i%W<1100&&treeHeld(i)&&mat[i]===WATER)wet++;
return {lo,hi,n,wet,workers:simPool?.workers.length};}''')
pools=pg.evaluate(measure)
assert pools and all(p['max']-p['min']<=1 for p in pools),pools
print(state,result,pools,flush=True)
assert result['n']>150 and result['hi']-result['lo']<=1 and result['wet']==0
pg.evaluate('snapCamera();renderDirty.fill(1);')
pg.wait_for_timeout(300)
pg.screenshot(path=str(ROOT/f'shots/t96-{state}-settled.png'))
assert not errors,errors
print('PASS t96 pixel flat startup and 600-tick fresh/reloaded lakes, dry roots, 2 browser helpers, no page errors',flush=True)