Recipe System Core
Version History
| Build Version | Change Date | Change Type | Description |
|---|---|---|---|
| 676042 | 2025-06-21 | stable | Current version |
Overview
The recipe module provides the core infrastructure for Don't Starve Together's crafting system. It defines the Recipe and Ingredient classes that specify how items can be crafted, what components are required, and under what conditions crafting is allowed.
This module handles recipe registration, ingredient validation, tech requirements, and provides integration points for character-specific crafting restrictions and custom placement logic.
Global Variables
AllRecipes
Type: table
Status: stable
Description: Global registry of all recipes keyed by recipe name.
AllBuilderTaggedRecipes
Type: table
Status: stable
Description: Registry of recipes restricted to specific characters, keyed by recipe name with builder tag or skill as value.
mod_protect_Recipe
Type: boolean
Status: stable
Description: Flag to warn about deprecated direct Recipe usage in mods.
Ingredient Class
Ingredient(ingredienttype, amount, atlas, deconstruct, imageoverride)
Status: stable
Description: Creates a new ingredient specification for recipes.
Parameters:
ingredienttype(string): Type of ingredient (prefab name, CHARACTER_INGREDIENT, or TECH_INGREDIENT)amount(number): Quantity requiredatlas(string, optional): Custom atlas path for ingredient imagedeconstruct(boolean, optional): Whether ingredient is returned on deconstructionimageoverride(string, optional): Custom image filename override
Validation:
- Character ingredients (health/sanity) must be multiples of
CHARACTER_INGREDIENT_SEG(5) - Uses string-based precision checking to avoid floating-point errors
Example:
-- Regular item ingredient
local twig_ingredient = Ingredient("twigs", 2)
-- Character cost ingredient
local health_cost = Ingredient(CHARACTER_INGREDIENT.HEALTH, 20)
-- Tech ingredient
local science_req = Ingredient(TECH_INGREDIENT.SCIENCE, 1)
-- Custom atlas ingredient
local custom_ingredient = Ingredient("myitem", 1, "images/myatlas.xml", true, "myimage.tex")
Instance Properties
type(string): The ingredient typeamount(number): Required quantityatlas(string): Atlas path for imageimage(string): Image filenamedeconstruct(boolean): Returned on deconstruction
Ingredient:GetAtlas()
Status: stable
Description: Retrieves the atlas path for the ingredient's image, resolving it if not already set.
Returns:
- (string): Resolved atlas path
Example:
local ingredient = Ingredient("twigs", 2)
local atlas = ingredient:GetAtlas()
-- Returns resolved path to twigs atlas
Ingredient:GetImage()
Status: stable
Description: Gets the image filename for the ingredient, generating default if not specified.
Returns:
- (string): Image filename with .tex extension
Example:
local ingredient = Ingredient("rocks", 3)
local image = ingredient:GetImage()
-- Returns: "rocks.tex"
Helper Functions
IsCharacterIngredient(ingredienttype)
Status: stable
Description: Checks if an ingredient type is a character resource (health, sanity, etc.).
Parameters:
ingredienttype(string): Ingredient type to check
Returns:
- (boolean): True if ingredient is a character resource
Example:
local is_char = IsCharacterIngredient(CHARACTER_INGREDIENT.HEALTH)
-- Returns: true
local is_item = IsCharacterIngredient("twigs")
-- Returns: false
IsTechIngredient(ingredienttype)
Status: stable
Description: Checks if an ingredient type is a tech resource (science points, etc.).
Parameters:
ingredienttype(string): Ingredient type to check
Returns:
- (boolean): True if ingredient is a tech resource
Example:
local is_tech = IsTechIngredient(TECH_INGREDIENT.SCIENCE)
-- Returns: true
Recipe Class
Recipe(name, ingredients, tab, level, placer_or_more_data, ...)
Status: deprecated for mods
Description:
Legacy Recipe constructor. Mods should use AddRecipe() instead.
Note: Direct Recipe usage from mods triggers deprecation warning when mod_protect_Recipe is true.
Recipe2(name, ingredients, tech, config)
Status: stable
Description: Modern Recipe constructor with cleaner parameter structure.
Parameters:
name(string): Recipe identifier and default product nameingredients(table): Array of Ingredient objectstech(table): Tech requirements using TECH constantsconfig(table, optional): Additional configuration options
Config Options:
product(string): Override output prefab namenumtogive(number): Quantity produced (default: 1)builder_tag(string): Required character tagbuilder_skill(string): Required skill tree unlockplacer(string): Placer prefab for structuresmin_spacing(number): Minimum spacing for structures (default: 3.2)testfn(function): Custom placement validationcanbuild(function): Custom crafting permission checkatlas(string): Custom image atlasimage(string): Custom image filenounlock(boolean): Don't show in crafting menumanufactured(boolean): Station handles item creationstation_tag(string): Required crafting station taglimitedamount(boolean): Can only be crafted onceactionstr(string): Custom action textsg_state(string): Custom state graph state for craftingno_deconstruction(boolean/function): Disable deconstructionrequire_special_event(string): Require active special event
Example:
Recipe2("campfire",
{
Ingredient("log", 2),
Ingredient("cutgrass", 3)
},
TECH.NONE,
{
placer = "campfire_placer",
min_spacing = 2.0,
atlas = "images/inventoryimages.xml",
image = "campfire.tex"
}
)
Recipe Instance Properties
Core Properties:
name(string): Recipe identifierproduct(string): Output prefab nameingredients(table): Regular item ingredientscharacter_ingredients(table): Character resource coststech_ingredients(table): Tech requirementslevel(table): Tech tree requirementsnumtogive(number): Output quantity
Builder Restrictions:
builder_tag(string): Required character tagbuilder_skill(string): Required skill unlockno_builder_tag(string): Excluded character tagno_builder_skill(string): Excluded skill
UI Properties:
atlas(string): Image atlas pathimage(string): Image filenameimagefn(function): Dynamic image functionnameoverride(string): Display name overridedescription(string): Description overrideactionstr(string): Custom action text
Placement Properties:
placer(string): Placer prefabmin_spacing(number): Minimum structure spacingtestfn(function): Custom placement testbuild_mode(number): Placement mode (BUILDMODE constants)build_distance(number): Maximum build distance
Special Properties:
manufactured(boolean): Station-crafted itemstation_tag(string): Required station taglimitedamount(boolean): One-time craftablenounlock(boolean): Hidden from menuis_deconstruction_recipe(boolean): Deconstruction recipe flagrequire_special_event(string): Event requirement
Recipe:GetAtlas()
Status: stable
Description: Gets the resolved atlas path for the recipe's display image.
Returns:
- (string): Atlas path
Recipe:SetModRPCID()
Status: stable
Description: Sets RPC ID for mod recipes using hash collision detection.
Note: Automatically called by mod system during recipe registration.
DeconstructRecipe Class
DeconstructRecipe(name, return_ingredients, config)
Status: stable
Description: Specialized recipe class for item deconstruction.
Parameters:
name(string): Recipe namereturn_ingredients(table): Items returned on deconstructionconfig(table, optional): Additional configuration
Properties:
is_deconstruction_recipe= truenounlock= true (hidden from crafting menu)level= TECH.NONE
Example:
DeconstructRecipe("axe_deconstruct",
{
Ingredient("twigs", 1),
Ingredient("flint", 1)
}
)
Global Functions
GetValidRecipe(recname)
Status: stable
Description: Retrieves a recipe if it's valid for the current game mode and conditions.
Parameters:
recname(string): Recipe name to validate
Returns:
- (Recipe|nil): Recipe object if valid, nil otherwise
Validation Checks:
- Game mode compatibility
- Not a deconstruction recipe
- Special event requirements (if any)
Example:
local campfire_recipe = GetValidRecipe("campfire")
if campfire_recipe then
print("Campfire can be crafted")
end
IsRecipeValid(recname)
Status: stable
Description: Checks if a recipe is valid without returning the recipe object.
Parameters:
recname(string): Recipe name to check
Returns:
- (boolean): True if recipe is valid
RemoveAllRecipes()
Status: stable
Description: Clears all recipe registries. Used for cleanup and testing.
Note: Resets AllRecipes, AllBuilderTaggedRecipes, and recipe counter.
Ingredient Types
Regular Ingredients
Standard items from player inventory:
Ingredient("twigs", 2)
Ingredient("rocks", 3)
Ingredient("goldnugget", 1)
Character Ingredients
Resources from character stats (defined in constants.lua):
Ingredient(CHARACTER_INGREDIENT.HEALTH, 20)
Ingredient(CHARACTER_INGREDIENT.SANITY, 15)
Ingredient(CHARACTER_INGREDIENT.MAX_HEALTH, 10)
Tech Ingredients
Technology requirements (defined in constants.lua):
Ingredient(TECH_INGREDIENT.SCIENCE, 1)
Ingredient(TECH_INGREDIENT.MAGIC, 2)
Ingredient(TECH_INGREDIENT.ANCIENT, 1)
Tech Tree Integration
Recipes integrate with the tech tree system through:
levelproperty defining tech requirements- Tech ingredients for prototype unlocking
- Station tags for crafting location restrictions
Common Tech Levels:
TECH.NONE -- No requirements
TECH.SCIENCE_ONE -- Science Machine
TECH.SCIENCE_TWO -- Alchemy Engine
TECH.MAGIC_TWO -- Prestihatitator
TECH.ANCIENT_TWO -- Ancient Pseudoscience Station
Mod Integration
Recipe Post-Initialization
Recipes support mod post-initialization hooks:
RecipePostInit: Called for specific recipesRecipePostInitAny: Called for all recipes
Best Practices for Mods
-- In modmain.lua - CORRECT
AddRecipe2("myitem",
{Ingredient("twigs", 2)},
TECH.NONE,
{atlas = "images/mymod.xml"}
)
-- Direct Recipe usage - DEPRECATED
Recipe2("myitem", ...) -- Triggers warning
Usage Examples
Basic Item Recipe
Recipe2("spear",
{
Ingredient("twigs", 2),
Ingredient("flint", 1),
Ingredient("rope", 1)
},
TECH.NONE,
{
atlas = "images/inventoryimages.xml",
image = "spear.tex"
}
)
Character-Specific Recipe
Recipe2("lighter",
{
Ingredient("twigs", 2),
Ingredient("flint", 1)
},
TECH.NONE,
{
builder_tag = "pyromaniac", -- Willow only
atlas = "images/inventoryimages.xml",
image = "lighter.tex"
}
)
Structure with Placement Logic
local function ValidMermPlacement(pt)
local tile = TheWorld.Map:GetTileAtPoint(pt.x, pt.y, pt.z)
return tile == WORLD_TILES.MARSH
end
Recipe2("mermhouse_crafted",
{
Ingredient("boards", 4),
Ingredient("cutreeds", 3),
Ingredient("pondfish", 2)
},
TECH.SCIENCE_ONE,
{
builder_tag = "merm_builder",
placer = "mermhouse_crafted_placer",
min_spacing = 5.0,
testfn = ValidMermPlacement
}
)
Related Modules
- Recipes: Complete recipe definitions
- Recipe Filters: Crafting menu categorization
- Tech Tree: Technology requirements
- Builder Component: Recipe crafting logic
- Constants: Ingredient and tech type definitions