Expert blueprint for survival games (Minecraft, Don't Starve, The Forest, Rust) covering needs systems, resource gathering, crafting recipes, base building, and progression balancing. Use when building open-world survival, crafting-focused, or resource management games. Keywords survival, needs system, crafting, inventory, hunger, resource gathering, base building.
Resource scarcity, needs management, and progression through crafting define survival games.
is_equal_approx() or <= to prevent 0.0 precision misses.MeshInstance3D nodes for foliage; strictly use MultiMeshInstance3D for batched draw calls.ResourceLoader.load_threaded_request() to prevent hitches.ConfigFile or JSON for easy balancing and modding.| Phase | Skills | Purpose |
|---|---|---|
| 1. Data | resources, custom-resources | Item data (weight, stack size), Recipes |
| 2. UI | grid-containers, drag-and-drop | Inventory management, crafting menu |
| 3. World | tilemaps, noise-generation | Procedural terrain, resource spawning |
| 4. Logic | state-machines, signals | Player stats (Needs), Interaction system |
| 5. Save | file-system, json-serialization | Saving world state, inventory, player stats |
Everything in the inventory is an Item.
# item_data.gd
extends Resource
class_name ItemData
@export var id: String
@export var name: String
@export var icon: Texture2D
@export var max_stack: int = 64
@export var weight: float = 1.0
@export var consumables: Dictionary # { "hunger": 10, "health": 5 }
A grid-based data structure.
# inventory.gd
extends Node
signal inventory_updated
var slots: Array[ItemSlot] = [] # Array of Resources or Dictionaries
@export var size: int = 20
func add_item(item: ItemData, amount: int) -> int:
# 1. Check for existing stacks
# 2. Add to empty slots
# 3. Return amount remaining (that couldn't fit)
pass
A universal way to harvest, pickup, or open things.
# interactable.gd
extends Area2D
class_name Interactable
@export var prompt: String = "Interact"
func interact(player: Player) -> void:
_on_interact(player)
func _on_interact(player: Player) -> void:
pass # Override this
Simple float values that deplete over time.
# needs_manager.gd
var hunger: float = 100.0
var thirst: float = 100.0
var decay_rate: float = 1.0
func _process(delta: float) -> void:
hunger -= decay_rate * delta
thirst -= decay_rate * 1.5 * delta
if hunger <= 0:
take_damage(delta)
Check if player has ingredients -> Remove ingredients -> Add result.
func craft(recipe: Recipe) -> bool:
if not has_ingredients(recipe.ingredients):
return false
remove_ingredients(recipe.ingredients)
inventory.add_item(recipe.result_item, recipe.result_amount)
return true
### 4. Tiered Tool Scaling
Scaling resource yield with tool quality (`item_data.gd` metadata):
- **Stone Axe**: 1 yield per hit, 3s harvest time.
- **Steel Axe**: 5 yield per hit, 1.5s harvest time.
- **Auto-Saw**: Constant yield stream while within proximity.
### 5. Spawn Safe Zones
Preventing "Spawn Camping" via check:
```gdscript
func get_spawn_point() -> Vector3:
var point = find_random_point()
for bed in get_tree().get_nodes_in_group("player_beds"):
if point.distance_to(bed.global_position) < safe_radius:
return get_spawn_point() # Re-roll
return point
## Godot-Specific Tips
* **TileMaps**: Use `TileMap` (Godot 3) or `TileMapLayer` (Godot 4) for the world.
* **FastNoiseLite**: Built-in noise generator for procedural terrain (trees, rocks, biomes).
* **ResourceSaver**: Save the `Inventory` resource directly to disk if it's set up correctly with `export` vars.
* **Y-Sort**: Essential for top-down 2D games so player sorts behind/in-front of trees correctly.
## Common Pitfalls
1. **Tedium**: Harvesting takes too long. **Fix**: Scale resource gathering with tool tier (Stone Axe = 1 wood, Steel Axe = 5 wood).
2. **Inventory Clutter**: Too many unique items that don't stack. **Fix**: Be generous with stack sizes and storage options.
3. **No Goals**: Player survives but gets bored. **Fix**: Add a tech tree or a "boss" to work towards.
## Reference
- Master Skill: [godot-master](../godot-master/SKILL.md)