Generator Module Documentation
Overview
The generator/ subfolder contains the core idle game mechanics: automated resource production with scaling costs, upgrades (buffs), and manual interaction.
Files
| File | Purpose |
|---|---|
currency_generator.gd |
Runtime generator logic (Node2D) |
currency_generator_data.gd |
Balancing data resource |
generator_buff_data.gd |
Buff/upgrade definitions |
generator_container.gd |
UI panel for generator stats |
Architecture
CurrencyGenerator (Node2D)
├── Handles production cycles
├── Manages purchases
├── Processes clicks/hover
└── GeneratorPanel (UI)
├── Shows stats/costs
└── Buff upgrade buttons
CurrencyGeneratorData
Resource class for generator balancing data.
Key Properties
@export var id: StringName = &"" # Unique identifier
@export var name: String = "" # Display name
@export var starts_unlocked: bool = true # Visible at game start
@export var purchase_currency: Currency # What to spend
@export var unlock_goal: GoalData # Goal to unlock this (behavior defined in GoalData)
# Cost formula: cost = base * coefficient^owned
@export var initial_cost: float = 10.0 # Base cost
@export var coefficient: float = 1.15 # Growth factor
# Production
@export var initial_time: float = 1.0 # Seconds per cycle
@export var initial_productivity: float = 1.0 # Resources per cycle
# Milestones
@export var milestone_step: int = 25 # Every N units
@export var milestone_multiplier: float = 2.0 # x multiplier
# Manual click
@export var click_mantissa: float = 1.0
@export var click_exponent: int = 0
@export var click_cooldown_seconds: float = 0.2
Cost Formula
Bulk Buy Cost (geometric series):
total_cost = base * r^owned * ((r^n - 1) / (r - 1))
Where:
base= initial_costr= coefficientowned= current countn= amount to buy
Max Buy (inverse formula):
max = floor(log((currency * (r-1) / (base * r^owned)) + 1) / log(r))
Production Formula
production_per_cycle = initial_productivity * owned * run_multiplier * milestone_mult * purchased_mult
production_per_second = production_per_cycle / initial_time
CurrencyGenerator
Runtime node instance attached to generator scenes.
Signals
signal purchase_completed(amount, total_owned, total_purchased, total_cost)
signal production_tick(amount, cycle_count, total_owned)
signal buff_purchased(buff_id, new_level, cost, cost_currency_id)
signal goal_achieved(generator_id, goal_id) # Emitted when generator unlocks from goal
Key Methods
# Purchase
func buy(amount: int = 1) -> bool
func buy_max() -> int
func get_cost_for_amount(amount: int) -> BigNumber
func can_buy(amount: int) -> bool
# Goal-based unlock (automatic when goal completes)
# Generator listens to GameState.goal_completed signal
Production
func grant_currency(amount: BigNumber) func get_effective_auto_run_multiplier() -> float
Buffs
func buy_buff(buff_id: StringName) -> bool func get_buff_level(buff_id: StringName) -> int func is_buff_unlocked(buff_id: StringName) -> bool
### Production Cycle
1. Accumulate `cycle_progress_seconds` in `_process()`
2. When `>= initial_time`, grant production
3. Emit `production_tick` signal
4. Multiply by:
- Owned count
- Run multiplier (export)
- Buff multipliers (auto_production)
- Milestone bonuses
- Purchase boost
## GeneratorBuffData
Defines upgradeable modifiers for generators.
### Buff Kinds
```gdscript
enum BuffKind {
AUTO_PRODUCTION_MULTIPLIER, # x output per cycle
MANUAL_CLICK_MULTIPLIER, # x click reward
RESOURCE_PURCHASE # Instant currency grant
}
Key Properties
@export var id: StringName = &""
@export var target_ids: Array[StringName] = [] # Generators affected
@export var kind: BuffKind
@export var max_level: int = -1 # -1 = unlimited
@export var base_effect: float = 1.0 # Starting multiplier
@export var effect_increment: float = 0.1 # +per level
@export var base_cost_mantissa: float = 10.0
@export var base_cost_exponent: int = 0
@export var cost_multiplier: float = 1.5 # Cost growth
# Effect: base_effect + (effect_increment * level)
func get_effect_multiplier(level: int) -> float
Cost Formula
cost_for_level = base_cost * cost_multiplier^level
Resource Purchase Buff
Special buff type that grants instant currency:
resource_purchase_amount = base_amount * (resource_purchase_increment_multiplier^level)
GeneratorPanel
UI component showing generator information.
Displays
- Generator name and owned count
- Next purchase cost
- Production per second
- Buff upgrade buttons with costs
Signals Connected
purchase_completed- Refresh UIproduction_tick- Update production displaygenerator_buff_level_changed- Refresh buff rows
Goal-Based Unlock
Generators with unlock_goal automatically listen to GameState.goal_completed signal:
- When goal completes, generator unlocks automatically
- Goal's
unlock_behavior(AUTOMATIC/MANUAL) controls when goal completes - Manual goals require player to click "Unlock" button first
# In CurrencyGenerator._ready():
GameState.goal_completed.connect(_on_goal_completed)
func _on_goal_completed(goal_id: StringName) -> void:
if data.has_unlock_goal() and data.get_unlock_goal_id() == goal_id:
unlock_generator()
Prestige Integration
Generators automatically apply prestige multipliers:
effective_multiplier = run_multiplier * buff_multiplier * prestige_multiplier
On prestige:
reset_runtime_state_for_prestige()calledcycle_progress_secondsreset- Buff levels reset to 0
- Unlocks re-evaluated from goals
See Also
core/game_state.gd- Generator state storagegoals/goal_data.gd- Unlock conditionsprestige/prestige_manager.gd- Multiplier application