Add docs
This commit is contained in:
167
core/goals/README.md
Normal file
167
core/goals/README.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# Goals Module Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The `goals/` subfolder contains the achievement system. Goals track player progress and can unlock generators or buffs when conditions are met.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `goal_data.gd` | Goal definition resource |
|
||||
| `goal_requirement_data.gd` | Individual requirement criteria |
|
||||
|
||||
## GoalData
|
||||
|
||||
Resource class defining an achievement.
|
||||
|
||||
### Properties
|
||||
|
||||
```gdscript
|
||||
class_name GoalData
|
||||
extends Resource
|
||||
|
||||
@export var id: StringName = &"" # Unique identifier
|
||||
@export var requirements: Array[GoalRequirementData] # Conditions to complete
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
```gdscript
|
||||
func is_valid() -> bool # Has id and valid requirements
|
||||
func is_met() -> bool # All requirements satisfied
|
||||
func get_progress() -> float # 0.0 to 1.0 based on closest requirement
|
||||
func get_first_requirement_summary() -> String # "100 Gold" format
|
||||
```
|
||||
|
||||
## GoalRequirementData
|
||||
|
||||
Single condition within a goal.
|
||||
|
||||
### Properties
|
||||
|
||||
```gdscript
|
||||
class_name GoalRequirementData
|
||||
extends Resource
|
||||
|
||||
@export var currency: Currency # Currency to track
|
||||
@export var amount_mantissa: float = 0.0 # Required amount (scientific notation)
|
||||
@export var amount_exponent: int = 0
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
```gdscript
|
||||
func get_amount() -> BigNumber # Required amount
|
||||
func is_met() -> bool # Current >= required
|
||||
func get_progress() -> float # Log-scaled 0.0-1.0
|
||||
func get_summary_text() -> String # "100 Gold" format
|
||||
```
|
||||
|
||||
### Progress Calculation
|
||||
|
||||
Uses **logarithmic scaling** for better visual feedback on huge numbers:
|
||||
|
||||
```gdscript
|
||||
# Convert to log space
|
||||
current_log = log(current_mantissa) / log(10) + current_exponent
|
||||
required_log = log(required_mantissa) / log(10) + required_exponent
|
||||
|
||||
# Progress ratio
|
||||
progress = clampf(current_log / required_log, 0.0, 1.0)
|
||||
```
|
||||
|
||||
This means reaching 50% progress on a 1e100 goal requires ~1e50 currency.
|
||||
|
||||
## Goal Evaluation
|
||||
|
||||
### Automatic Checking
|
||||
|
||||
`GameState` evaluates goals whenever currency changes:
|
||||
|
||||
```gdscript
|
||||
func _on_currency_changed(currency_id, new_amount):
|
||||
GameState.evaluate_all_goals()
|
||||
```
|
||||
|
||||
### Completion Flow
|
||||
|
||||
1. Currency updated → signal emitted
|
||||
2. `GameState.evaluate_all_goals()` called
|
||||
3. Each uncompleted goal checked via `is_met()`
|
||||
4. If met → `goal_completed` signal emitted
|
||||
5. Buffs with unlock goals checked → unlocked if goal complete
|
||||
|
||||
### Manual Unlock vs Automatic
|
||||
|
||||
Generators can be configured to:
|
||||
- **Automatic**: Unlock immediately when goal completes
|
||||
- **Manual**: Goal completion enables a button player must click
|
||||
|
||||
## Usage Example
|
||||
|
||||
### Defining a Goal
|
||||
|
||||
Create `res://sandbox/goals/first_million.tres`:
|
||||
|
||||
```
|
||||
[gd_resource type="Resource" script_class="GoalData"]
|
||||
[resource]
|
||||
id = &"first_million"
|
||||
requirements = [
|
||||
preload("res://sandbox/goals/first_million_req.tres")
|
||||
]
|
||||
```
|
||||
|
||||
### Defining a Requirement
|
||||
|
||||
Create `res://sandbox/goals/first_million_req.tres`:
|
||||
|
||||
```
|
||||
[gd_resource type="Resource" script_class="GoalRequirementData"]
|
||||
[resource]
|
||||
currency = preload("res://sandbox/currencies/gold.tres")
|
||||
amount_mantissa = 1.0
|
||||
amount_exponent = 6 # 1,000,000
|
||||
```
|
||||
|
||||
### Connecting to Generator
|
||||
|
||||
In `CurrencyGeneratorData`:
|
||||
```gdscript
|
||||
@export var unlock_goal: GoalData # Assign goal resource
|
||||
@export var unlock_goal_behavior: UnlockGoalBehavior = AUTOMATIC
|
||||
```
|
||||
|
||||
## Signals
|
||||
|
||||
```gdscript
|
||||
signal goal_completed(goal_id: StringName)
|
||||
signal goal_progress_changed(goal_id: StringName, progress: float)
|
||||
```
|
||||
|
||||
## Integration Points
|
||||
|
||||
### With GameState
|
||||
- Goals auto-discovered from `res://sandbox/goals/`
|
||||
- Completion state saved to JSON
|
||||
- Buff unlock goals checked automatically
|
||||
|
||||
### With Buffs
|
||||
```gdscript
|
||||
# In GeneratorBuffData
|
||||
@export var unlock_goal: GoalData
|
||||
|
||||
# When goal completes, buff auto-unlocks:
|
||||
GameState._try_unlock_buff_from_goal(buff)
|
||||
```
|
||||
|
||||
### With Prestige
|
||||
- Goal completion state persists through prestige
|
||||
- Reset via `GameState.reset_for_prestige()`
|
||||
|
||||
## See Also
|
||||
|
||||
- `core/game_state.gd` - Goal state management
|
||||
- `generator/currency_generator_data.gd` - Generator unlock goals
|
||||
- `generator/generator_buff_data.gd` - Buff unlock goals
|
||||
Reference in New Issue
Block a user