luvcraft/birthday/gazebo.lisp
The octagon vocabulary
The |dx|+|dz| bound that chamfers a square of half-width radius into a
near-regular octagon.
Call function with (dx dz rim-p) over every cell of the filled octagon.
The eight vertex cells of the octagon, as (dx dz) pairs.
The vertices of the ideal octagon sit on the circumradius R/cos(pi/8) at the eight half-step angles; rounding those puts each post exactly on the rim ring where the flat sides meet the chamfers.
One cell near the middle of each of the eight rim edges.
The axis-aligned midpoints land on the rim directly; the diagonal ones round to just outside the chamfer, so walk inward until the octagon holds the cell -- one step, onto the row under the eave.
Tier radii from eave to cap: one wider than the floor, then shrinking by one and two alternately so the silhouette curves instead of coning.
Reading the ground
The highest solid surface y among five columns around the center.
Taking the maximum keeps the plinth proud of a gently uneven clearing
instead of half-buried in it. Absent chunks read as air, so a wholly
unmaterialized site errors here, by name, rather than as a mysterious
chunk-not-resident mid-build.
The build
Build the party gazebo centered on center-x, center-z and return its
anchor plist (see the file header). ground-y is the y of the surface
block to stand on; when NIL the terrain is probed for it. All edits go
through the world's source overlay in one change transaction; the caller
relights.
The flat side at |dz| = radius spans the cells between two
posts; everything strictly between them is entrance.
Clear the interior air band first, so a stray shrub or terrain bump inside the footprint does not end up furnishing the party.
The plinth: stone brick rim, planks field, sandstone where the path runs through, cobblestone pads under the posts, and a cobblestone underpinning wherever the rim overhangs a dip.
Sandstone steps: a flush landing two cells deep outside each entrance, underpinned where the meadow falls away.
Posts and railings. Railings run one block high along the rim between posts; the two entrance sides stay completely open.
The roof: filled slate octagons from the eave up, so there is no hole to rain through, then the crystal finial on the cap.
Garland lights tucked under the eave: a crystal hanging from the overhang at each rim-edge midpoint, clear of the posts.
The cake on its table: a low 3x3 planks table, a full 3x3 snow base tier (a clean white box reads as frosting; a cut-corner tier read as a grey lump), a single snow top tier, one crystal candle whose glow lights the party.
(world &key (center-x 0) (center-z 0)
ground-y (radius 7))Build the party gazebo centered on CENTER-X, CENTER-Z and return its anchor plist (see the file header). GROUND-Y is the y of the surface block to stand on; when NIL the terrain is probed for it. All edits go through the world's source overlay in one change transaction; the caller relights.
The interactive block world built on luv.
(block world x y z)((world) &body body)(radius)The |dx|+|dz| bound that chamfers a square of half-width RADIUS into a near-regular octagon.
Multiplication and scalar scaling.
The componentwise square root of a raw value.
(dx dz radius)Logical conjunction of tests and raw truth values.
Test whether one compatible scalar is at most another.
The componentwise absolute value of a raw value.
Addition over compatible quantities.
(dx dz radius)Logical negation of one test or raw truth value.
(function radius)Subtraction or unary negation.
(radius)The eight vertex cells of the octagon, as (dx dz) pairs. The vertices of the ideal octagon sit on the circumradius R/cos(pi/8) at the eight half-step angles; rounding those puts each post exactly on the rim ring where the flat sides meet the chamfers.
Division of two represented quantities.
Test whether two compatible scalars are equal.
(radius)One cell near the middle of each of the eight rim edges. The axis-aligned midpoints land on the rim directly; the diagonal ones round to just outside the chamfer, so walk inward until the octagon holds the cell -- one step, onto the row under the eave.
(radius)Tier radii from eave to cap: one wider than the floor, then shrinking by one and two alternately so the silhouette curves instead of coning.
(world center-x center-z radius)The highest solid surface y among five columns around the center. Taking the maximum keeps the plinth proud of a gently uneven clearing instead of half-buried in it. Absent chunks read as air, so a wholly unmaterialized site errors here, by name, rather than as a mysterious CHUNK-NOT-RESIDENT mid-build.
(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…
The maximum of compatible quantities.
Logical disjunction of tests and raw truth values.
The gazebo: a big beautiful pavilion at the heart of the party.
Contract: (
build-birthday-gazeboworld &key center-x center-z ground-y radius) builds the gazebo out of block edits (luvcraft:edit-block-atinside oneluvcraft::with-world-change-transaction; the caller relights) and returns a plist describing the interesting anchor points for the other decorations: (:floor-y N ; the y of the floor slab blocks :roof-apex (x y z) ; above the finial, where a balloon ; bundle ties :post-tops ((x y z) ...) ; topmost wood block of each post, ; for balloon strings :cake (x y z)) ; center block of the cake's base tierConstruction is octagons all the way up. One membership predicate -- a square chamfered at |dx|+|dz| <= round(R*sqrt2) -- draws the floor slab, the railing ring, and every roof tier, so the plan stays concentric by construction. The eight posts stand where the octagon's vertices land: computed from the circumradius R/cos(pi/8) at the eight half-step angles and rounded onto the grid, rather than placed by hand, so a different RADIUS keeps its corners true.
Vertically: a one-block plinth lifts the floor above the meadow (stone brick rim, planks field, cobblestone pads under the posts); five-block wood posts carry a stack of slate octagons that starts one cell wider than the floor -- a real eave -- and shrinks by one and two alternately to a cap, crowned with a glowing crystal finial. Crystal garland lights hang under the eave at the rim-edge midpoints, so the covered interior glows warm instead of going dark under the solid roof. Two flat sides (toward -z and +z) are left entirely open between their posts, with a sandstone path through the rim and a sandstone step out onto the grass, so a four-year-old can run straight in, past the cake, and out the other side.
Blocks are the existing palette only: stone bricks and cobblestone for the base, planks for floor and railings, wood for posts, slate for the tiered roof, crystal for the finial and garland lights, snow for the cake's frosting.