Files

59 lines
3.5 KiB
Python

"""Frozen legacy references, captured before retirement; compare the WebGPU world only."""
import base64, gzip, json, pathlib, sys, subprocess
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent / 'tools'))
from use_venv import ensure_playwright; ensure_playwright()
from browser import launch, consume_gpu_option
consume_gpu_option()
ROOT = pathlib.Path(__file__).resolve().parent.parent
GOLD = ROOT / 'test/fixtures/golden'
with launch(viewport={'width': 640, 'height': 480}) as (_, pg, url):
errors=[]
pg.on('pageerror', lambda e: errors.append(str(e)))
pg.on('console', lambda m: errors.append(m.text) if m.type=='error' else None)
pg.add_init_script('requestAnimationFrame=()=>0;')
pg.goto(url); pg.evaluate('CAPS_CHECK')
assert pg.evaluate('GPU.ok'), pg.evaluate('GPU.error')
for scene in ['renderer','joins','sky','lamp','opening','magma','fire']:
for look in ['pixel','smooth']:
for zoom in [12,2]:
height = 512 if scene=='joins' else 384
frozen = json.loads(gzip.decompress((ROOT/f'test/fixtures/golden-world-640x{height}.json.gz').read_bytes()))
# Keep the inputs that produced the legacy PNGs when simulation RNG changes.
pg.evaluate("""([h, frozen])=>{
generateWorld(424242,640,h,null);
for(const [name,encoded]of Object.entries(frozen)) {
const target=eval(name),raw=Uint8Array.from(atob(encoded),c=>c.charCodeAt(0));
new Uint8Array(target.buffer).set(raw);
}
enterGame();GAME.paused=true;
}""",[height,frozen])
name = 'joins' if scene=='joins' else 't88-renderer' if scene in ['renderer','sky'] else 't88-light'
pg.evaluate('() => {'+(ROOT / f'tools/scenes/{name}.js').read_text()+'}')
if scene not in ['renderer','joins','sky']:
pg.evaluate('s=>lightScene(s)',scene)
if scene=='joins':
pg.evaluate('SET.fog=false; CAM=[280,98];')
if scene=='sky':
pg.evaluate('CAM=[320,55]; SET.fog=false;')
pg.evaluate("""([look,zoom])=>{
SET.look=look;SET.zoom=zoom;SET.lighting='full';SET.lightEvery=1;SET.glow='low';
SM.t0=0; SM.surf=-1;
performance.now=()=>5000;resizeRender();bot.x=CAM[0]-bot.w/2;bot.y=CAM[1]-bot.h/2;
snapCamera();R.frame=1000;drawWorld();
}""",[look,zoom])
raw=pg.evaluate("""() => {
const c=document.createElement('canvas');c.width=384;c.height=288;
c.getContext('2d').drawImage(worldPixelContext().canvas,128,96,384,288,0,0,384,288);
return c.toDataURL().split(',')[1];
}""")
path=GOLD/f'{scene}-{look}-{zoom}.png'
actual=base64.b64decode(raw)
rgb=lambda data: subprocess.run(['magick','png:-','-alpha','off','-depth','8','rgb:-'],input=data,capture_output=True,check=True).stdout
a,b=rgb(actual),rgb(path.read_bytes())
ds=[abs(x-y) for x,y in zip(a,b)]
mean=sum(ds)/len(ds);bad=sum(max(ds[i:i+3])>8 for i in range(0,len(ds),3))
assert mean<0.5 and bad<384*288*0.003, (path.name,mean,bad)
print('PASS golden',path.name,round(mean,4),bad)
(ROOT/'shots'/('golden-'+path.name)).write_bytes(actual)
assert not errors,errors