// Fog: surface, sight, range, saves and simulation independence. const { load, suite, flatWorld, rect, ticks } = require('./harness'); const { run } = load(), { check, done } = suite(); run('generateWorld(4242, 512, 384, null)'); check('sky and surface start seen', run('fogSeen(20, 0) >= 200 && fogSeen(20, surfY[20]) >= 200')); check('deep ground starts unseen', run('fogSeen(20, surfY[20] + 60) === 0')); flatWorld(run, 256, 256, 40); rect(run, 40, 100, 140, 110, run('EMPTY')); rect(run, 40, 125, 140, 135, run('EMPTY')); run('bot.x = 60; bot.y = 102; fogLook(62.5, 104.5)'); check('open pocket is visible', run('fogSeen(82, 104) >= 200')); check('rock hides separate pocket', run('fogSeen(62, 130) === 0')); check('one look has limited range', run('fogSeen(124, 104) === 0')); check('fog only increases', run('(()=>{const f = fog.slice(); fogLook(90,104); return f.every((v,i)=>fog[i]>=v)})()')); check('save/load keeps fog', run('(()=>{fogLook(bot.x+bot.w/2,bot.y+bot.h/2);const s=serializeWorld(), f=fog.slice();deserializeWorld(s.meta,s.buffers);return f.every((v,i)=>fog[i]===v)})()')); rect(run, 200, 160, 203, 163, run('EMPTY')); run('placeBlock(BP_WALL, RSTONE, 50, 40, true)'); check('old save rebuilds exploration', run('(()=>{const s=serializeWorld();delete s.buffers.fog;deserializeWorld(s.meta,s.buffers);return fogSeen(62,104)>=200 && fogSeen(202,162)===255 && fogSeen(20,220)===0})()')); check('wrong length fog rebuilds exploration', run('(()=>{const s=serializeWorld();s.buffers.fog=new Uint8Array(1);deserializeWorld(s.meta,s.buffers);return fogSeen(202,162)===255})()')); const hash = () => run('mat.reduce((h,v)=>Math.imul(h^v,16777619)>>>0,2166136261)'); run('generateWorld(42, 256, 256, null)'); ticks(run, 300); const h = hash(); run('generateWorld(42, 256, 256, null); fogLook = function () {}'); ticks(run, 300); check('fog leaves simulation unchanged', hash() === h); done();