programextensions/scene/demos/voxels-water.xtl

Voxels, 11: water that flows. A stepped hill stands by the start with a lake on its top terrace, held in by a rim of grass. Dig into the rim and the lake spills out and runs down the steps like a waterfall; dig beside the sea and the hole fills. Water flows as a cellular automaton on the cells it has just reached (Endless.xtl): each tick a cell falls into the air below it, or, standing on something solid, spreads one level lower into the air at its sides, 7 levels from a source; the lake and the sea are sources that never empty. The cells it reaches are edits like any dug or placed block, so the water stays where it ran. Water is drawn translucent: the lake's floor and the seabed show through. Run: just demo scene voxels-water click (or X) dig, right-click (or E) place, 1 to 7 choose the block (7 is water, which flows), W A S D walk, Space jump, Shift run, F fly (Space up, Shift down), drag or the arrows to look, H back to the rim, q quit

source · imports en: extensions/scene/demos/Endless.xtl; vx: extensions/scene/demos/Voxels.xtl; pl: extensions/scene/demos/Play.xtl; sc: extensions/scene/lib/Scene.xtl

w : Int

value · line 23
w ← "Voxels 11: water -- X_eTaL" ˢᶜo̲pen! 640 400
Used in: g, k, s, hud, z

g : Int

value · line 24
g ← w ˢᶜf̲og! 22.0 44.0

k : Int

value · line 25
k ← w ˢᶜs̲ky! 0.55 0.72 0.92

k : Int

value · line 26
k ← w ˢᶜc̲urve! 160.0

The hill and its lake

hv : Int

value · line 39

A stepped hill on the 17 by 17 columns around (8, 8), built as edits before any column is made: each ring around the center (r, the larger of the distances east-west and north-south) one block lower than the one inside it, down to the ground; the top terrace (r up to 3) at T, five blocks above the highest ground there, dirt under grass; on it a lake (r up to 2) two blocks deep, held in by the rim (r = 3): 50 cells of moving water, each a full block, 25 a layer.

hv ← r̲avel ᵛˣh̲eightsAt 0 0 17
Used in: gt, T

cell : Int

value · line 40
cell ← (r̲ange 17 × 32 × 17) − 1
Used in: cx, cy, cz

cx : Int

value · line 41
cx ← cell d̲iv 32 × 17
Used in: gt, r, ᵘc̲ells

cy : Int

value · line 42
cy ← (cell d̲iv 17) m̲od 32
Used in: pool, fill, blk, ᵘc̲ells

cz : Int

value · line 43
cz ← cell m̲od 17
Used in: gt, r, ᵘc̲ells

gt : Int

value · line 44
gt ← ((1 + cz + 17 × cx) s̲elect hv) − 1
Used in: fill

T : Int

value · line 45
T ← 28 m̲in 5 + 'm̲ax r̲/ hv − 1

r : Int

value · line 46
r ← (a̲bs cx − 8) m̲ax a̲bs cz − 8
Used in: top, pool

top : Int

value · line 47
top ← T − 0 m̲ax r − 3
Used in: fill, blk

pool : Int

value · line 48
pool ← (r ≤ 2) × (cy ≥ T − 1) × cy ≤ T

fill : Int

value · line 49
fill ← (1 − pool) × (cy > gt) × cy ≤ top

blk : Int

value · line 50
blk ← fill × 2 + cy = top

ᵘc̲ells : Int -> Int

function · line 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 }
Used in: s, lake

s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))

value · line 57

the player on the rim, south of the lake, facing it (north)

s ← w ᵉⁿn̲ewAt 8.5 c̲at (f̲loat T + 1) c̲at 11.5

s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))

value · line 58
s ← (ᵘc̲ells fill, fill r̲eplicate blk) ᵉⁿs̲etAll s

lake : Int

value · line 59
lake ← ᵘc̲ells pool
Used in: s

s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))

value · line 60
s ← (lake c̲at₂ ((t̲ally lake) c̲at 3) r̲eshape ᵉⁿfull c̲at 0 0) ᵉⁿp̲our s

Measuring

ᵘm̲easure : (Any a, Any b, Any c, Any d, Any e, Any f, Any g, Any h, Any i, Any j) => (a, (b, c, d, e, f, g, Int, h), i, j) -> (a, (b, c, d, e, f, g, Int, h), i, j)

function · line 68

u:m_easure s: the lake's two layers and all the moving water, in blocks of water, said

ᵘm̲easure ← { s →
  W ← ᵉⁿw̲ater s
  x ← 1 s̲elect₂ W
  y ← 2 s̲elect₂ W
  z ← 3 s̲elect₂ W
  inlake ← ((a̲bs x − 8) m̲ax a̲bs z − 8) ≤ 2
  a ← 4 s̲elect₂ W
  t̲oBlocks ← { u → f̲ormat (f̲loat f̲loor 0.5 + 100.0 × (f̲loat u) ÷ f̲loat ᵉⁿfull) ÷ 100.0 }
  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
  s
}
Used in: ᵘm̲easureAt, s

ᵘm̲easureIf : (Truthy a, Any b, Any c, Any d, Any e, Any f, Any g, Any h, Any i, Any j, Any k) => a -> ((b, (c, d, e, f, g, h, Int, i), j, k), l) -> (b, (c, d, e, f, g, h, Int, i), j, k)

function · line 79
ᵘm̲easureIf ← { yes sk →
  (s, k) ← sk
  yes ? k ᵘm̲easureAt s
  s
}
Used in: ᵘf̲rame

ᵘm̲easureAt : (Any b, Any c, Any d, Any e, Any f, Any g, Any h, Any i, Any j, Any k) => a -> (b, (c, d, e, f, g, h, Int, i), j, k) -> (b, (c, d, e, f, g, h, Int, i), j, k)

function · line 84
ᵘm̲easureAt ← { k s →
  said ← p̲rint! "after " c̲at (f̲ormat k) c̲at " frames:"
  ᵘm̲easure s
}

Playing

ᵘf̲rame : (Num a, Num b, Num c, Num d, Truthy d, Num e) => (((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (a, Int, Int, Int), (Int, Int, Float, b, c)), Int, d, e) -> (((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (a, Int, Int, Int), (Int, Int, Float, b, c)), Int, d, e)

function · line 94

The state is (the world and its player, the chosen block, whether the water was asleep, the frames so far); each time the water falls asleep after moving, the lake is measured.

ᵘf̲rame ← { (s, sel, was, k) →
  (s, sel) ← ᵖˡf̲rame (s, sel)
  now ← ᵉⁿa̲sleep s
  s ← (now × 1 − was) ᵘm̲easureIf (s, k + 1)
  (s, sel, now, k + 1)
}
Used in: last

hud : Int

value · line 101
hud ← w ᵖˡh̲ud 1

s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))

value · line 102
s ← (3 × (1 + 2 × ᵉⁿreach) × 1 + 2 × ᵉⁿreach) 'ᵉⁿs̲tream p̲ower s

s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))

value · line 103
s ← ᵘm̲easure s

last : (((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int)), Int, Int, Int)

value · line 104
last ← 100000 'ᵘf̲rame p̲ower (s, 1, 1, 0)
Used in: s

z : Int

value · line 105
z ← ˢᶜc̲lose! w

ᵘw̲orldOf : (Any a, Any b, Any c, Any d) => (a, b, c, d) -> a

function · line 108
ᵘw̲orldOf ← { (s, _, _, _) → s }
Used in: s

s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))

value · line 109
s ← ᵘw̲orldOf last

s : ((Float, Float, Float, Float, Float, Float), (Int, Int, Box Int, Box Int, Int, Int, Int, Int), (Int, Int, Int, Int), (Int, Int, Float, Int, Int))

value · line 111
s ← ᵘm̲easure s