luvcraft/streaming.lisp
Wait outside frame encoding for a useful initial set of chunk meshes.
minimum defaults to nine or the whole desired set when it is smaller. The
visible startup path asks only for the nearest product before its first
presentation; deterministic captures wait for the broader default set.
The source-neutral half of asynchronous chunk loading.
A concrete world source subclasses this with whatever it needs to rebuild
one chunk in isolation on the worker, and answers
perform-production-request with a block-chunk-load-payload. Publication
and demand-token validation live here, on the base class.
Make the off-thread load request which produces resident chunk key.
Return NIL when source cannot generate chunks away from the owning thread;
the session then keeps key desired without scheduling work for it. A
returned request must carry the production key (:LOAD key) so it matches
the session's outstanding-work and cancellation bookkeeping.
The little world's realization of the load protocol. The request captures everything the worker needs as plain values: the seed, the chunk shape, deterministic landmarks owned by the chunk, and the sparse edits inside it.
Active work cannot be canceled, so retain its ticket until its result returns and fails desired-set/incarnation validation.
Eviction is an owner-side publication. Pending work is either canceled before it starts or allowed to finish and fail its desired-set/incarnation validation harmlessly.
Treat a caller-owned resident set as desired without loading or eviction.
Reconcile session's desired chunk set as world's source prescribes.
A source which can rematerialize its terrain keeps a sliding window around the player, letting the session load and evict chunks as the player moves. The default method treats a caller-owned resident set as desired without loading or eviction: those chunks still receive immutable mesh production, but nothing could regenerate them once evicted.
Without a player or radius there is no window to slide, so even a generative world falls back to caller-owned residency.
The chunk's light revision, or -1 while it has no published field.
Describe exactly which resident data chunk's exposed mesh observes.
Content and light are named as separate revision domains: relighting must invalidate a mesh without impersonating an authored edit, and the stamp preserves which domain made a product stale.
Only the neighbor boundary facing this chunk contributes.
Return a combined, inspectable snapshot of session's chunk meshes.
Return the keys of visible products which no longer describe the world.
Group stale visible chunk products connected across block faces.
Return staged mesh groups which may replace visible products together.
A block edit can invalidate its own chunk and each face-neighbor whose mesh observed the edited boundary. Connected stale visible products therefore form one publication cohort: the old cohort remains drawable until every current replacement is staged. A chunk with no visible predecessor may be published independently.
No rendering can interleave with these owner-thread hash updates. Install the complete cohort before retiring any of its predecessors.
Name the exact resident content captured by an asynchronous light solve.
Reconcile cell edits incrementally or schedule a residency-wide relight.
Authored edits normally touch one settled cell and are much cheaper to reconcile against the published field than to solve every resident chunk from scratch. Chunk arrivals and departures still use a coalesced immutable worker request, keeping residency-scale lighting out of the frame callback.
New hooks which fire after this capture accumulate for the next request. A stale or failed result explicitly restores dirtiness.
Validate and accept one worker product on the render/GPU owning thread.
This is the owner-side mirror of perform-production-request: each request
class carries its own publication rule, so a new kind of asynchronous product
plugs in with one method on each generic rather than an edit to the drain
loop. A stale product simply fails its own validation here. Product kinds
whose visible dependencies span several chunks may stage a complete candidate
here and install its publication cohort later at the frame boundary.
Batch arrivals, then solve a frozen region off-thread. Publication still precedes mesh capture, so dependency stamps observe complete light fields.
A result captured before this frame's lighting publication may already be stale. Reject it before deciding whether a complete mesh cohort can cross the frame boundary.
Snapshot the owner-side streaming state on the canvas thread.
Wait until session has no unpublished streaming or lighting work.
When center is supplied, also wait for the residency window to reach it.
This is intended for repeatable live profiling orchestration, not frame code.
Trace quiet play followed by one natural +X residency-window advance.
The Tracy client must be enabled. This waits for a connected capture and a
fully quiescent session, marks the baseline, leaves the game untouched for
baseline-seconds, then moves the player just across the next chunk boundary.
It returns only after the resulting loads, lighting, and meshes are published.
--------------------------------------------------------------------- The streaming knobs.
The window is only rebuilt when its centre moves, so a knob over its
radius must forget the centre: that is the residency-realization. The
per-frame budgets are read each frame and need nothing.
The value shapes the streaming window, which is only rebuilt when its centre moves; forget the centre so it rebuilds now.
(session &key minimum (timeout 10.0))Wait outside frame encoding for a useful initial set of chunk meshes. MINIMUM defaults to nine or the whole desired set when it is smaller. The visible startup path asks only for the nearest product before its first presentation; deterministic captures wait for the broader default set.
Logical disjunction of tests and raw truth values.
The minimum of compatible quantities.
Addition over compatible quantities.
Multiplication and scalar scaling.
(canvas function)Run FUNCTION with a timestamp on CANVAS's native frame/event thread. The initial native implementation is synchronous: the caller waits for the function's values. The protocol leaves room for a real frame scheduler.
Test whether one compatible scalar is at least another.
Logical conjunction of tests and raw truth values.
An inspectable immutable unit of CPU work after it is submitted.
(name-and-options &rest method-tail)Define a method whose complete dynamic extent is an ambient trace zone. The inferred name includes the generic function, non-T required specializers, and qualifiers. :ZONE and :VALUE have the same meaning as in ZDEFUN.
(request)Compute REQUEST on the production worker and return a transferable value.
(mesher snapshot)The voxel-light program selected for production solves. Only :COMPILED is implemented by the runtime. The legacy implementation is loaded explicitly by the LUVCRAFT/LIGHT-REFERENCE system as a differential test oracle; unsupported names signal through the closed EQL dispatch. #X7Q90E #PJY6E1 #K3WRD3
(solver region &key &allow-other-keys)Solve captured REGION with the explicitly implemented voxel-light SOLVER. There is deliberately no default method: unsupported solver names signal instead of silently selecting another implementation.
Division of two represented quantities.
Subtraction or unary negation.
The source-neutral half of asynchronous chunk loading. A concrete world source subclasses this with whatever it needs to rebuild one chunk in isolation on the worker, and answers PERFORM-PRODUCTION-REQUEST with a BLOCK-CHUNK-LOAD-PAYLOAD. Publication and demand-token validation live here, on the base class.
(source world key demand-token priority)Make the off-thread load request which produces resident chunk KEY. Return NIL when SOURCE cannot generate chunks away from the owning thread; the session then keeps KEY desired without scheduling work for it. A returned request must carry the production key (:LOAD KEY) so it matches the session's outstanding-work…
Test whether two compatible scalars are equal.
(source world key)Capture deterministic landmarks whose owned sites lie inside KEY. This retains the current visual generator while making chunk production independent: cross-boundary canopy sites are attributed to their destination chunk and do not require neighboring live mutation.
(&key (id (gensym "BLOCK-WORLD-"))
(chunk-width 16)
(chunk-height 16)
(chunk-depth 16)
(cell-extent 1d0)
source)(source world chunk-x chunk-y chunk-z)(world x y z)Return one site as BLOCK and :RESIDENT, or NIL and :ABSENT. This sparse world-coordinate accessor constructs coordinate descriptors and a chunk lookup key. It is appropriate for inspectors, ray hits, collision probes, and sparse interaction. Algorithms over many cells should select a chunk/domain once and use…
(world x y z)(session key)(system key)(world player)(player)(player)(session world player radius)(text &key color)(x y z)(world)(chunk)(world x y z)(session world player)(source session world)Reconcile SESSION's desired chunk set as WORLD's SOURCE prescribes. A source which can rematerialize its terrain keeps a sliding window around the player, letting the session load and evict chunks as the player moves. The default method treats a caller-owned resident set as desired without loading or eviction: those…
(name-and-options lambda-list &body body)Define a function whose complete dynamic extent is an ambient trace zone. The inferred name is PACKAGE/FUNCTION. Use (NAME :ZONE ZONE-NAME) to provide a more semantic name and :VALUE FORM to attach a Tracy work count.
(chunk direction)(field direction)(world chunk)Describe exactly which resident data CHUNK's exposed mesh observes. Content and light are named as separate revision domains: relighting must invalidate a mesh without impersonating an authored edit, and the stamp preserves which domain made a product stale.
(coordinate direction)(world coordinate)(direction)(chunk direction)Test whether one compatible scalar is less than another.
(session)(accumulator mesh)(name)Return the represented-value declaration published by global NAME, or NIL.
(handle)Logically invalidate HANDLE immediately. Native teardown may be deferred until submitted work which captured HANDLE has completed.
(session key product)Logical negation of one test or raw truth value.
(key direction)(session)Return staged mesh groups which may replace visible products together. A block edit can invalidate its own chunk and each face-neighbor whose mesh observed the edited boundary. Connected stale visible products therefore form one publication cohort: the old cohort remains drawable until every current replacement is…
(key center)Raise a dimensionless value to a dimensionless power.
(left right center)(world chunk dependency-stamp)Copy CHUNK and its one-cell halo into immutable worker-owned columns. Every resident chunk's indices are already offsets under WORLD's vocabulary, so the halo is gathered by plain slab copies from the up to 27 neighbours, with no per-cell decomposition, translation, or block object lookup. The vocabulary's members…
Reconcile cell edits incrementally or schedule a residency-wide relight. Authored edits normally touch one settled cell and are much cheaper to reconcile against the published field than to solve every resident chunk from scratch. Chunk arrivals and departures still use a coalesced immutable worker request, keeping…
(state)(world &key immutable-p)Capture every resident chunk of WORLD for a from-scratch relight. With IMMUTABLE-P, copy content indices and capture absent-boundary semantics; the returned region may then be solved without reading the live world.
((name &key (tracy-value nil tracy-value-supplied-p)) &body body)Measure BODY as nested zone NAME for whichever measurement is watching. TRACY-VALUE, when supplied, is attached to the Tracy zone at exit. It does not affect the bounded CPU trace, whose zones retain time and runtime costs. Two independent things may be: a Tracy viewer attached to this image, and an opt-in…
(state)Settle STATE's queues over a candidate and publish once. Returns the chunks whose published light changed. Work runs on the calling owner thread; the counters record its actual cost so any move to captured producer batches is justified by measurement rather than guesswork.
(session)(session request value)Validate and accept one worker product on the render/GPU owning thread. This is the owner-side mirror of PERFORM-PRODUCTION-REQUEST: each request class carries its own publication rule, so a new kind of asynchronous product plugs in with one method on each generic rather than an edit to the drain loop. A stale…
(device descriptor)Asks the DEVICE for a handle to newly created instance of some object fulfilling the DESCRIPTOR.
The maximum of compatible quantities.
(region)(world x y z content)Install transferred block-content storage as a newly resident chunk. The caller gives WORLD ownership of CONTENT and must not mutate it afterward. CONTENT is a BLOCK-CONTENT-COLUMN. Installation rebinds that aggregate to the authoritative resident domain and WORLD's vocabulary, translating its indices in place if it…
(session)(state &optional center)(session &key center (timeout 30d0))Wait until SESSION has no unpublished streaming or lighting work. When CENTER is supplied, also wait for the residency window to reach it. This is intended for repeatable live profiling orchestration, not frame code.
(&key (timeout 10d0))(session &key (baseline-seconds 0.5d0) (timeout 10d0))Trace quiet play followed by one natural +X residency-window advance. The Tracy client must be enabled. This waits for a connected capture and a fully quiescent session, marks the baseline, leaves the game untouched for BASELINE-SECONDS, then moves the player just across the next chunk boundary. It returns only…
True while this image is offering zones to a Tracy viewer.
(player)(player)(player)(camera player)The value shapes the streaming window, which is only rebuilt when its centre moves; forget the centre so it rebuilds now.
(knob session)Do what SESSION needs after KNOB's value changed for the change to show. The primary method on KNOB does nothing: a value the renderer reads every frame is realized by the next frame. A realization mixin adds a method.
One live value: where it lives, what it measures, and -- by its class -- what SESSION must do after a change for the change to show.
A knob over a real, bounded and quantized.
(name (&key label (group :grading) documentation
(class ''scalar-knob)
quantity (type 'single-float)
unit-label minimum maximum step)
place)Define NAME as a knob of CLASS over the setf-able PLACE. PLACE may refer to SESSION, so a knob can live on the session -- its sky clock, its player -- as well as in a special. QUANTITY is a quantity plist as DEFINE-QUANTITY-CONSTANT takes, (:quantity ... :unit ...); it and TYPE make the knob's declaration, which…
Asynchronous chunk residency: generation and meshing off the frame thread.
The world/canvas thread is the only writer of residency and the only owner of GPU objects. It ships immutable work descriptions (chunk load requests, mesh snapshots) to the production worker, then validates each returned product against the current desired set and dependency stamps before publishing a bounded number of results per frame. Stale products fail validation harmlessly instead of requiring cancellation of active work.