Statue Shaper

Overview

Statue Shaper is a mod for the survival game Vintage Story. The main mod and its two published content packs have about 5,000 downloads.

Vintage Story is made of one-metre blocks, but it also has a chisel. A block subdivides into a 16×16×16 grid of voxels, and you knock those out to sculpt detail finer than a block. That is the entire toolset: freehand, no template, no undo worth the name. Carving a statue by eye is possible and almost nobody does it.

Statue Shaper adds the template. You place frames in the footprint you want and attach a controller, then pick a voxel blueprint from a browser. Fill the volume with whatever material you want the statue made of, and a marking-line tool chalks outlines around exactly the voxels you need to remove. Chisel along the chalk and it disappears as the voxels do. The Capture tab saves anything built on the frames as a reusable blueprint.

1 / 5

Partially carved voxel statue with chalk guides around the remaining blocks

Four frame tiers set the size limit, from a 2×2×2 ornament to a 32×32×32 colossus. The statue is made of whatever you filled the volume with, so the same blueprint gives a marble angel or a terracotta one.

Version 1.4.2 is licensed under AGPL-3.0 and available from mods.vintagestory.at/statueshaper.

Turning a Mesh Into a Blueprint

The blueprints are voxelised 3D scans of real sculptures, and the mod converts them itself. An STL and OBJ importer runs in-game, and the same conversion core backs a command-line tool, so the two cannot drift apart.

Filling a mesh solid means flood-filling the outside and keeping what is left, which works until the scan has a hole and the fill leaks inward. So the converter checks whether the mesh is watertight, ignoring the degenerate slivers real scans have around the poles. When that check fails it falls back to an even-odd inside test voted across all three axes, on the reasoning that a hole usually breaks only one direction.

The placement optimiser is the part I am most pleased with. Where the model sits relative to the voxel grid changes how the shape decomposes into chisel operations, and chiselling works in power-of-two chunks. So the converter searches sub-voxel phases and cell shifts, scores each with a model of the in-game chunk decomposition, and keeps the placement costing the player the fewest chisel actions. It optimises for how much work the human has to do, not for geometric fidelity.

Two sub-voxel placements of the same silhouette, and what each costs to chiselThe same round silhouette rasterised into one sixteen by sixteen voxel cell at two different sub-voxel offsets. The material to remove is decomposed greedily into aligned power-of-two chunks. The first placement needs 54 chunks; the second needs 28, which is what the converter keeps.placement as first rasterisedplacement the optimiser keeps54chisel actions28chisel actions, 48% fewermaterial keptone chisel action: an aligned chunk of 16, 8, 4, 2 or 1 voxels
An illustrative shape and a flat slice of what is really a cube decomposition, but the counts are honest: both were computed with the same greedy largest-first rule the mod uses. Moving the silhouette a fraction of a voxel changes nothing a player can see and roughly halves the work.

Engineering

Rendering previews used to freeze the game for seconds when a player hovered over a blueprint. One client-wide cache now owns every preview mesh. A worker pool builds the meshes from a priority queue ordered by voxel volume, so small previews never wait behind a colossus. This pipeline also produced an unusual rendering bug: opening the picker made water elsewhere in the world render at an oblique angle with no depth. The preview renderer changed depth, culling and blending state inside the engine's opaque stage. State that it failed to restore then affected the liquid pass later in the frame.

Players can upload blueprints, so the decoder treats them as untrusted input. It limits decompressed bytes, each grid dimension and the total decoded voxel count. The decoder enforces the byte limit during inflation, stopping a decompression bomb before writing the expanded payload.

The server stores identical uploads once. Each blueprint keeps an ordered list of the players holding it, and the player at the head pays the storage cost. If that player leaves, ownership transfers to the first holder with enough space. If nobody has enough space, the operation asks for confirmation and changes nothing until the departing owner agrees to delete the blueprint.

The project builds with nullable warnings as errors. I replaced nullable references with explicit Option values. Operations that can fail now return a result containing either a value or an error, and methods return tuples instead of writing through out parameters. These changes followed a crash caused by opening a controller menu before attaching the controller to any frames. The frame assembly now represents that state explicitly instead of using null.

The Content Packs

The mod ships no statues of its own. Four companion packs supply them, 69 sculptures between them. Greek, Holy and Medieval include full-height and short versions. Monuments instead pairs each full-detail blueprint with a lower-resolution version at the same scale. Greek and Holy are published; Medieval and Monuments are built but not released.

1 / 4

Voxelised medieval equestrian monument in Vintage Story

Every blueprint is a voxelisation of somebody's 3D scan of a real sculpture, which makes licensing the hard part. Each blueprint inherits its source scan's licence, every pack ships a per-blueprint licence file and an attribution table, and the build tool validates licences against an exact list of six accepted strings rather than pattern-matching them.

The Medieval pack's attribution ledger is the document I would show someone. It has three sections. First, the models that shipped. Second, the ones held out with a reason each, including a tomb effigy excluded because it lies down and the mod builds vertical columns. Third, three that voxelise perfectly well and still did not ship, because their licensing never cleared.

mpg3@sfu.ca, linkedin · Updated 2026-08-13