Water pours off ledges several times faster, raining clouds spread boiled-off water (t21)

- Liquids step up to 8 cells a tick toward a drop (fewer the thicker they are), and a top-layer
  grain looks 4 times as far for one, so pools empty and thin film drains. A 100-wide pool
  empties in about 50 s; the old code left 24-650 grains stranded on wide ledges.
- Only a top-layer grain stepping sideways wakes the row ahead, so settled lakes still sleep.
- World generation settles at the old speed: seeds make the same worlds as before.
- Cooled steam under a roof no longer stays steam for ever (its heat area slept).
- Raining clouds keep drifting at half pace and rain over a band either side, so a waterfall into
  a hot shaft no longer rains straight back on its own lake.
- New test/t_water.js; t_weather rain-location checks; t_conveyors counts steam in flight;
  t_molds seeds the random burning-bed check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 20:44:06 -04:00
co-authored by Claude Opus 5.5
parent eee170e3d1
commit 9291040ff0
10 changed files with 195 additions and 20 deletions
+12 -4
View File
@@ -27,16 +27,24 @@ rect(run, 150, 100, 169, 109, run('STEAM'));
run('updateRoof(); for (let y = 100; y < 110; y++) for (let x = 150; x < 170; x++) temp[y*W+x] = 60;');
ticks(run, 600);
check('under a roof steam still turns back into water', count(run, run('WATER')) > 120 && moist() === 0, `water ${count(run, run('WATER'))}, clouds ${moist()}`);
// clouds rain back out over the band where they gathered
// clouds rain back out over the band where they gathered, and a band either side
flatWorld(run, 512, 200, 120);
run('weather.moist[3] = 400; weather.wind = 0;');
ticks(run, 2);
check('a big cloud starts to rain', run('weather.raining[3]') === 1);
ticks(run, 900);
let drops = 0, near = 0; // where the drops fall (the water spreads out over the flat ground after it lands)
for (let k = 0; k < 90; k++) { ticks(run, 10); for (const x of JSON.parse(run('JSON.stringify(flyers.filter(f => f.rain).map(f => f.x | 0))'))) { drops++; if (x >= 2 * 64 && x < 5 * 64) near++; } }
const landed = count(run, run('WATER'));
const near = count(run, run('WATER'), 3 * 64 - 64, 0, 4 * 64 + 64, 199);
check('a cloud rains its water back down', landed + rainInAir(run('WATER')) + moist() > 390 && landed > 250, `landed ${landed}, in the air ${rainInAir(run('WATER'))}, left in the cloud ${moist().toFixed(0)}`);
check('close to where it gathered', near > landed * 0.85, `${near} of ${landed} within a band`);
check('it falls near where it gathered, give or take a band', drops > 0 && near > drops * 0.85, `${near} of ${drops} drops seen within a band`);
// with a wind the raining cloud keeps drifting, so the rain is spread out downwind instead of all
// falling back where the steam rose (a waterfall into a hot shaft would otherwise refill its own lake)
flatWorld(run, 1024, 200, 120);
run('weather.moist[3] = 400; weather.wind = 0.3;');
const fell = new Array(16).fill(0);
for (let k = 0; k < 150; k++) { ticks(run, 10); for (const x of JSON.parse(run('JSON.stringify(flyers.filter(f => f.rain).map(f => f.x | 0))'))) fell[(x / 64) | 0]++; }
const allRain = fell.reduce((a, v) => a + v, 0), downwind = fell.slice(2, 8).reduce((a, v) => a + v, 0);
check('in a wind the rain spreads out downwind of the cloud', allRain > 0 && downwind > allRain * 0.85 && fell[3] < allRain * 0.6, `by band ${fell.join(' ')}`);
// boiling water outdoors comes back as rain
flatWorld(run, 320, 200, 120);
rect(run, 140, 116, 179, 119, run('WATER'));