Getting Started with DST Lua API
Welcome to the Don't Starve Together (DST) Lua API documentation! This comprehensive guide will take you from basic API understanding to creating advanced mods for the game.
Version History
Date | Build | Changes |
---|---|---|
2023-06-15 | 675312 | Initial documentation |
Introduction to DST Modding
Don't Starve Together is a multiplayer survival game developed by Klei Entertainment. The game is highly moddable, allowing players and developers to create custom content and modify gameplay through Lua scripting.
What is the DST Lua API?
The DST Lua API is a comprehensive set of functions, components, and systems that allow modders to interact with the game's core functionality. Through this API, you can:
- Create new items, characters, creatures, and structures
- Modify existing game mechanics and behaviors
- Add new gameplay features and systems
- Create custom UI elements and screens
- Change world generation and environmental features
Prerequisites
Before diving into DST modding, you should have:
- Basic programming knowledge
- Familiarity with Lua programming language
- Understanding of Don't Starve Together gameplay mechanics
- A copy of Don't Starve Together on Steam
- Text editor for code development
- Steam Workshop access for distribution
Setting Up Your Modding Environment
Find Your Mods Directory
- Windows:
C:\Users\[YourUsername]\Documents\Klei\DoNotStarveTogether\mods\
- Mac:
~/Documents/Klei/DoNotStarveTogether/mods/
- Linux:
~/.klei/DoNotStarveTogether/mods/
Basic Mod Structure
my_first_mod/
├── modinfo.lua # Mod metadata and configuration
├── modmain.lua # Main entry point for your mod
├── scripts/ # Custom scripts folder
│ ├── prefabs/ # Custom entity definitions
│ └── components/ # Custom component definitions
├── anim/ # Custom animations
└── images/ # Images and icons
└── inventoryimages/ # Item icons
Understanding the Core Systems
DST's codebase is organized around several core systems:
Entity-Component System
The game uses an entity-component architecture:
- Entities: Base objects in the world (players, creatures, items)
- Components: Modular pieces of functionality attached to entities
- Prefabs: Templates for creating entities with predefined components
Script Organization
The API scripts are organized in several key directories:
- actions.lua: Defines player actions like chopping, mining, etc.
- behaviours/: AI behavior scripts
- brains/: AI decision-making scripts
- components/: Entity component definitions
- prefabs/: Entity template definitions
- stategraphs/: State machine definitions for entities
Your First Mod: Complete Tutorial
Step 1: Create Mod Directory Structure
Create your mod folder structure in the game's mods directory:
mods/
└── your_first_mod/
├── modinfo.lua # Mod metadata and configuration
├── modmain.lua # Main mod entry point
├── scripts/
│ └── prefabs/
│ └── myitem.lua # Custom item definition
└── images/
└── inventoryimages/
└── myitem.tex # Item icon
Step 2: Create modinfo.lua
-- modinfo.lua - Mod metadata and configuration
name = "My First Mod"
description = "A simple example mod for learning DST modding"
author = "Your Name"
version = "1.0.0"
forumthread = ""
api_version = 10
dst_compatible = true
dont_starve_compatible = false
reign_of_giants_compatible = false
all_clients_require_mod = true
client_only_mod = false
icon_atlas = "modicon.xml"
icon = "modicon.tex"
-- Mod configuration options
configuration_options = {
{
name = "item_durability",
label = "Item Durability",
options = {
{description = "Low", data = 50},
{description = "Normal", data = 100},
{description = "High", data = 150},
},
default = 100,
}
}
Step 3: Create modmain.lua
-- modmain.lua - Main mod entry point
-- This file is executed when the mod loads
-- Add your custom item to the prefab files list
PrefabFiles = {
"myitem",
}
-- Add item to inventory images
Assets = {
Asset("ATLAS", "images/inventoryimages/myitem.xml"),
Asset("IMAGE", "images/inventoryimages/myitem.tex"),
}
-- Add recipe for your item
AddRecipe2("myitem",
{Ingredient("twigs", 2), Ingredient("flint", 1)},
TECH.NONE,
{
placer = "myitem_placer",
min_spacing = 0,
atlas = "images/inventoryimages/myitem.xml",
image = "myitem.tex",
}
)
-- Example of using mod configuration
local config_durability = GetModConfigData("item_durability") or 100
TUNING.MYITEM_DURABILITY = config_durability
-- Debug print to confirm mod loading
modprint("My First Mod loaded successfully!")
Step 4: Create Custom Item Prefab
-- scripts/prefabs/myitem.lua - Custom item definition
local assets = {
Asset("ANIM", "anim/myitem.zip"),
Asset("ATLAS", "images/inventoryimages/myitem.xml"),
Asset("IMAGE", "images/inventoryimages/myitem.tex"),
}
local function fn()
local inst = CreateEntity()
-- Add standard entity components
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
-- Set up visual appearance
inst.AnimState:SetBank("myitem")
inst.AnimState:SetBuild("myitem")
inst.AnimState:PlayAnimation("idle")
-- Add to inventory item group
MakeInventoryPhysics(inst)
-- Network entity setup
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
-- Add inventory item component
inst:AddComponent("inventoryitem")
inst.components.inventoryitem.imagename = "myitem"
inst.components.inventoryitem.atlasname = "images/inventoryimages/myitem.xml"
-- Add inspectable component
inst:AddComponent("inspectable")
-- Add tool functionality (example: axe)
inst:AddComponent("tool")
inst.components.tool:SetAction(ACTIONS.CHOP)
-- Add finite uses
inst:AddComponent("finiteuses")
inst.components.finiteuses:SetMaxUses(TUNING.MYITEM_DURABILITY or 100)
inst.components.finiteuses:SetUses(TUNING.MYITEM_DURABILITY or 100)
inst.components.finiteuses:SetOnFinished(inst.Remove)
return inst
end
return Prefab("myitem", fn, assets)
Step 5: Testing Your Mod
- Enable Debug Mode: Set
CHEATS_ENABLED = true
in settings - Load the Game: Start DST and enable your mod
- Spawn Test Item: Use console command
c_give("myitem", 1)
- Test Functionality: Verify the item works as expected
Step 6: Common Debugging Commands
-- Console commands for mod debugging
c_give("myitem", 1) -- Give yourself the item
c_spawn("myitem", 5) -- Spawn items on ground
c_find("myitem") -- Find instances in world
print(TUNING.MYITEM_DURABILITY) -- Check configuration values
Common Modding Scenarios
Scenario 1: Creating a Custom Character
-- modmain.lua for character mod
local require = GLOBAL.require
local STRINGS = GLOBAL.STRINGS
-- Character assets
Assets = {
Asset("ANIM", "anim/mycharacter.zip"),
Asset("ANIM", "anim/ghost_mycharacter_build.zip"),
}
-- Add character to game
AddModCharacter("mycharacter", "FEMALE", {
{ type = "normal_skin", play_emotes = true },
{ type = "ghost_skin", anim_bank = "ghost", idle_anim = "idle" }
})
-- Character strings
STRINGS.CHARACTER_NAMES.mycharacter = "My Character"
STRINGS.CHARACTER_DESCRIPTIONS.mycharacter = "A unique character with special abilities"
STRINGS.CHARACTER_QUOTES.mycharacter = "\"I have my own way of doing things.\""
-- Character-specific stats
AddPlayerPostInit(function(inst)
if inst.prefab == "mycharacter" then
-- Custom starting items
inst.components.inventory:GiveItem(SpawnPrefab("mystartingitem"))
-- Custom stats
inst.components.health:SetMaxHealth(120)
inst.components.sanity:SetMax(180)
inst.components.hunger:SetMax(140)
end
end)
Scenario 2: Adding Custom Recipes and Crafting
-- Custom crafting station
AddRecipe2("mycraftingstation",
{Ingredient("boards", 4), Ingredient("rope", 2)},
TECH.SCIENCE_ONE,
{
placer = "mycraftingstation_placer",
atlas = "images/inventoryimages/mycraftingstation.xml",
image = "mycraftingstation.tex",
},
{"STRUCTURES", "CRAFTING"}
)
-- Recipe that requires custom station
AddRecipe2("advanceditem",
{Ingredient("gold", 2), Ingredient("gears", 1)},
TECH.MYCUSTOMTECH,
{
builder_tag = "mycraftingstation", -- Requires being near custom station
atlas = "images/inventoryimages/advanceditem.xml",
image = "advanceditem.tex",
}
)
-- Add new tech level
TECH.MYCUSTOMTECH = {MYCUSTOMTECH = 1}
Scenario 3: World Generation Modifications
-- Add custom world generation content
AddRoomPreInit("Forest", function(room)
-- Add custom prefab to forest rooms
room.contents.distributeprefabs = room.contents.distributeprefabs or {}
table.insert(room.contents.distributeprefabs, "mycustomprefab")
end)
-- Add custom biome
AddLevel({
id = "MYCUSTOMLEVEL",
name = "My Custom World",
desc = "A world with custom features",
location = "forest",
version = 2,
overrides = {
{"world_size", "default"},
{"season_start", "autumn"},
{"mycustomsetting", "enabled"}
}
})
Scenario 4: Custom Components and Behaviors
-- scripts/components/mycustomcomponent.lua
local MyCustomComponent = Class(function(self, inst)
self.inst = inst
self.value = 0
self.max_value = 100
end)
function MyCustomComponent:SetValue(value)
self.value = math.max(0, math.min(value, self.max_value))
self.inst:PushEvent("valuechanged", {value = self.value})
end
function MyCustomComponent:OnSave()
return {value = self.value}
end
function MyCustomComponent:OnLoad(data)
if data and data.value then
self.value = data.value
end
end
return MyCustomComponent
-- Using the component in modmain.lua
AddComponentPostInit("inventoryitem", function(self)
-- Add custom functionality to all inventory items
if self.inst.prefab == "myspecialitem" then
self.inst:AddComponent("mycustomcomponent")
end
end)
Steam Workshop Integration
Preparing Your Mod for Workshop
Mod Validation Checklist
- modinfo.lua complete: All required fields filled correctly
- Assets optimized: Images compressed, animations efficient
- Code tested: No error messages in console
- Compatibility verified: Works with base game and common mods
- Description written: Clear explanation of mod features
Workshop Upload Process
-
In-Game Upload:
Main Menu → Workshop → Upload Mod → Select your mod folder
-
Steam Workshop Page:
- Add detailed description
- Include screenshots/videos
- Set appropriate tags
- Choose visibility settings
Workshop Best Practices
Naming Conventions
-- Clear, descriptive mod names
name = "Enhanced Farming Tools" -- Good
name = "AwesomeMod123" -- Avoid
-- Consistent prefab naming
"enhanced_hoe" -- Mod-specific prefix
"enhanced_watering_can"
"enhanced_fertilizer"
Debugging and Troubleshooting
Essential Debugging Tools
Console Commands for Mod Development
-- Basic mod debugging commands
c_give("myitem", 1) -- Give item to player
c_spawn("myitem", 10) -- Spawn items at cursor
c_find("myitem") -- Find all instances in world
c_sel() -- Select entity under mouse
c_reset() -- Reset selected entity
-- Advanced debugging
c_findnext("myitem") -- Find next instance
c_gonext("myitem") -- Teleport to next instance
c_regenerateworld() -- Regenerate world with mods
c_dumptable(inst.components) -- Dump component data
Mod-Specific Debug Functions
-- Error handling and debug output
modprint("Debug message:", variable) -- Debug-only print
moderror("Error occurred!") -- Mod error reporting
modassert(condition, "Must be true") -- Mod assertion
-- Configuration debugging
local config = GetModConfigData("setting_name")
print("Config value:", config)
-- Component inspection
local function DebugEntity(inst)
print("Entity:", inst.prefab)
print("Valid:", inst:IsValid())
print("Components:", table.concat(inst.components, ", "))
if inst.components.health then
print("Health:", inst.components.health.currenthealth)
end
end
Common Issues and Solutions
Issue 1: Mod Not Loading
Symptoms: Mod doesn't appear in mod list, no debug output
Solutions:
- Fix modinfo.lua syntax - ensure all required fields are present
- Check file permissions - ensure mod files are readable
- Verify directory structure - follow exact naming conventions
- Review console errors - look for Lua syntax errors
Issue 2: Items Not Working
Symptoms: c_give() fails, items have no functionality, recipes don't work
Solutions:
- Verify prefab files are in PrefabFiles list
- Check component setup - validate all required components
- Test recipe ingredients - ensure all exist and are available
- Review asset paths - verify all references are correct
Issue 3: Multiplayer Problems
Symptoms: Works in single-player but not multiplayer
Solutions:
- Proper network setup - use inst.entity:SetPristine() correctly
- Server-client separation - check TheWorld.ismastersim appropriately
- RPC implementation - use proper mod RPC handlers for custom data
Performance Optimization
Efficient Entity Management
-- Pool pattern for frequently spawned/removed entities
local entity_pool = {}
local function GetPooledEntity(prefab)
if entity_pool[prefab] and #entity_pool[prefab] > 0 then
return table.remove(entity_pool[prefab])
else
return SpawnPrefab(prefab)
end
end
Memory-Efficient Data Structures
-- Use weak references for temporary data
local temporary_data = setmetatable({}, {__mode = "k"})
-- Efficient caching with limits
local cache = {}
local cache_limit = 100
local function CacheData(key, data)
if #cache >= cache_limit then
table.remove(cache, 1)
end
cache[key] = data
end
Next Steps
Now that you understand the basics, you can explore:
- Core Systems: Learn about the fundamental systems that power DST
- Mod Support: Advanced mod infrastructure and tools
- Components: Study the component system for adding behaviors to entities
- Game Mechanics: Understand how key game systems function
Resources and Community
- Klei Forums: Official forums for DST modding
- DST Modding Wiki: Community-maintained wiki with modding resources
- Steam Workshop: Browse existing mods for inspiration
API Documentation Structure
This documentation is organized by system and functionality:
- Getting Started: Introduction, setup guides, and comprehensive tutorials
- Core Systems: Fundamental game systems including mod support infrastructure
- Components: Entity components and their functionality
- Game Mechanics: Key gameplay systems like health, hunger, and sanity
- World Management: World generation, seasons, and environment
Use the sidebar navigation to explore the different sections of the API documentation.