Skip to main content

Tuning

Version History

Build VersionChange DateChange TypeDescription
6760422025-06-21stableCurrent version

Overview

The Tuning system provides the central game balance and configuration mechanism for Don't Starve Together. It consists of a global TUNING table containing hundreds of numeric values that control almost every aspect of gameplay, including damage values, tool durability, character stats, time settings, and world generation parameters. The system enables consistent game balance and facilitates easy adjustments without modifying core game logic.

Usage Example

-- Access tuning values for gameplay mechanics
local player_health = TUNING.WILSON_HEALTH -- 150
local spear_damage = TUNING.SPEAR_DAMAGE -- 34
local day_length = TUNING.TOTAL_DAY_TIME -- 480 seconds

-- Use tuning values in component setup
inst.components.health:SetMaxHealth(TUNING.WILSON_HEALTH)
inst.components.weapon:SetDamage(TUNING.SPEAR_DAMAGE)

Global Tables

TUNING

Type: table

Status: stable

Description: The main global table containing all game balance values. Populated by the Tune() function during game initialization.

Structure:

TUNING = {
-- Time constants
SEG_TIME = 30,
TOTAL_DAY_TIME = 480,

-- Character stats
WILSON_HEALTH = 150,
WILSON_HUNGER = 150,
WILSON_SANITY = 200,

-- Tool durability and damage
SPEAR_DAMAGE = 34,
SPEAR_USES = 150,

-- And hundreds more values...
}

TUNING_MODIFIERS

Type: table

Status: stable

Description: Table storing modifier functions for tuning values that can be dynamically calculated. Used by the AddTuningModifier() function.

ORIGINAL_TUNING

Type: table

Status: stable

Description: Backup table storing original tuning values before modifications are applied. Used for restoration purposes.

Core Functions

Tune(overrides)

Status: stable

Description: Main function that populates the TUNING table with all game balance values. Called during game initialization with optional override parameters.

Parameters:

  • overrides (table, optional): Table of override values to modify default tuning

Example:

-- Called internally during game startup
Tune() -- Uses default values

-- Called with overrides
Tune({
wilson_health = 200, -- Override Wilson's health
day_time = 300 -- Override day length
})

AddTuningModifier(tuning_var, fn, tuning_value)

Status: stable

Description: Safely modifies tuning values using a transformation function. Stores the original value and applies the modifier function when the value is accessed.

Parameters:

  • tuning_var (string): Name of the TUNING variable to modify (e.g., "WILSON_HEALTH")
  • fn (function): Function that transforms the value
  • tuning_value (number): Default value if the tuning variable doesn't exist

Example:

-- Increase Wilson's health by 20%
AddTuningModifier("WILSON_HEALTH", function(health)
return health * 1.2
end, 150)

-- Add difficulty scaling to damage
AddTuningModifier("SPEAR_DAMAGE", function(damage)
return damage * GetDifficultyMultiplier()
end, 34)

Time Constants

Time values form the foundation of many game mechanics:

Core Time Values

ConstantValueDescription
SEG_TIME30Duration of one day segment in seconds
TOTAL_DAY_TIME480Total day length (16 segments)
DAY_SEGS_DEFAULT10Number of daytime segments
DUSK_SEGS_DEFAULT4Number of dusk segments
NIGHT_SEGS_DEFAULT2Number of night segments

Example:

-- Calculate time periods
local day_duration = TUNING.SEG_TIME * TUNING.DAY_SEGS_DEFAULT -- 300 seconds
local dusk_duration = TUNING.SEG_TIME * TUNING.DUSK_SEGS_DEFAULT -- 120 seconds
local night_duration = TUNING.SEG_TIME * TUNING.NIGHT_SEGS_DEFAULT -- 60 seconds

Character Statistics

Base Character Values

ConstantValueDescription
WILSON_HEALTH150Base character health
WILSON_HUNGER150Base hunger capacity
WILSON_SANITY200Base sanity maximum
WILSON_HUNGER_RATE0.15625Hunger drain per second (75/480)
WILSON_ATTACK_PERIOD0.4Time between attacks

Example:

-- Set up character components
function SetupCharacterStats(inst)
inst.components.health:SetMaxHealth(TUNING.WILSON_HEALTH)
inst.components.hunger:SetMax(TUNING.WILSON_HUNGER)
inst.components.sanity:SetMax(TUNING.WILSON_SANITY)
inst.components.hunger:SetRate(TUNING.WILSON_HUNGER_RATE)
end

Character-Specific Values

WX-78 Statistics:

TUNING.WX78_HEALTH = 125    -- Starting health (lower than Wilson)
TUNING.WX78_HUNGER = 125 -- Starting hunger
TUNING.WX78_SANITY = 150 -- Starting sanity
TUNING.WX78_MIN_HEALTH = 150 -- Minimum upgraded health
TUNING.WX78_MAX_HEALTH = 400 -- Maximum upgraded health

Combat System

Base Damage Values

ConstantValueDescription
BASE_SURVIVOR_ATTACK34Base player unarmed damage
UNARMED_DAMAGE10Damage when completely unarmed
DEFAULT_ATTACK_RANGE2Standard melee attack range
DEFAULT_HIT_RECOVERY0.75Recovery time after being hit

Weapon Damage

Melee Weapons:

TUNING.SPEAR_DAMAGE = 34              -- 1x base damage
TUNING.NIGHTSWORD_DAMAGE = 68 -- 2x base damage
TUNING.HAMBAT_DAMAGE = 59.5 -- 1.75x base damage
TUNING.BATBAT_DAMAGE = 42.5 -- 1.25x base damage
TUNING.SPIKE_DAMAGE = 51 -- 1.5x base damage
TUNING.RUINS_BAT_DAMAGE = 59.5 -- 1.75x base damage

Tool Damage:

TUNING.AXE_DAMAGE = 27.2              -- 0.8x base damage
TUNING.PICKAXE_DAMAGE = 27.2 -- 0.8x base damage
TUNING.HAMMER_DAMAGE = 17 -- 0.5x base damage
TUNING.TORCH_DAMAGE = 17 -- 0.5x base damage

Weapon Durability

Melee Weapons:

TUNING.SPEAR_USES = 150
TUNING.NIGHTSWORD_USES = 100
TUNING.HAMBAT_USES = 100
TUNING.BATBAT_USES = 75
TUNING.RUINS_BAT_USES = 200

Tools:

TUNING.AXE_USES = 100
TUNING.PICKAXE_USES = 33
TUNING.HAMMER_USES = 75
TUNING.SHOVEL_USES = 25
TUNING.PITCHFORK_USES = 25

Item Stack Sizes

Different item categories have different maximum stack sizes:

ConstantValueCategoryExamples
STACK_SIZE_LARGEITEM10Large itemsLogs, rocks, gold
STACK_SIZE_MEDITEM20Medium itemsGrass, twigs, flint
STACK_SIZE_SMALLITEM40Small itemsBerries, seeds, petals
STACK_SIZE_TINYITEM60Tiny itemsButterfly wings, flower petals
STACK_SIZE_PELLET120Pellet itemsGunpowder pellets

Example:

-- Set appropriate stack size for an item
function SetItemStackSize(inst, category)
local stack_size = TUNING["STACK_SIZE_" .. string.upper(category)]
inst.components.stackable:SetStackSize(stack_size)
end

Food and Healing Values

Hunger (Calories) Values

ConstantValueDescription
CALORIES_TINY9.375Tiny food value
CALORIES_SMALL12.5Small food value
CALORIES_MEDSMALL18.75Medium-small food value
CALORIES_MED25Medium food value
CALORIES_LARGE37.5Large food value
CALORIES_HUGE75Huge food value
CALORIES_SUPERHUGE150Super huge food value

Health Values

ConstantValueDescription
HEALING_TINY1Tiny healing amount
HEALING_SMALL3Small healing amount
HEALING_MEDSMALL8Medium-small healing
HEALING_MED20Medium healing amount
HEALING_MEDLARGE30Medium-large healing
HEALING_LARGE40Large healing amount
HEALING_HUGE60Huge healing amount
HEALING_SUPERHUGE100Super huge healing

Sanity Values

ConstantValueDescription
SANITY_SUPERTINY1Super tiny sanity change
SANITY_TINY5Tiny sanity change
SANITY_SMALL10Small sanity change
SANITY_MED15Medium sanity change
SANITY_MEDLARGE20Medium-large sanity change
SANITY_LARGE33Large sanity change
SANITY_HUGE50Huge sanity change

Example:

-- Set food component values
function SetFoodValues(inst, hunger_size, health_size, sanity_size)
local hunger_val = TUNING["CALORIES_" .. string.upper(hunger_size)]
local health_val = TUNING["HEALING_" .. string.upper(health_size)]
local sanity_val = TUNING["SANITY_" .. string.upper(sanity_size)]

inst.components.edible.hungervalue = hunger_val
inst.components.edible.healthvalue = health_val
inst.components.edible.sanityvalue = sanity_val
end

Multiplayer Balance Modifiers

The tuning system includes special modifiers for multiplayer balance:

ConstantValueDescription
MULTIPLAYER_ATTACK_MODIFIER1Player damage modifier in multiplayer
MULTIPLAYER_GOLDENTOOL_MODIFIER1Golden tool efficiency modifier
MULTIPLAYER_ARMOR_DURABILITY_MODIFIER0.7Armor durability modifier (reduced)
MULTIPLAYER_ARMOR_ABSORPTION_MODIFIER1Armor absorption modifier
MULTIPLAYER_WILDLIFE_RESPAWN_MODIFIER1Wildlife respawn rate modifier

Example:

-- Apply multiplayer balance in damage calculations
function CalculatePlayerDamage(base_damage)
return base_damage * TUNING.MULTIPLAYER_ATTACK_MODIFIER
end

-- Apply multiplayer balance to armor durability
function SetArmorDurability(inst, base_uses)
local multiplayer_uses = base_uses * TUNING.MULTIPLAYER_ARMOR_DURABILITY_MODIFIER
inst.components.armor:SetMaxUses(multiplayer_uses)
end

Ocean and Fishing System

The tuning system includes extensive values for ocean fishing mechanics:

Ocean Fishing Constants

TUNING.OCEAN_FISHING = {
MAX_CAST_DIST = 16, -- Maximum fishing cast distance
REEL_STRENGTH_MIN = 2, -- Minimum reel strength
REEL_STRENGTH_MAX = 3, -- Maximum reel strength
LINE_TENSION_HIGH = 0.80, -- High tension threshold
LINE_TENSION_GOOD = 0.10, -- Good tension threshold
FISHING_CATCH_DIST = 2.5, -- Distance to catch fish
}

Tackle and Lure Systems

Bobber Accuracy Modifiers:

TUNING.OCEANFISHING_TACKLE = {
BASE = {
dist_max = 5,
dist_min_accuracy = 0.70,
dist_max_accuracy = 1.30,
max_angle_offset = 40
},
BOBBER_TWIG = {
dist_max = 2,
dist_min_accuracy = 0.10,
max_angle_offset = -10
}
}

Common Usage Patterns

Using Tuning Values in Components

-- Weapon component setup
function SetupWeapon(inst, weapon_type)
local damage_key = string.upper(weapon_type) .. "_DAMAGE"
local uses_key = string.upper(weapon_type) .. "_USES"

inst.components.weapon:SetDamage(TUNING[damage_key] or TUNING.BASE_SURVIVOR_ATTACK)
inst.components.finiteuses:SetMaxUses(TUNING[uses_key] or 100)
end

-- Character stat scaling
function ScaleCharacterStats(inst, scale_factor)
local base_health = TUNING.WILSON_HEALTH
local base_hunger = TUNING.WILSON_HUNGER
local base_sanity = TUNING.WILSON_SANITY

inst.components.health:SetMaxHealth(base_health * scale_factor)
inst.components.hunger:SetMax(base_hunger * scale_factor)
inst.components.sanity:SetMax(base_sanity * scale_factor)
end

Modifying Tuning Values

-- Simple value modification
TUNING.WILSON_HEALTH = 200 -- Direct assignment

-- Safe modification with AddTuningModifier
AddTuningModifier("SPEAR_DAMAGE", function(damage)
return damage * 1.5 -- 50% damage increase
end, TUNING.SPEAR_DAMAGE)

-- Conditional modification
if GetGameMode() == "easy" then
TUNING.WILSON_HEALTH = TUNING.WILSON_HEALTH * 1.5
TUNING.WILSON_HUNGER_RATE = TUNING.WILSON_HUNGER_RATE * 0.75
end

Creating Custom Tuning Categories

-- Add custom tuning values for mods
TUNING.CUSTOM_WEAPON_DAMAGE = TUNING.BASE_SURVIVOR_ATTACK * 1.3
TUNING.CUSTOM_TOOL_USES = 200
TUNING.CUSTOM_FOOD_VALUE = TUNING.CALORIES_LARGE * 1.2

-- Function to batch-set custom values
function AddCustomTuning(custom_values)
for key, value in pairs(custom_values) do
TUNING["CUSTOM_" .. string.upper(key)] = value
end
end

Integration Notes

Relationship to Other Systems

The tuning system integrates with virtually all game systems:

  • Component System: Components use tuning values for initialization
  • Recipe System: Crafting costs and requirements reference tuning values
  • World Generation: Spawn rates and world parameters use tuning constants
  • Character System: Character-specific abilities and stats are tuned
  • Combat System: All damage and defense calculations use tuning values

Performance Considerations

  • Tuning values are resolved at startup, not runtime
  • Direct table access (TUNING.VALUE) is very fast (O(1) lookup)
  • Modifier functions add slight overhead but provide flexibility
  • Consider caching frequently accessed tuning calculations

Mod Compatibility

The tuning system is designed for mod compatibility:

  • Mods can safely override any tuning value
  • AddTuningModifier() provides safer modification for complex logic
  • Original values are preserved in ORIGINAL_TUNING table
  • Multiple mods can modify the same values if done carefully

Source Reference

File Location: scripts/tuning.lua

Global Access: Available globally as TUNING table

Key Functions:

  • Tune(overrides): Main initialization function
  • AddTuningModifier(tuning_var, fn, tuning_value): Safe modification utility

Dependencies:

  • techtree.lua: Technology tree definitions