Skip to content

Common Shapes

Mystery2099 edited this page Sep 18, 2026 · 3 revisions

Common shapes

You do not have to rebuild every slab, pillar, or fence from cuboids. CommonShapes contains a handful of shapes I kept needing often enough to give them proper factories.

The class lives in com.github.mystery2099.voxlib.shapes. Every factory validates its parameters and memoizes the finite set of possible results, so calling one again with the same arguments returns the same shape instance.

Factory reference

Slabs

val slab    = CommonShapes.createSlab(8)       // bottom 8 units, full block footprint
val topSlab = CommonShapes.createTopSlab(8)    // top 8 units
  • createSlab(height): full-width box from the bottom of the block to height. height is 1 to 16.
  • createTopSlab(height): full-width box from 16 - height to the top. 1 to 16.

Pillars

val centered = CommonShapes.createPillar(6)              // centered, 6 wide
val corner   = CommonShapes.createPillar(6, centered = false) // in the west/north corner
  • createPillar(width, centered): full-height column of the given width. width is 1 to 14. Centered pillars offset by (16 - width) / 2; uncentered pillars sit at x/z 0.

Tables

val table = CommonShapes.createTable()             // legWidth 2, topThickness 2
val beefy = CommonShapes.createTable(legWidth = 3, topThickness = 4)
  • createTable(legWidth, topThickness): a full-width top slab plus four corner legs of legWidth (1 to 6) and a top topThickness thick (1 to 6). Legs run from the floor to the underside of the top.

Chairs

val chair    = CommonShapes.createChair()                                  // seat 8, backrest 8
val lowSeat  = CommonShapes.createChair(seatHeight = 4)
val stool    = CommonShapes.createChair(hasBackrest = false)
val tallBack = CommonShapes.createChair(seatHeight = 8, backrestHeight = 16)
  • createChair(seatHeight, hasBackrest, backrestHeight): seat is a 14x2x14 pad (x/z 1 to 15) whose top sits at seatHeight + 2; a 12xseatHeightx12 base fills the legs area; the backrest rises from the seat top on the positive Z (south) side.
  • seatHeight is 1 to 12, backrestHeight is 1 to 16.
  • Chairs without a backrest ignore backrestHeight and share a canonical shape per seat height, since the parameter cannot affect their geometry.

Fences

val post = CommonShapes.createFencePost()
val fence = CommonShapes.createFenceConnections(north = true, south = true)
val cross = CommonShapes.createFenceConnections(
    north = true, east = true, south = true, west = true
)
  • createFencePost(): a 4x16x4 post centered in the block (x/z 6 to 10).
  • createFenceConnections(north, east, south, west): the post plus a 2-wide, 15-tall rail toward each connected side (rails run from y 6 to 15). Each boolean defaults to false.

Stairs

import net.minecraft.core.Direction

val stairs = CommonShapes.createStairs(Direction.NORTH)
  • createStairs(facing): a full bottom half plus an upper half toward the given horizontal direction. facing must be NORTH, EAST, SOUTH, or WEST; passing UP or DOWN throws IllegalArgumentException.

Importing

import com.github.mystery2099.voxlib.shapes.CommonShapes

Memoization behavior

  • Each factory family has a fixed array of slots covering every valid parameter combination (16 slab heights, 28 pillar variants, 36 tables, 321 chair variants, 16 fence connections, 4 stairs).
  • Results are created lazily on first use and retained for the life of the class loader. Creation is thread-safe through compare-and-set; a racing loser reuses the winner's shape.
  • All chairs together use 321 slots because backrestless chairs are canonicalized by seat height.
  • A hit skips shape construction, validation, and cache-key work entirely, so the memoized factories are cheap to call repeatedly even in getShape.

Memoization makes repeated factory calls cheap, but it does not make a lookup cheaper than doing no lookup. If a block's shape never changes, keep the result in a companion object or static field. See Caching and performance.

Java usage

CommonShapes is a Kotlin object. Java calls its instance methods through CommonShapes.INSTANCE, and Java callers must pass values for Kotlin default parameters:

import com.github.mystery2099.voxlib.shapes.CommonShapes;
import net.minecraft.core.Direction;

CommonShapes shapes = CommonShapes.INSTANCE;
VoxelShape slab = shapes.createSlab(8);
VoxelShape table = shapes.createTable(2, 2);
VoxelShape chair = shapes.createChair(8, true, 8);
VoxelShape stairs = shapes.createStairs(Direction.NORTH);
VoxelShape fence = shapes.createFenceConnections(true, true, false, false);

Kotlin named arguments are unavailable in Java. The fence booleans are north, east, south, west.

Clone this wiki locally