Files
idle/README.md
2026-04-18 10:50:44 +02:00

199 lines
6.3 KiB
Markdown

# Idles - Godot 4.6 Idle Game
A modular idle/incremental game prototype featuring a decoupled buff system, multi-target buffs with wildcard support, and goal-based progression.
## Quick Start
```bash
# Run the project
"$GODOT_BIN" --path .
# Headless mode (lint/smoke test)
"$GODOT_BIN" --headless --path . --quit
# Check single script syntax
"$GODOT_BIN" --headless --check-only --script res://core/big_number.gd
```
## Architecture Overview
### Core Systems
| System | Location | Purpose |
|--------|----------|---------|
| **BigNumber** | `core/big_number.gd` | Handles huge numbers (mantissa + exponent) for idle game math |
| **Currency** | `core/currency/`, `core/currency_catalogue.gd` | Catalog system for all in-game currencies |
| **LevelGameState** | `core/level_game_state.gd` | Central state authority (currencies, generators, buffs, persistence, research) |
| **Generators** | `core/generator/` | Production mechanics (auto cycles, clicks, purchases) |
| **Buffs** | `core/generator/generator_buff_data.gd` | Global multipliers with multi-target support |
| **Goals** | `core/goals/` | Unlock conditions for generators and buffs |
| **Prestige** | `core/prestige/` | Reset-with-bonus mechanics |
| **Research** | `core/research/` | XP-based progression with production multipliers |
### Key Nodes
| Node | Script | Description |
|------|--------|-------------|
| `LevelGameState` | `core/level_game_state.gd` | Central state management, save/load |
| `CurrencyCatalogue` | `core/currency_catalogue.gd` | Currency catalog resource |
| `PrestigeManager` | `core/prestige/prestige_manager.gd` | Prestige system |
### Data Directory Structure
```
sandbox/
├── currencies/ # Currency resources (gold, food, wood, worker, etc.)
├── generators/ # Generator configuration (.tres files)
├── buffs/ # Buff definitions with target_ids
├── goals/ # Unlock goal definitions
└── prestige/ # Prestige configuration
```
## Current Architecture (Post-Refactoring)
### Decoupled Buff System
Buffs are now **globally registered** and **multi-target capable**:
- **Global Levels**: Buff levels are shared across all targets
- **Multi-Target**: A single buff resource can affect multiple generators
- **Wildcards**: `target_ids: ["*"]` applies to all current + future generators
- **Auto-Discovery**: Buffs loaded from `res://sandbox/buffs/` at runtime
- **Goal-Based Activation**: Buffs unlock automatically when goals are met
### Key Design Decisions
| Feature | Implementation |
|---------|----------------|
| **Buff Levels** | Global (shared across all targets) |
| **Buff Registry** | Auto-discovered from `res://sandbox/buffs/` |
| **Wildcards** | `["*"]` matches all current AND future generators |
| **Default State** | Inactive until goal met |
| **Persistence** | Buff definitions serialized to save |
| **Prestige** | All buff levels reset to 0 |
| **Activation** | Automatic via goals, no manual toggle |
### API Changes
**Old API (per-generator state):**
```gdscript
GameState.register_generator_buff(generator_id, buff_id, level)
GameState.get_generator_buff_level(generator_id, buff_id)
```
**New API (global buff state):**
```gdscript
GameState.register_buff(buff: GeneratorBuffData)
GameState.get_buff(buff_id) -> GeneratorBuffData
GameState.get_buffs_for_generator(generator_id) -> Array[GeneratorBuffData]
GameState.get_effective_multiplier(generator_id, kind) -> float
```
## Save Format
**Version 5 (current):**
```json
{
"save_format_version": 5,
"currencies": {
"<currency_id>": {
"current": {"m": float, "e": int},
"total": {"m": float, "e": int},
"all_time": {"m": float, "e": int}
}
},
"generator_states": { ... },
"buff_levels": { "farm_flux": 5 },
"buff_unlocked": { "farm_flux": true },
"buff_active": { "farm_flux": true },
"goals": { "completed": ["goal_id"] },
"research_xp": { "<research_id>": {"m": float, "e": int} },
"research_levels": { "<research_id>": int },
"last_save_time": 1234567890
}
```
**Note**: Save format version 5 includes research XP as BigNumber serialization.
## Development
### Adding New Content
**New Currency:**
1. Create `res://sandbox/currencies/<name>.tres` (Currency resource)
2. Set `id`, `display_name`, `icon`
3. Add to `CurrencyCatalogue` resource
**New Generator:**
1. Create `res://sandbox/generators/<name>.tres` (CurrencyGeneratorData)
2. Configure production stats, costs, purchase currency
3. Optionally add `unlock_goal`
4. Add `CurrencyGenerator` node to scene
**New Buff:**
1. Create `res://sandbox/buffs/<name>.tres` (GeneratorBuffData)
2. Set `target_ids` (e.g., `["farm", "forestry"]` or `["*"]`)
3. Configure effect, cost, unlock goal
4. Add to `BuffCatalogue` resource
**New Research:**
1. Create `res://sandbox/research/<name>.tres` (ResearchData)
2. Link to generator via `generator_id`
3. Configure XP and multiplier parameters
4. Add to `ResearchCatalogue` resource
### Testing
```bash
# Run project and test manually
"$GODOT_BIN" --path .
# No automated test framework committed yet
# (GUT not included in repository)
```
## Known Issues / TODOs
- [ ] Manual save triggers not implemented (auto-save needed)
- [ ] `GeneratorPanel` has missing `mouse_entered`/`mouse_exited` handlers
- [ ] Some buffs configured locked with no unlock path
- [ ] No automated test suite
## Current Status
Research system fully implemented with:
- XP-based progression tied to production
- Auto-leveling with BigNumber support
- Buff multipliers for XP gain
- Save format version 5 with research persistence
## Technical Details
### BigNumber System
- **Representation**: Mantissa (float) + Exponent (int)
- **Range**: Handles values up to ~10^308 (float precision limit)
- **Operations**: Add, subtract, multiply, divide, compare
- **Optimization**: `add_in_place()` for performance-critical loops
### Production Formulas
```
Cost for N items: base * ratio^k * ((ratio^n - 1) / (ratio - 1))
Max affordable: log((currency*(ratio-1)/(base*ratio^k)) + 1) / log(ratio)
Production: base_productivity * owned * run_mult * milestone_mult * purchased_mult
```
### Buff Multiplier Stacking
Multiple buffs of the same kind stack **multiplicatively**:
```
total_multiplier = buff1_effect * buff2_effect * buff3_effect * ...
```
## License
Internal prototype - no external license applied.
---
*Last updated: Refactoring plan documented*
*Godot version: 4.6*