| name | godot-game-loop-harvest |
| description | Data-driven resource harvesting (mining, logging, foraging) for Godot 4: apply_hit tool/tier validation via HarvestToolData enums, HarvestResourceData yields, harvestable_node shake/deplete, respawn_manager world persistence, UNIX offline progress, autosave, and noise vein proc-gen. Trigger keywords: apply_hit, HarvestResourceData, HarvestToolData, offline UNIX, respawn_manager, tool tier, harvestable_node, FastNoiseLite veins. |
Script Catalog (MANDATORY by path)
Setup (short)
- Author
HarvestResourceData / HarvestToolData .tres (tool enum + tier, yield range, optional drop scene).
- Attach
harvestable_node.gd to StaticBody3D; assign data + mesh_to_shake; keep interaction on Layer 1.
- Autoload
harvest_respawn_manager.gd as HarvestRespawnManager when world persistence is required.
Hit path
Raycast/interact → apply_hit(tool_data: HarvestToolData):
if collider is HarvestableNode:
collider.apply_hit(player_tool)
| Signal | Payload | Wire to |
|---|
harvested | (data, amount) | Inventory / harvest_inventory_manager |
took_damage | (curr, max) | HUD bar / popup pool |
interaction_failed | (reason: StringName) | "wrong_tool" / "low_tier" feedback |
NEVER Do
- NEVER use float for accumulated harvest counts — use
int.
- NEVER gather rates in
_process without delta — framerate-scales economy.
- NEVER trust
OS.get_ticks_msec() for offline progress — use Time.get_unix_time_from_system().
- NEVER check tool type via free-form strings — use
HarvestToolData.ToolType / StringName enums (see scripts).
- NEVER mutate shared Resource templates —
duplicate(true) before runtime durability/health mutation.
- NEVER
queue_free() before VFX/SFX finish — hide mesh, swap collision layer, free after juice.
- NEVER skip saving UNIX timestamp on exit — offline gains depend on it.
- NEVER couple harvest logic to UI counters — signals only.
- NEVER scale collision shapes non-uniformly — edit shape resource sizes.
Vein proc-gen (noise)
Use FastNoiseLite thresholds for organic clusters; spawn HarvestableNode instances where noise.get_noise_2dv(pos) > threshold. Persist depleted IDs via respawn manager — do not re-roll veins every load without a seed.
Tool durability
Keep durability on HarvestToolData (Resource), not the player node. Emit durability/break signals from the tool Resource after successful hits.
MANDATORY for offline UNIX math, worker-thread batching, popup pools, and vein proc-gen depth: harvest-elite-patterns.md. Do NOT Load when hit path + respawn manager suffice.
Reference
Progressive disclosure: Skim Official Documentation only for the APIs you are implementing (Resources, StaticBody3D hits, signals, timers, save/offline time). Open Related Skills when wiring inventory, autoloads, raycasts, or economy balance—do not preload the whole lattice.
Official Documentation
- Resources — Author
HarvestResourceData / HarvestToolData as shareable .tres assets so designers tune health, yield ranges, and tool gates without editing harvest scripts.
- Resource — Call
duplicate(true) before mutating runtime harvest/tool state so one node’s depletion or durability cannot rewrite the shared template Resource.
- GDScript exports —
@export / @export_group power Inspector-authored tool tiers, yield ranges, respawn times, and drop scenes on harvest data Resources.
- Using signals — Emit
harvested, took_damage, and interaction_failed so inventory, HUD bars, and feedback UI subscribe without coupling to HarvestableNode internals.
- StaticBody3D — World harvestables are static colliders players query/hit; keep them on an interaction layer and move to an inactive layer while depleted.
- Collision shapes (3D) — Size shape resources directly; non-uniform scale on collision shapes breaks hit tests for pickaxes/axes against trees and ore nodes.
- Idle and Physics Processing — Multiply continuous gather rates by
delta (prefer _physics_process for fixed-step economy ticks) so harvest speed is not framerate-dependent.
- Time — Persist
Time.get_unix_time_from_system() for offline gains; do not use OS.get_ticks_msec() / uptime for real-world absence math.
- Saving games — Persist inventory counts, depleted-node IDs, and absolute respawn/offline timestamps with the rest of progression data.
- FileAccess — Interval autosave writes JSON (or binary) under
user:// via FileAccess.open so harvest progress survives crashes between manual saves.
Related Skills
Prerequisites
- godot-resource-data-patterns — Harvest yields, tool stats, and drop scenes are Resource-first; establish composition/duplicate rules before baking economy numbers into nodes.
- godot-signal-architecture —
harvested / inventory_updated ownership and safe connects keep gather nodes decoupled from HUD and inventory hubs.
- godot-physics-3d —
StaticBody3D layers/masks and shape setup for interactable world props are prerequisites to reliable hit validation.
- godot-gdscript-mastery — Typed Resources,
await on create_timer, and Mutex/WorkerThreadPool patterns assume solid GDScript fundamentals.
Complements
- godot-inventory-system — Connect
harvested into a real inventory/stacking pipeline instead of leaving counts in a harvest-only dictionary.
- godot-save-load-systems — Round-trip warehouse totals, tool durability, and depleted-node timers through the project save schema beyond interval JSON dumps.
- godot-autoload-architecture — Respawn and inventory managers belong in a disciplined Autoload graph with clear init order and signal-bus boundaries.
- godot-raycasting-queries — Player gather input typically raycasts or shapecasts to the harvestable collider before calling
apply_hit(tool_data).
- godot-tweening — Expand hit shakes into polish tweens (squash, flash, camera punch) without cutting VFX short via early
queue_free().
- godot-economy-system — Wire harvest yields into sinks, crafting costs, and vendor loops so gathering feeds a coherent economy.
Downstream / consumers
- godot-monte-carlo-balancer — After yields, respawn times, and tool tiers are tunable Resources, Monte Carlo sims validate gather pacing and sink pressure before shipping curves.
- godot-genre-survival — Survival loops compose harvesting with hunger, crafting, and world threat systems on top of this gather core.
- godot-game-loop-collection — Collection/scavenger objectives often consume the same harvest/inventory signals for “gather N of X” quests.
- godot-procedural-generation — Noise-driven resource veins and world placement build on harvest node data once the interaction loop is solid.
Master
- godot-master — Library router and mirrored module entry; use when discovering peer skills or syncing shared script mirrors after Domain Skill edits.