DramaticShapeVoxelMod archival mirror · read-only
56a32f1c43354469f4c7e3bdee54dc2abf4ceca3

console class: a machine on furniture, without the furniture's edging

DramaticShape · 2026-07-27 · parent 8b73cbd54d

console class: a machine on furniture, without the furniture's edging

The Poke Mart register shares its two tiles with the counter, which draws
a full-height black rule down each outer edge. Black always survives the
shade flood, so the billboard pool extruded those rules too and the
machine stood flanked by a pair of tall black slabs.

A white column separates them from the register body, so they are their
own connected components -- which is exactly what `cutout`'s one-object
contract drops. `cutout` is a single voxel though, and a register wants
body, so this adds `console`: the billboard treatment at ten voxels with
that same contract. It cannot be the default for the thick pools,
because a cluster there may legitimately hold several objects (two
stools side by side, a leaf beside a vase).

Changed files

data/voxel_heights.lua | 15 +++++++++++++--
 lib/Structures.lua     | 17 +++++++++++------
 lib/TileShape.lua      |  6 ++++++
 3 files changed, 30 insertions(+), 8 deletions(-)

Diff

diff --git a/data/voxel_heights.lua b/data/voxel_heights.lua
index a3f6975..f74d52c 100644
--- a/data/voxel_heights.lua
+++ b/data/voxel_heights.lua
@@ -753,8 +753,19 @@ return {
       -- box.  Its own pool, so the counter can never absorb it.  The art
       -- has a clean light margin on three sides and a black outline all
       -- round, so the shade flood drains the work surface away and leaves
-      -- the machine whole (verified pixel by pixel before shooting).
-      billboard = { 14, 15, 30, 31 },
+      -- the machine whole.
+      --
+      -- `console`, not `billboard`, for the two vertical black rules the
+      -- COUNTER draws down the outer edges of those same tiles (columns
+      -- 0 and 15 of the pair, full height).  They are the counter's own
+      -- edging, not the register, but black always survives the shade
+      -- flood, so the billboard pool extruded them too and the machine
+      -- stood flanked by a pair of tall black slabs.  A white column
+      -- separates them from the register body, so they are their own
+      -- connected components -- and `console` carries the same
+      -- one-object contract `cutout` has, which keeps the largest
+      -- drawing and drops them, at ten voxels of body rather than one.
+      console = { 14, 15, 30, 31 },
       -- the free-standing shelf racks: TALL drawings, not deep ones --
       -- each rank collapses onto a one-cell-deep shelf at its drawn
       -- height (the Dojo/Red's-house treatment). 64/65/67 and 80/81/83
diff --git a/lib/Structures.lua b/lib/Structures.lua
index 3baf693..62d77d9 100644
--- a/lib/Structures.lua
+++ b/lib/Structures.lua
@@ -69,7 +69,7 @@ local OBJECT_DEPTH = 6             -- voxel thickness of a detected prop
 -- `signpost` is a plate on a stick -- 2 voxels, the thinnest that still
 -- shows an edge
 local PINNED_DEPTH = { billboard = 10, prop = 5, stool = 10, cutout = 1,
-                       post = 6, signpost = 2 }
+                       console = 10, post = 6, signpost = 2 }
 
 local MAX_ROWS = 6                 -- volume height cap: 48px
 
@@ -1994,13 +1994,18 @@ function Structures.buildObject(S, map, region, cluster,
     c.z1 = c.z0 + depth
   end
 
-  -- A `cutout` pin is ONE object by contract: keep only the largest
-  -- connected drawing.  Loose black scraps -- a cast shadow's drawn
-  -- edge, a seam -- are background even though black pixels always
-  -- survive the shade flood, and this is what removes them.
+  -- A `cutout` or `console` pin is ONE object by contract: keep only
+  -- the largest connected drawing.  Loose black scraps -- a cast
+  -- shadow's drawn edge, a seam, the vertical rules the surrounding
+  -- furniture draws down its own edges -- are background even though
+  -- black pixels always survive the shade flood, and this is what
+  -- removes them.  Every other pool may hold several objects per
+  -- cluster (two stools side by side, a leaf beside a vase), so this
+  -- cannot be the default.
   if force then
     local cs = S.shapeAt[keyOf(cluster.tiles[1][1], cluster.tiles[1][2])]
-    if cs and cs.class == "cutout" and #comps > 1 then
+    if cs and (cs.class == "cutout" or cs.class == "console")
+       and #comps > 1 then
       local biggest = comps[1]
       for _, c in ipairs(comps) do
         if c.n > biggest.n then biggest = c end
diff --git a/lib/TileShape.lua b/lib/TileShape.lua
index a1fddcb..4f0e9d5 100644
--- a/lib/TileShape.lua
+++ b/lib/TileShape.lua
@@ -81,6 +81,7 @@ local FALLBACK_HEIGHTS = {
   desk = 24,
   prop = 16,
   cutout = 16,
+  console = 16,
   relief = 3,
   bookcase = 32,
   stair_e = 16,
@@ -150,6 +151,11 @@ local ART = {
   desk = "upright",
   prop = "billboard",
   cutout = "billboard",
+  -- a machine standing on furniture: the billboard treatment with
+  -- body, plus the one-object contract `cutout` has -- the drawing is
+  -- ringed by the furniture it sits on, and those edges must not be
+  -- extruded along with it (see Structures' component filter)
+  console = "billboard",
   relief = "relief",
   -- free-standing shelves: the drawing is TALL, not deep -- Structures
   -- collapses each drawn rank onto a one-cell-deep box at full height