Structure definition¶
A structure definition (“def”) is the single table you pass to
Registry.registerStructure(def) (or RCSF.defineStructure(def)).
It describes one buildable structure: its identity, how it builds, what it costs, how it
validates, and how it tears down.
Only id is required. Every other field is optional; when a callback is absent the
framework uses a sensible no-op default. The matching EmmyLua type is RCSFStructureDef
in Contracts.lua.
Note
Callback signatures below are the exact shapes the framework invokes. The framework
binds the structureId, so your def.* callbacks do not receive it.
Identity¶
Field |
Type |
Notes |
|---|---|---|
|
|
Required. Unique structure id. |
|
|
|
|
|
Variant set (keys are variant ids, e.g. |
|
|
Derived (sorted) from |
Build mode¶
Field |
Type |
Notes |
|---|---|---|
|
|
|
|
|
Legacy whole-structure build. Only used when |
|
|
Generic-builder hook: populate |
|
|
Return |
|
|
Return |
|
|
Per-piece material requirement fed to the active MaterialSource. |
|
|
Mutate the placed |
|
|
Finalize a placed structure (e.g. via |
Disassembly¶
Field |
Type |
Notes |
|---|---|---|
|
|
Objects to remove for a teardown. |
|
|
Return |
|
|
Post-teardown hook (bulk refunds, cleanup). |
|
|
|
Material¶
Pick one of materialSource or createMaterialSource. See
Concepts → Material sources.
Field |
Type |
Notes |
|---|---|---|
|
|
|
|
|
Custom source factory; wins over |
|
|
Legacy single-container config (tags etc.); see |
|
|
Minimum material count gate for container flows. |
Validation¶
Field |
Type |
Notes |
|---|---|---|
|
|
Opt into built-in validators by name (see DefaultValidators). |
|
|
|
|
|
|
|
|
Available default validator names: noEmptyPlan, noOverlap, slotKindCompatible,
roofNeedsWallUnder, floorNeedsCell, zAboveEmpty, minimumRoomRectSize, stairLinks,
obstructionFree, footprintFitsInRect, multiRectEdgeConnectivity.
Sprites & geometry¶
Field |
Type |
Notes |
|---|---|---|
|
|
Resolve a wall/piece sprite when a piece doesn’t carry an explicit |
|
|
Resolve a floor sprite for a cell. |
|
|
UI summary (counts, completeness). |
|
|
Override footprint derivation. |
|
|
Roof gable axis, piece count for costing, and preview tiles. |
|
|
Named callbacks routed by |
UI & flags¶
Field |
Type |
Notes |
|---|---|---|
|
|
Whether the floor paint phase is offered and which piece types are paintable. |
|
|
Custom presets file name. |
|
|
Use the scrollable catalog picker. |
|
|
|
|
|
|
|
|
Footprint / Z constraints. |
Worked example A - minimal (raw inventory, generic builder)¶
RCSF.Registry.registerStructure({
id = "MyMod_Shed",
roomName = "MyModShed",
useGenericBuilder = true,
materialSource = "raw",
variants = { default = true },
editor = { allowCells = true, pieceTypes = { "wall", "floor" } },
validation = { useDefaults = { "noEmptyPlan", "noOverlap", "slotKindCompatible" } },
})
Worked example B - heavily customized (MilitaryTents-style)¶
A def that overrides most of the pipeline (bag-of-containers materials, custom roofs, custom validation, per-object configuration):
RCSF.Registry.registerStructure({
id = "military_tent",
roomName = "MilitaryTentRoom",
variants = { green = true, yellow = true },
useGenericBuilder = true,
materialSource = "bag",
requireSingleRect = true,
singleStorey = true,
disableZControl = true,
editor = { allowCells = false, pieceTypes = { "wall", "door", "window" } },
validation = { useDefaults = { "noOverlap", "slotKindCompatible" } },
-- sprites & geometry
getPieceSpriteName = Tent.getWallSpriteName,
getPlacementSummary = Tent.getPlacementSummary,
getGableAxis = Tent.getGableAxis,
getRoofPieceCount = Tent.getRoofPieceCount,
getRoofPreview = Tent.getRoofPreview,
synthesizeRoofs = Tent.synthesizeRoofs,
-- build
beforeBuild = Tent.beforeBuild,
afterBuild = Tent.afterBuild,
configureWallObject = Tent.configureWallObject,
configureRoofObject = Tent.configureRoofObject,
getPieceMaterialRequirement = Tent.getPieceMaterialRequirement,
getMinimumContainerMaterialCount = Tent.getMinimumPackPieceCount,
buildCompletion = Tent.buildRoofAndRoom,
-- validate & disassemble
validateContainerPlacement = Tent.validatePackPlacement,
validateCompletion = Tent.validateRoofBuild,
validateDisassembly = Tent.validateDisassembly,
getRemovableObjects = Tent.getRemovableTentObjects,
beforeDisassemble = Tent.beforeDisassemble,
afterDisassemble = Tent.afterDisassemble,
})
Registration is validated¶
Registry.registerStructure validates your def. It errors only when id is missing;
otherwise it warns (and continues) on:
an unknown top-level key (with a “did you mean …?” suggestion for likely typos),
a
materialSourcevalue outside{ "raw", "universal", "bag" },both
materialSourceandcreateMaterialSourceset (createMaterialSource wins),a
validation.useDefaultsname that isn’t a known validator.
Warn-don’t-throw keeps the framework forward-compatible with consumers built against a
newer version. Disable validation entirely with RCSF_Config.validateDefs = false.
Tip
RCSF.defineStructure(def) wraps registration with the same
validation, fills a default variant, and batch-registers an inline pieces array - a nice
one-call shorthand.