Skip to main content

Entity Spawning Snippets

This page provides reusable code snippets for spawning entities in Don't Starve Together.

Basic Entity Spawning

Spawn a Simple Entity

-- Spawn a basic entity at the player's position
local function SpawnEntityAtPlayer(prefab)
local player = ThePlayer
if player then
local x, y, z = player.Transform:GetWorldPosition()
local entity = SpawnPrefab(prefab)
entity.Transform:SetPosition(x, y, z)
return entity
end
return nil
end

-- Usage
local rabbit = SpawnEntityAtPlayer("rabbit")

Spawn at Specific Position

-- Spawn an entity at specific coordinates
local function SpawnEntityAt(prefab, x, y, z)
local entity = SpawnPrefab(prefab)
entity.Transform:SetPosition(x, y, z)
return entity
end

-- Usage
local beefalo = SpawnEntityAt("beefalo", 100, 0, 100)

Advanced Entity Spawning

Spawn with Offset

-- Spawn an entity with offset from a position
local function SpawnEntityWithOffset(prefab, pos, offset_x, offset_y, offset_z)
local entity = SpawnPrefab(prefab)
entity.Transform:SetPosition(pos.x + offset_x, pos.y + offset_y, pos.z + offset_z)
return entity
end

-- Usage
local player_pos = ThePlayer:GetPosition()
local spider = SpawnEntityWithOffset("spider", player_pos, 5, 0, 5)

Spawn Multiple Entities in a Pattern

-- Spawn entities in a circle pattern
local function SpawnEntitiesInCircle(prefab, center_pos, radius, count)
local entities = {}
local angle_step = 2 * math.pi / count

for i = 1, count do
local angle = angle_step * i
local x = center_pos.x + radius * math.cos(angle)
local z = center_pos.z + radius * math.sin(angle)

local entity = SpawnPrefab(prefab)
entity.Transform:SetPosition(x, center_pos.y, z)
table.insert(entities, entity)
end

return entities
end

-- Usage
local player_pos = ThePlayer:GetPosition()
local hounds = SpawnEntitiesInCircle("hound", player_pos, 10, 5)

Spawn with Components Configuration

-- Spawn an entity with specific component configurations
local function SpawnConfiguredEntity(prefab, pos, config)
local entity = SpawnPrefab(prefab)
entity.Transform:SetPosition(pos:Get())

-- Configure components based on provided config
if config.health and entity.components.health then
entity.components.health:SetMaxHealth(config.health)
entity.components.health:SetPercent(config.health_percent or 1)
end

if config.combat and entity.components.combat then
entity.components.combat:SetDefaultDamage(config.combat.damage or 10)
entity.components.combat:SetAttackPeriod(config.combat.period or 2)
end

if config.lootdropper and entity.components.lootdropper then
entity.components.lootdropper:SetLoot(config.lootdropper.loot or {})
end

return entity
end

-- Usage
local config = {
health = 200,
health_percent = 0.5,
combat = {
damage = 20,
period = 3
},
lootdropper = {
loot = {"meat", "meat"}
}
}

local player_pos = ThePlayer:GetPosition()
local custom_hound = SpawnConfiguredEntity("hound", player_pos, config)

Special Spawning Techniques

Spawn with Safe Position Finding

-- Spawn an entity at a safe position near the target
local function SpawnEntityAtSafePosition(prefab, near_pos, min_dist, max_dist)
local entity = SpawnPrefab(prefab)

-- Try to find a valid spawn position
local function IsValidSpawnPoint(pt)
return TheWorld.Map:IsPassableAtPoint(pt.x, pt.y, pt.z) and
not TheWorld.Map:IsPointNearHole(pt) and
TheWorld.Map:GetTileAtPoint(pt.x, pt.y, pt.z) ~= GROUND.IMPASSABLE
end

-- Try several positions
local theta = math.random() * 2 * math.pi
local radius = min_dist
local attempts = 0
local max_attempts = 20

while attempts < max_attempts do
radius = min_dist + (max_dist - min_dist) * (attempts / max_attempts)
local offset = Vector3(radius * math.cos(theta), 0, radius * math.sin(theta))
local pos = near_pos + offset

if IsValidSpawnPoint(pos) then
entity.Transform:SetPosition(pos:Get())
return entity
end

theta = theta + math.pi * 0.5
attempts = attempts + 1
end

-- If no safe position found, use the original position
entity.Transform:SetPosition(near_pos:Get())
return entity
end

-- Usage
local player_pos = ThePlayer:GetPosition()
local safe_spider = SpawnEntityAtSafePosition("spider", player_pos, 5, 15)

Spawn with Delayed Activation

-- Spawn an entity that activates after a delay
local function SpawnDelayedEntity(prefab, pos, delay, activation_fn)
local entity = SpawnPrefab(prefab)
entity.Transform:SetPosition(pos:Get())

-- Initially disable the entity if possible
if entity.components.combat then
entity.components.combat:SetTarget(nil)
end

if entity.components.locomotor then
entity.components.locomotor:Stop()
end

-- Add a task to activate the entity after delay
entity:DoTaskInTime(delay, function(inst)
if activation_fn then
activation_fn(inst)
else
-- Default activation behavior
if inst.sg then
inst.sg:GoToState("idle")
end

if inst.components.sleeper then
inst.components.sleeper:WakeUp()
end
end
end)

return entity
end

-- Usage
local player_pos = ThePlayer:GetPosition()
local delayed_hound = SpawnDelayedEntity("hound", player_pos, 5, function(inst)
inst.components.combat:SetTarget(ThePlayer)
end)

Spawn with Network Synchronization

-- Spawn an entity with proper network synchronization
local function SpawnNetworkedEntity(prefab, pos)
-- Only the server should spawn the actual entity
if TheWorld.ismastersim then
local entity = SpawnPrefab(prefab)
entity.Transform:SetPosition(pos:Get())
return entity
else
-- On client, we can request the server to spawn
SendRPCToServer(RPC.SpawnPrefab, prefab, pos.x, pos.y, pos.z)
return nil
end
end

-- Server-side RPC handler (add to modmain.lua)
-- AddModRPCHandler("ModName", "SpawnPrefab", function(player, prefab, x, y, z)
-- local entity = SpawnPrefab(prefab)
-- entity.Transform:SetPosition(x, y, z)
-- end)

-- Usage
local player_pos = ThePlayer:GetPosition()
local networked_entity = SpawnNetworkedEntity("rabbit", player_pos)

Spawning Special Effects

Spawn FX at Entity

-- Spawn a visual effect at an entity's position
local function SpawnFXAtEntity(fx_prefab, entity, height_offset)
if entity and entity:IsValid() then
local x, y, z = entity.Transform:GetWorldPosition()
local fx = SpawnPrefab(fx_prefab)
fx.Transform:SetPosition(x, y + (height_offset or 0), z)
return fx
end
return nil
end

-- Usage
local fx = SpawnFXAtEntity("statue_transition", ThePlayer, 1)

Spawn FX with Automatic Cleanup

-- Spawn a temporary effect that cleans itself up
local function SpawnTemporaryFX(fx_prefab, pos, duration)
local fx = SpawnPrefab(fx_prefab)
fx.Transform:SetPosition(pos:Get())

-- Set up automatic removal after duration
fx:DoTaskInTime(duration, function(inst)
inst:Remove()
end)

return fx
end

-- Usage
local player_pos = ThePlayer:GetPosition()
local temp_fx = SpawnTemporaryFX("collapse_small", player_pos, 5)

Spawning Groups and Structures

Spawn Structure with Surrounding Entities

-- Spawn a structure with surrounding entities
local function SpawnStructureWithGuards(structure_prefab, guard_prefab, pos, guard_count, radius)
-- Spawn the main structure
local structure = SpawnPrefab(structure_prefab)
structure.Transform:SetPosition(pos:Get())

-- Spawn guards around it
local guards = {}
local angle_step = 2 * math.pi / guard_count

for i = 1, guard_count do
local angle = angle_step * i
local x = pos.x + radius * math.cos(angle)
local z = pos.z + radius * math.sin(angle)

local guard = SpawnPrefab(guard_prefab)
guard.Transform:SetPosition(x, pos.y, z)

-- Make guards protect the structure
if guard.components.combat then
guard:ListenForEvent("attacked", function(inst, data)
if structure:IsValid() and data.attacker and
data.attacker.components.combat then
guard.components.combat:SetTarget(data.attacker)
end
end, structure)
end

table.insert(guards, guard)
end

return structure, guards
end

-- Usage
local player_pos = ThePlayer:GetPosition()
local nest, spiders = SpawnStructureWithGuards("spiderden", "spider", player_pos, 3, 3)

Spawn Linked Entities

-- Spawn two entities that are linked to each other
local function SpawnLinkedEntities(prefab1, prefab2, pos1, pos2, link_tag)
local entity1 = SpawnPrefab(prefab1)
local entity2 = SpawnPrefab(prefab2)

entity1.Transform:SetPosition(pos1:Get())
entity2.Transform:SetPosition(pos2:Get())

-- Create a link between the entities
link_tag = link_tag or "linked_entity_" .. tostring(math.random(1000000))
entity1:AddTag(link_tag)
entity2:AddTag(link_tag)

entity1.linked_entity = entity2
entity2.linked_entity = entity1

return entity1, entity2
end

-- Usage
local pos1 = ThePlayer:GetPosition()
local pos2 = pos1 + Vector3(20, 0, 0)
local wormhole1, wormhole2 = SpawnLinkedEntities("wormhole", "wormhole", pos1, pos2, "wormhole_pair_1")

These snippets provide a foundation for various entity spawning scenarios in Don't Starve Together mods. Adapt them to your specific needs and combine them for more complex spawning behaviors.