luv

Workshop wiki

light-tests.lisp

luvcraft/light-tests.lisp

system luvcraft/core/test · 40 definitions · on GitHub

in-package#:luvcraft.tests

The reference relight is exercised on small hand-built worlds whose correct fields can be reasoned out cell by cell: open columns, roofs and shafts, emitters and their falloff, and both vertical and lateral chunk seams.

defparameter*test-glow-block*
make-instance'luvcraft::block-kind:name:test-glow:face-tiles'
:all:stone
:light-emission10:surface-emission1.0
defparameter*test-dim-glow-block*
make-instance'luvcraft::block-kind:name:test-dim-glow:face-tiles'
:all:stone
:light-emission6
defmethodlocate-chunk-window-site:around
regionluvcraft::light-region
xyz
call-next-method
defunmake-open-sky-test-world
&restchunk-keys

A world whose absent +Y boundary is open sky, with all-air chunks.

let
world
make-block-world:source
make-instance'little-world-source:seed1
dolist
key
orchunk-keys'
000
world
defunsky-at
worldxyz
values
defunblocklight-at
worldxyz
nth-value1
deftestopen-columns-see-full-sky
let
ok
=
sky-atworld8158
15
ok
=
sky-atworld808
15
ok
=
sky-atworld000
15
ok
=
sky-atworld15715
15

Lateral terrain is generatable but not resident, so the result is honest but provisional.

ok
eq
nth-value2
:provisional
deftestroofs-block-light-and-shafts-transmit-it
let
dotimes
x16
dotimes
z16
unless
and
=x8
=z8
setfluvcraft::*stone-block*

Stone roof cells admit no sky; the open shaft carries a full beam to the floor, and lateral spread attenuates one level per step.

ok
=
sky-atworld2152
0
ok
=
sky-atworld8158
15
ok
=
sky-atworld808
15
ok
=
sky-atworld7148
14
ok
=
sky-atworld2142
3
ok
=
sky-atworld000
0
deftestemitters-fall-off-and-the-brighter-source-wins
let
ok
=10
ok
ok
=
blocklight-atworld8811
7
ok

Sixteen Manhattan steps out, the level is exhausted.

ok

Between the two emitters each cell keeps the brighter contribution.

ok
=
blocklight-atworld1088
8
ok
=
blocklight-atworld1188
7

Emission does not perturb the sky field.

ok
=
sky-atworld898
15
deftestwalls-stop-blocklight
let

A full stone shell one step out along +X.

dotimes
y16
dotimes
z16
setfluvcraft::*stone-block*
ok
ok
ok
deftestsky-crosses-a-vertical-chunk-seam
let

Roof the upper chunk's top layer, world y = 31, with one shaft.

dotimes
x16
dotimes
z16
unless
and
=x4
=z4
setfluvcraft::*stone-block*
ok
=
sky-atworld4314
15

The beam crosses the seam at world y = 15/16 undiminished.

ok
=
sky-atworld4164
15
ok
=
sky-atworld4154
15
ok
=
sky-atworld404
15

Lateral falloff below the seam still measures from the shaft.

ok
=
sky-atworld050
7
ok
=
sky-atworld15515
0
deftestsky-crosses-a-lateral-chunk-seam
let

Roof the +X chunk completely; its light must arrive sideways from the open chunk across the seam.

dotimes
x16
dotimes
z16
setf
world-block-atworld
+16x
15z
luvcraft::*stone-block*
ok
=
sky-atworld15148
15
ok
=
sky-atworld16148
14
ok
=
sky-atworld20148
10
ok
=
sky-atworld31148
0
deftestrelighting-is-a-derived-domain-with-its-own-revisions
let
let*
content-revision
luvcraft::block-chunk-revisionchunk
world-revision
block-world-revisionworld
field
block-chunk-light-fieldchunk
ok
=
lengthchanged
1
ok
=
chunk-light-field-revisionfield
1

Light publication does not impersonate an authored edit.

ok
=
luvcraft::block-chunk-revisionchunk
content-revision
ok
=
block-world-revisionworld
world-revision

A second solve over unchanged content publishes nothing.

ok
=
chunk-light-field-revisionfield
1

A content edit then changes the field and only the light revision and changed light boundaries advance.

The incremental relighter is judged against the reference solver: after its queues settle, every resident cell must be bit-identical to a from-scratch solve of the same world.

defunlight-matches-reference-p
world
let
loopforchunkinalways
let*
key
chunk-domain-coordinate
block-chunk-domainchunk
entry
gethashkey
luvcraft::light-region-entriesreference
field
block-chunk-light-fieldchunk
deftestcompiled-frontier-light-is-inspectable-and-matches-the-oracle
let
ok
eq:monotone-max-fixpoint
luvcraft.frontier:frontier-program-definition-familydefinition
ok
eq:brightest-first-buckets
luvcraft.frontier:frontier-program-definition-frontier-layoutdefinition
ok
eq:voxel-face-relations
luvcraft.frontier:frontier-program-definition-neighborhooddefinition
let
world

Give the comparison vertical and lateral crossings, occlusion, two competing emitters, and a direct sky shaft in one small world.

dotimes
x32
dotimes
z16
unless
and
=x4
=z4
setfluvcraft::*stone-block*
let
ok
luvcraft.light-reference:voxel-light-solver-comparison-equal-pcomparison
ok
null
luvcraft.light-reference:voxel-light-solver-comparison-mismatched-keyscomparison
ok
=
luvcraft.light-reference:voxel-light-solver-comparison-legacy-visitscomparison
luvcraft.light-reference:voxel-light-solver-comparison-candidate-visitscomparison
ok
plusp
luvcraft.light-reference:voxel-light-solver-comparison-legacy-bytes-consedcomparison
ok
plusp
luvcraft.light-reference:voxel-light-solver-comparison-candidate-bytes-consedcomparison
ok
>=
luvcraft.light-reference:voxel-light-solver-comparison-legacy-gc-secondscomparison
0d0
ok
>=
luvcraft.light-reference:voxel-light-solver-comparison-candidate-gc-secondscomparison
0d0
ok
=2
length
luvcraft.light-reference:voxel-light-solver-comparison-candidate-executionscomparison
dolist
execution
luvcraft.light-reference:voxel-light-solver-comparison-candidate-executionscomparison
ok
plusp
luvcraft.frontier:frontier-execution-visitsexecution
ok
=
*6
luvcraft.frontier:frontier-execution-visitsexecution
luvcraft.frontier:frontier-execution-relationsexecution
ok
plusp
luvcraft.frontier:frontier-execution-crossingsexecution
defunmake-compiled-light-proof-world

Three chunks with vertical and lateral seams, occlusion, a shaft, emitters.

let
world
dotimes
x32
dotimes
z16
unless
and
=x4
=z4
setfluvcraft::*stone-block*
world
deftestcompiled-light-kernel-is-inspectable-and-matches-the-reference-oracle

The program states its law; the realization retains the checked expressions, the emitted forms, and the compiled functions.

let*
ok
luvcraft.frontier:frontier-program-definition-transferdefinition
ok
equal'
"LEVEL""OPACITY"
mapcar
lambda
role
symbol-name
luvcraft.frontier:frontier-field-role-namerole
luvcraft.frontier:frontier-program-definition-fieldsdefinition
ok
eq'lambda
first
luvcraft.frontier:frontier-realization-drain-formrealization
ok
functionp
luvcraft.frontier:frontier-realization-drain-functionrealization
ok
functionp
luvcraft.frontier:frontier-realization-admit-functionrealization
ok
=15
luvcraft.frontier:frontier-realization-maximum-priorityrealization

The transfer law is checked in the bound field's own quantity: sky light stays sky light, and attenuation steps enter through an explicit as-field-quantity boundary rather than by coincidence of encoding.

ok
eq:sky-propagation-level
luv.arithmetic:quantity-specification-name
luv.arithmetic.language:arithmetic-expression-quantity-specification
luvcraft.frontier:frontier-realization-transferrealization
ok
eq:block-propagation-level
luv.arithmetic:quantity-specification-name
luv.arithmetic.language:arithmetic-expression-quantity-specification
luvcraft.frontier:frontier-realization-transfer

The emitted scalar loop contains no arithmetic dispatch: the law was inlined as ordinary CL operators over declared lanes.

ok
not
labels
mentions-p
tree
if
atomtree
or
mentions-p
cartree
mentions-p
cdrtree
mentions-p
luvcraft.frontier:frontier-realization-drain-formrealization
let*
ok
luvcraft.light-reference:voxel-light-solver-comparison-equal-pcomparison
ok
=
luvcraft.light-reference:voxel-light-solver-comparison-legacy-visitscomparison
luvcraft.light-reference:voxel-light-solver-comparison-candidate-visitscomparison
ok
eq:compiled
luvcraft.light-reference:voxel-light-solver-comparison-candidate-solvercomparison
ok
=2
length
luvcraft.light-reference:voxel-light-solver-comparison-candidate-executionscomparison
deftestcompiled-light-seeds-are-boundary-transfers

Open sky is a virtual source at full brightness related inward through the program's own transfer law: straight down pays only opacity, a lateral boundary pays one step more, and a fully opaque cell admits nothing. The realization exposes this as its RELATE entry.

let*
setfluvcraft::*stone-block*
let*
ok
functionp
luvcraft.frontier:frontier-realization-relate-functionsky
flet
ok
=15
areflevels
ok
=14
areflevels
ok
=0
areflevels

A second, dimmer relation into the same site is not an improvement.

ok
=2
luvcraft.frontier:bucket-frontier-countfrontier
ok
=2
luvcraft.frontier:frontier-execution-admissionsexecution
deftestcompiled-light-drain-allocates-nothing-per-relation

A warmed drain over pre-grown frontier storage allocates only at chunk crossings, where the window resolves a coordinate key (#L84JCX), never per site or per relation. The proof world exposes about 68,000 relations and 4,000 crossings; one cons per relation would exceed a megabyte.

let*
dotimes
round3
let*
luvcraft::seed-compiled-sky-boundariesskyregionfrontierexecution
let
observation
make-runtime-observation
setfbytes
runtime-observation-bytes-consedobservation
relations
luvcraft.frontier:frontier-execution-relationsexecution
crossings
luvcraft.frontier:frontier-execution-crossingsexecution
ok
>relations60000
ok
<bytes
+
*641024
*128crossings
deftestcompiled-frontier-light-is-the-production-default
let
request
make-instance'luvcraft::block-light-production-request:key'
:light
:regionnil:dependency-stampnil
ok
eq:compiled
luvcraft::block-light-production-request-solverrequest
deftestbucket-frontier-admission-does-not-construct-a-type-per-site
let
frontier
luvcraft.frontier:make-bucket-frontier:maximum-priority15:initial-capacity8192
observation
make-runtime-observation

Warm CLOS accessor caches outside the measured extent.

with-runtime-observation
observation
dotimes
offset8192
dotimes
offset8192
declare
ignoreoffset

The former dynamic TYPEP specifier allocated three conses per push.

ok
<
runtime-observation-bytes-consedobservation
4096
deftestlight-solvers-expose-symmetric-nested-timing-zones
let
trace
make-cpu-trace:label"voxel light solvers"
let
names
mapcar#'cpu-trace-zone-name
ok
equal'
:lighting/compare:lighting/legacy:lighting/legacy/seed-sky:lighting/legacy/propagate-sky:lighting/legacy/drain-sites:lighting/legacy/seed-block:lighting/legacy/propagate-block:lighting/legacy/drain-sites:lighting/compiled:lighting/compiled/seed-sky:lighting/compiled/propagate-sky:lighting/compiled/drain-sites:lighting/compiled/seed-block:lighting/compiled/propagate-block:lighting/compiled/drain-sites
names
defuncheck-incremental-edits-converge
let*

Arrival through the hook lights the fresh chunk incrementally.

Roofing one cell darkens its column; removing it restores the beam.

setfluvcraft::*stone-block*
ok
=
sky-atworld8148
14
setfnil
ok
=
sky-atworld808
15

An emitter appears and disappears.

ok
setfnil
ok

A settled state publishes nothing further.

ok
plusp
luvcraft::lighting-state-publicationsstate
ok
plusp
luvcraft::lighting-state-cells-visitedstate
deftestasynchronous-lighting-publishes-only-a-current-immutable-capture
let*
session
make-instance'luvcraft-session:worldworld:lighting-statestate
stale-request
make-instance'luvcraft::block-light-production-request:key'
:light
:priority-1:dependency-stamp:region

The request owns its dense input. A later edit invalidates publication without changing what the producer is currently solving.

let
ok
null
luvcraft::publish-production-resultsessionstale-requestpayload
ok
null
block-chunk-light-fieldchunk
let*
request
make-instance'luvcraft::block-light-production-request:key'
:light
:priority-1:solver:compiled:dependency-stamp:region
ok
eq:compiled
luvcraft::block-light-production-request-solverrequest
deftestsettled-cell-edits-use-the-incremental-relighter
let*
session
make-instance'luvcraft-session:worldworld:lighting-statestate

Initial residency is a global concern. Settle it before modeling the ordinary player edit path in an already visible world.

setfluvcraft::*stone-block*
ok
not
gethash'
:light
luvcraft-session-outstanding-productionsession
ok
=
sky-atworld8148
14
defuncheck-random-edits-and-residency
let*
world
make-block-world:source
make-instance'little-world-source:seed1
rng987654321
chunk-keys'
000
100
010
labels
next-random
limit
setfrng
mod
+
*rng1103515245
12345
expt231
mod
floorrng65536
limit
random-block
case
next-random8
012
luvcraft::*stone-block*
tnil
random-resident-cell
let*
key
nth
next-random
lengthkeys
keys
list
+
*16
firstkey
next-random16
+
*16
next-random16
+
*16
thirdkey
next-random16
dolist
keychunk-keys

Random terrain, then interleaved edit bursts and reconciles.

dotimes
index300
destructuring-bind
xyz
random-resident-cell
setf
random-block
dotimes
round6
dotimes
edit10
destructuring-bind
xyz
random-resident-cell
setf
random-block

A departure relights the retained neighbors; a re-arrival with fresh edits converges again.

dotimes
edit12
setf
world-block-atworld
+16
next-random16
next-random16
next-random16
random-block
deftestcompiled-random-edits-and-residency-match-the-reference-solver

The compiled removal and addition programs must reproduce the reference field across the same edit bursts, departure, and re-arrival. #K3WRD3

deftestcompiled-light-removal-is-an-invalidation-program
let
ok
eq:invalidation
luvcraft.frontier:frontier-program-definition-familydefinition
ok
luvcraft.frontier:frontier-program-definition-retain-admissions-pdefinition
ok
functionp
luvcraft.frontier:frontier-realization-drain-functionrealization
ok
functionp
luvcraft.frontier:frontier-realization-admit-functionrealization

Roofing a lit column: the sky removal clears exactly the beam beneath the roof (its dependents), hands the beam's lit lateral neighbours to the addition frontier as survivors, and the addition program relights the column from them to the reference field.

let*
setfluvcraft::*stone-block*
let*
multiple-value-bind
executionsvisits
destructuring-bind
sky-removalblock-removalsky-additionblock-addition
executions
declare
ignoreblock-removalblock-addition

The edited cell plus the fifteen cells of beam beneath it.

ok
=16
luvcraft.frontier:frontier-site-buffer-length
luvcraft.frontier:frontier-execution-admitted-sitessky-removal
ok
=16
luvcraft.frontier:frontier-execution-visitssky-removal
ok
plusp
luvcraft.frontier:frontier-execution-emissionssky-removal
ok
plusp
luvcraft.frontier:frontier-execution-visitssky-addition
ok
pluspvisits
clrhash
luvcraft::lighting-state-dirty-cellsstate
ok
=14
sky-atworld8148
deftestsame-key-replacement-removes-the-old-chunk-light
let*
ok
=
blocklight-atworld1588
9

Streaming can replace a chunk at the same key before the next lighting reconcile. The departure still has to run, or retained neighbors keep light propagated from the old incarnation.

ok
=
blocklight-atworld1588
0
deftestplayer-placeable-crystal-relights-across-chunk-boundaries
let*
let
left-revision-before
chunk-light-field-revision
block-chunk-light-fieldleft
right-revision-before
chunk-light-field-revision
block-chunk-light-fieldright
edit-block-at*crystal-block*world1688
ok
=
blocklight-atworld1688
block-light-emission*crystal-block*
ok
=
blocklight-atworld1588
1-
block-light-emission*crystal-block*
ok
>
chunk-light-field-revision
block-chunk-light-fieldleft
left-revision-before
ok
>
chunk-light-field-revision
block-chunk-light-fieldright
right-revision-before
let
left-revision-before
chunk-light-field-revision
block-chunk-light-fieldleft
right-revision-before
chunk-light-field-revision
block-chunk-light-fieldright
edit-block-atnilworld1688
ok
=
blocklight-atworld1688
0
ok
=
blocklight-atworld1588
0
ok
>
chunk-light-field-revision
block-chunk-light-fieldleft
left-revision-before
ok
>
chunk-light-field-revision
block-chunk-light-fieldright
right-revision-before
deftestmeshes-carry-raw-corner-light-and-material-emission
let*

A solid floor with a glowing block resting on it, under open sky.

dotimes
x16
dotimes
z16
setfluvcraft::*stone-block*
setf*crystal-block*
let*
mesh
mesh-block-chunkmesherworldchunk
vertices
block-mesh-verticesmesh
sky-readingsnil
block-readingsnil
emissive-vertices0
loopforbasefrom0below
lengthvertices
bystridedo
push
arefvertices
+base9
sky-readings
push
arefvertices
+base10
block-readings
when
plusp
arefvertices
+base11
incfemissive-vertices

Floor tops under open sky read full skylight; the glow block's own faces carry its surface emission, and its blocklight reaches the floor around it.

ok
find1.0sky-readings
ok
plusp
reduce#'maxblock-readings

Five exposed faces of the resting glow block, six vertices each.

ok
=emissive-vertices30

The immutable snapshot meshes bit-identically to the owner side.

let*
ok
equalp
block-mesh-verticesmesh
block-mesh-verticessnapshot-mesh
deftestabsent-neighbors-are-never-silently-open-sky

A world with no source keeps every boundary :UNKNOWN, so nothing is lit and the result says so instead of inventing daylight.

let
multiple-value-bind
skyblockstate
ok
=sky0
ok
=block0
ok
eqstate:provisional
deftestpacked-light-scheduling-preserves-the-fixed-point
let*
multiple-value-bind
lifo-resultlifo-visits
luvcraft::solve-light-regionlifo:scheduling:lifo
declare
ignorelifo-result
multiple-value-bind
level-resultlevel-visits
luvcraft::solve-light-regionlevel:scheduling:level
declare
ignorelevel-result
ok
<level-visitslifo-visits
maphash
lambda
keylifo-entry
let
level-entry
gethashkey
luvcraft::light-region-entrieslevel
oklevel-entry
luvcraft::light-region-entrieslifo
deftestlight-hot-traversal-locates-only-at-domain-crossings
let
world
make-block-world:chunk-width3:chunk-height3:chunk-depth3
let*
key
chunk-domain-coordinate
block-chunk-domainchunk
entry
gethashkey
luvcraft::light-region-entriesregion
labels
multiple-value-bind
visitedlookups
visit111
ok
=visited1
ok
zeroplookups
multiple-value-bind
visitedlookups
visit011
ok
=visited1
ok
=lookups1
deftestlight-boundary-change-comparison-uses-domain-faces
let
world
make-block-world:chunk-width3:chunk-height4:chunk-depth5
let*
key
chunk-domain-coordinate
block-chunk-domainchunk
domain
luvcraft::light-region-entry-domain
gethashkey
luvcraft::light-region-entriesregion
old
make-array:element-type'
unsigned-byte8
:initial-element0
new
copy-seqold
labels
changed-directions
loopfordirectioninluvcraft::*voxel-face-directions*whencollectdirection
ok
null
changed-directions
fillnew0
setf
arefnew0
1
deftestlight-region-is-a-chunk-window-with-policy-free-availability
let
let
multiple-value-bind
entryoffsetavailability
okentry
ok
zeropoffset
ok
eqavailability:available
multiple-value-bind
entryoffsetavailability
ok
nullentry
ok
nulloffset
ok
eqavailability:unavailable