Skip to main content

Last Update: 2023-07-06

Structure Prefabs

Structure prefabs define the buildings, crafting stations, and other placeable objects that players can construct and interact with in Don't Starve Together.

Structure Creation

Structures in Don't Starve Together are defined as prefabs that typically include components like workable, prototyper, and other specialized components based on the structure's functionality. Here's a typical structure for a structure prefab:

local assets = {
Asset("ANIM", "anim/firepit.zip"),
Asset("ANIM", "anim/firepit_fire.zip"),
Asset("SOUND", "sound/common.fsb"),
}

local prefabs = {
"campfirefire",
"collapse_small",
"ash",
}

-- Main creation function
local function fn()
local inst = CreateEntity()

-- Add required engine components
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddSoundEmitter()
inst.entity:AddNetwork()

-- Configure physics
MakeObstaclePhysics(inst, .3)

-- Configure animations
inst.AnimState:SetBank("firepit")
inst.AnimState:SetBuild("firepit")
inst.AnimState:PlayAnimation("idle")

-- Add tags for identification and optimization
inst:AddTag("structure")
inst:AddTag("fire")
inst:AddTag("campfire")

-- Network setup
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end

-- Add game components
inst:AddComponent("inspectable")
inst:AddComponent("lootdropper")
inst:AddComponent("workable")
inst:AddComponent("cooker")
inst:AddComponent("fueled")
inst:AddComponent("heater")
inst:AddComponent("light")

-- Configure components
inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
inst.components.workable:SetWorkLeft(4)
inst.components.workable:SetOnFinishCallback(onhammered)
inst.components.workable:SetOnWorkCallback(onhit)

inst.components.fueled:SetSections(4)
inst.components.fueled:InitializeFuelLevel(TUNING.FIREPIT_FUEL_MAX)
inst.components.fueled:SetTakeFuelFn(ontakefuel)
inst.components.fueled:SetUpdateFn(onupdatefueled)
inst.components.fueled:SetSectionCallback(onfuelchange)
inst.components.fueled:SetDepletedFn(onextinguish)

inst.components.heater:SetThermics(true, true)
inst.components.heater:SetHeaterRadius(TUNING.FIREPIT_HEAT_RADIUS)

-- Add special behaviors
MakeHauntableIgnite(inst)

return inst
end

return Prefab("firepit", fn, assets, prefabs)

Core Structure Components

Most structures have several common components:

ComponentPurpose
workableAllows the structure to be worked on (hammered, mined, etc.)
inspectableAllows the structure to be examined by players
lootdropperControls what items drop when the structure is destroyed
savedrotationPreserves rotation when the game is saved
physicsHandles collision with other entities

Structure Categories

Structures in Don't Starve Together fall into several categories:

Crafting Stations

Structures that allow crafting specific items:

-- Prototyper component for crafting stations
inst:AddComponent("prototyper")
inst.components.prototyper.trees = TUNING.PROTOTYPER_TREES.SCIENCEMACHINE

Resource Processors

Structures that transform resources:

-- Stewer component for cooking crockpot recipes
inst:AddComponent("stewer")
inst.components.stewer:SetCookingTime(TUNING.CROCKPOT_COOK_TIME)
inst.components.stewer:SetNumSlots(4)

-- Dryer component for drying meat
inst:AddComponent("dryer")
inst.components.dryer:SetDryTime(TUNING.MEAT_DRY_TIME)
inst.components.dryer:SetStartDryingFn(startdryfn)
inst.components.dryer:SetDoneDryingFn(donedryfn)

Light Sources

Structures that provide light:

-- Light component
inst:AddComponent("light")
inst.components.light:SetRadius(TUNING.FIREPIT_LIGHT_RADIUS)
inst.components.light:SetFalloff(TUNING.FIREPIT_LIGHT_FALLOFF)
inst.components.light:SetIntensity(TUNING.FIREPIT_LIGHT_INTENSITY)
inst.components.light:SetColour(255/255, 255/255, 192/255)
inst.components.light:Enable(false)

-- Fueled component for light sources
inst:AddComponent("fueled")
inst.components.fueled:SetSections(4)
inst.components.fueled:InitializeFuelLevel(TUNING.FIREPIT_FUEL_MAX)

Storage

Structures that store items:

-- Container component
inst:AddComponent("container")
inst.components.container:WidgetSetup("chest")
inst.components.container.onopenfn = onopen
inst.components.container.onclosefn = onclose

Placement System

Structures often use the placer system for placement previews:

-- Create a placer prefab
local function placer_postinit_fn(inst)
-- Show valid/invalid placement
inst.AnimState:SetLightOverride(1)
inst.AnimState:PlayAnimation("idle")

-- Add placement test functions
inst.components.placer:AddSnapping(function(pt, ...)
return FindWalkableOffset(pt, ...)
end)
end

-- Define placer in main prefab
return Prefab("firepit", fn, assets, prefabs),
MakePlacer("firepit_placer", "firepit", "firepit", "idle", nil, nil, nil, nil, nil, nil, placer_postinit_fn)

For an in-depth analysis of how the placement system can be enhanced with grid-based positioning, see the Geometric Placement mod case study, which demonstrates advanced techniques for modifying placement behavior.

Building Phases

Many structures have construction phases:

-- Define multiple phases
local PHASE_NAMES = { "COMPLETE", "STUFFED", "EMBERS", "ASHES" }

-- Phase transition function
local function OnPhaseChanged(inst, phase)
if phase == "COMPLETE" then
inst.AnimState:PlayAnimation("idle")
inst.components.cooker:Enable(true)
elseif phase == "STUFFED" then
inst.AnimState:PlayAnimation("stuffed")
inst.components.cooker:Enable(false)
elseif phase == "EMBERS" then
inst.AnimState:PlayAnimation("embers")
inst.components.cooker:Enable(false)
elseif phase == "ASHES" then
inst.AnimState:PlayAnimation("ashes")
inst.components.cooker:Enable(false)
end
end

Working and Destruction

Structures can be worked on (hammered, mined) using the workable component:

-- Configure workable component
inst:AddComponent("workable")
inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
inst.components.workable:SetWorkLeft(4) -- Number of hits to destroy
inst.components.workable:SetOnFinishCallback(onhammered) -- Called when destroyed
inst.components.workable:SetOnWorkCallback(onhit) -- Called on each hit

-- Example destruction callback
local function onhammered(inst, worker)
inst.components.lootdropper:DropLoot()

-- Visual/audio effects
local fx = SpawnPrefab("collapse_small")
fx.Transform:SetPosition(inst.Transform:GetWorldPosition())
fx:SetMaterial("wood")

inst:Remove()
end

Example: Firepit Structure Prefab

The firepit is a basic structure that demonstrates many common patterns:

-- Light and heat based on fuel level
local function onfuelchange(inst)
local fueled = inst.components.fueled
local heatpct = fueled:GetPercent()

-- Update light radius and intensity
inst.components.light:SetRadius(TUNING.FIREPIT_LIGHT_RADIUS * heatpct)
inst.components.light:SetIntensity(TUNING.FIREPIT_LIGHT_INTENSITY * heatpct)

-- Update heat radius
inst.components.heater:SetThermics(true, true)
inst.components.heater:SetHeatRadius(TUNING.FIREPIT_HEAT_RADIUS * heatpct)

-- Update animation based on fuel level
if fueled:IsEmpty() then
inst.AnimState:PlayAnimation("dead")
inst.components.light:Enable(false)
else
if fueled:GetPercent() <= 0.25 then
inst.AnimState:PlayAnimation("low")
elseif fueled:GetPercent() <= 0.5 then
inst.AnimState:PlayAnimation("med")
else
inst.AnimState:PlayAnimation("high")
end
inst.components.light:Enable(true)
end
end

-- Fuel handling
local function ontakefuel(inst)
inst.SoundEmitter:PlaySound("dontstarve/common/fireAddFuel")

-- Start a "sizzle" sound when wet ingredients are added
if inst.components.fueled.wetness > 0 then
inst.SoundEmitter:PlaySound("dontstarve/common/fireWetFuel")
end
end

Specialized Structure Behaviors

Many structures have unique behaviors implemented through specialized components:

-- Ice Flingomatic for extinguishing fires
inst:AddComponent("waterprojector")
inst.components.waterprojector:SetRange(TUNING.ICEHAT_PROJECTILE_RANGE)

-- Lightning Rod for lightning protection
inst:AddComponent("lightningrod")
inst.components.lightningrod:SetOnStruckFn(onstruck)

-- Teleporter for moving between locations
inst:AddComponent("teleporter")
inst.components.teleporter.targetTeleporter = GetTargetTeleporter

Structure Interaction

Structures often have specialized interaction actions:

-- Interactable component for actions
inst:AddComponent("activatable")
inst.components.activatable.OnActivate = OnActivate
inst.components.activatable.ActivateVerb = STRINGS.ACTIONS.ACTIVATE.GENERIC

-- Trading component for structures that accept items
inst:AddComponent("trader")
inst.components.trader:SetAcceptTest(ShouldAcceptItem)
inst.components.trader.onaccept = OnGetItem