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"