sourceextensions/scene/demos/voxels-water.xtl

1⍝# Voxels, 11: water that flows. A stepped hill stands by the start with 2⍝# a lake on its top terrace, held in by a rim of grass. Dig into the 3⍝# rim and the lake spills out and runs down the steps like a waterfall; 4⍝# dig beside the sea and the hole fills. Water flows as a cellular 5⍝# automaton on the cells it has just reached (Endless.xtl): each tick a 6⍝# cell falls into the air below it, or, standing on something solid, 7⍝# spreads one level lower into the air at its sides, 7 levels from a 8⍝# source; the lake and the sea are sources that never empty. The cells 9⍝# it reaches are edits like any dug or placed block, so the water stays 10⍝# where it ran. Water is drawn translucent: the lake's floor and the 11⍝# seabed show through. 12⍝# Run: just demo scene voxels-water 13⍝# click (or X) dig, right-click (or E) place, 1 to 7 choose the block 14⍝# (7 is water, which flows), W A S D walk, Space jump, Shift run, F 15⍝# fly (Space up, Shift down), drag or the arrows to look, H back to 16⍝# the rim, q quit 17 18ᵉⁿ⁼u̲se< "Endless" 19ᵛˣ⁼u̲se< "Voxels" 20ᵖˡ⁼u̲se< "Play" 21ˢᶜ⁼u̲se< "Scene" 22 23w ← "Voxels 11: water -- X_eTaL" ˢᶜo̲pen! 640 400 24g ← w ˢᶜf̲og! 22.0 44.0 25k ← w ˢᶜs̲ky! 0.55 0.72 0.92 26k ← w ˢᶜc̲urve! 160.0 27 28ᵖˡhelp 29 30⍝## The hill and its lake 31 32⍝# A stepped hill on the 17 by 17 columns around (8, 8), built as edits 33⍝# before any column is made: each ring around the center (r, the 34⍝# larger of the distances east-west and north-south) one block lower 35⍝# than the one inside it, down to the ground; the top terrace (r up to 36⍝# 3) at T, five blocks above the highest ground there, dirt under 37⍝# grass; on it a lake (r up to 2) two blocks deep, held in by the rim 38⍝# (r = 3): 50 cells of moving water, each a full block, 25 a layer. 39hv ← r̲avel ᵛˣh̲eightsAt 0 0 17 40cell ← (r̲ange 17 × 32 × 17) − 1 41cx ← cell d̲iv 32 × 17 42cy ← (cell d̲iv 17) m̲od 32 43cz ← cell m̲od 17 44gt ← ((1 + cz + 17 × cx) s̲elect hv) − 1 45T ← 28 m̲in 5 + 'm̲ax r̲/ hv − 1 46r ← (a̲bs cx − 8) m̲ax a̲bs cz − 8 47top ← T − 0 m̲ax r − 3 48pool ← (r ≤ 2) × (cy ≥ T − 1) × cy ≤ T 49fill ← (1 − pool) × (cy > gt) × cy ≤ top 50blk ← fill × 2 + cy = top 51ᵘc̲ells ← { m → 2 1 t̲ranspose (3 c̲at '+ r̲/ m) r̲eshape (m r̲eplicate cx) c̲at (m r̲eplicate cy) c̲at m r̲eplicate cz } 52"the terrace's height, the hill's blocks (dirt, grass) and the lake's cells:" 53T 54('+ r̲/₂ (2 3) '= t̲able fill r̲eplicate blk) c̲at '+ r̲/ pool 55 56⍝# the player on the rim, south of the lake, facing it (north) 57s ← w ᵉⁿn̲ewAt 8.5 c̲at (f̲loat T + 1) c̲at 11.5 58s ← (ᵘc̲ells fill, fill r̲eplicate blk) ᵉⁿs̲etAll s 59lake ← ᵘc̲ells pool 60s ← (lake c̲at₂ ((t̲ally lake) c̲at 3) r̲eshape ᵉⁿfull c̲at 0 0) ᵉⁿp̲our s 61"looking up no cells:" 62t̲ally (ᵉⁿw̲orld s) ᵉⁿl̲ook 0 3 r̲eshape 0 63 64⍝## Measuring 65 66⍝# u:m_easure s: the lake's two layers and all the moving water, in 67⍝# blocks of water, said 68ᵘm̲easure ← { s → 69 W ← ᵉⁿw̲ater s 70 x ← 1 s̲elect₂ W 71 y ← 2 s̲elect₂ W 72 z ← 3 s̲elect₂ W 73 inlake ← ((a̲bs x − 8) m̲ax a̲bs z − 8) ≤ 2 74 a ← 4 s̲elect₂ W 75 t̲oBlocks ← { u → f̲ormat (f̲loat f̲loor 0.5 + 100.0 × (f̲loat u) ÷ f̲loat ᵉⁿfull) ÷ 100.0 } 76 said ← p̲rint! "lake: top layer " c̲at (t̲oBlocks '+ r̲/ a × inlake × y = T) c̲at " of 25 blocks, the layer below " c̲at (t̲oBlocks '+ r̲/ a × inlake × y = T − 1) c̲at " of 25; all the moving water " c̲at t̲oBlocks ᵉⁿw̲aterUnits s 77 s 78} 79ᵘm̲easureIf ← { yes sk → 80 (s, k) ← sk 81 yes ? k ᵘm̲easureAt s 82 s 83} 84ᵘm̲easureAt ← { k s → 85 said ← p̲rint! "after " c̲at (f̲ormat k) c̲at " frames:" 86 ᵘm̲easure s 87} 88 89⍝## Playing 90 91⍝# The state is (the world and its player, the chosen block, whether the 92⍝# water was asleep, the frames so far); each time the water falls 93⍝# asleep after moving, the lake is measured. 94ᵘf̲rame ← { (s, sel, was, k) → 95 (s, sel) ← ᵖˡf̲rame (s, sel) 96 now ← ᵉⁿa̲sleep s 97 s ← (now × 1 − was) ᵘm̲easureIf (s, k + 1) 98 (s, sel, now, k + 1) 99} 100 101hud ← w ᵖˡh̲ud 1 102s ← (3 × (1 + 2 × ᵉⁿreach) × 1 + 2 × ᵉⁿreach) 'ᵉⁿs̲tream p̲ower s 103s ← ᵘm̲easure s 104last ← 100000 'ᵘf̲rame p̲ower (s, 1, 1, 0) 105z ← ˢᶜc̲lose! w 106⍝ (an accessor, not a top-level tuple pattern: xetal doc would list a 107⍝ hidden %N value for one, ask E10) 108ᵘw̲orldOf ← { (s, _, _, _) → s } 109s ← ᵘw̲orldOf last 110"at the end:" 111s ← ᵘm̲easure s 112"bye"