systems rework: buffs, prestige graph, research, modular architecture
Decouples core systems from centralized globals in favor of catalogue-based architecture and data-driven content. Key changes: - Prestige: node-based buff tech tree, graph panel, progress bar - Research: multi-worker system, per-generator research, xp generation - Ascension: meta-currency layer via multi-currency prestige resets - Buffs: refactored as generator-independent via catalogues - UI: currency panel, edge-scrolling camera + zoom, current-goal panel - Alchemy Tower: crafting building with recipe/cost system - Testing: 7 test suites (ascension, prestige, research, goals) - Content: migrated from hardcoded idles/ to gym format (tiny_sword)
This commit was merged in pull request #1.
This commit is contained in:
97
.opencode/plans/currency-panel.md
Normal file
97
.opencode/plans/currency-panel.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Plan: Create CurrencyPanel Widget
|
||||
|
||||
## Goal
|
||||
Regroup the 9 individual CurrencyTile nodes in tiny_sword.tscn into a single dynamic `CurrencyPanel` widget that automatically retrieves and displays all currencies from the LevelGameState catalogue.
|
||||
|
||||
## Changes
|
||||
|
||||
### 1. Create `CurrencyPanel` script (`core/currency/currency_panel.gd`)
|
||||
|
||||
**New file**: `res://core/currency/currency_panel.gd`
|
||||
|
||||
**Class**: `class_name CurrencyPanel`, extends `PanelContainer`
|
||||
|
||||
**Structure**:
|
||||
```gdscript
|
||||
class_name CurrencyPanel
|
||||
extends PanelContainer
|
||||
|
||||
const CURRENCY_TILE_SCENE: PackedScene = preload("res://currency_tile.tscn")
|
||||
|
||||
@onready var _tiles_container: VBoxContainer = $CurrencyTiles
|
||||
|
||||
var _game_state: LevelGameState
|
||||
|
||||
func _ready() -> void:
|
||||
_game_state = find_parent("LevelGameState")
|
||||
if _game_state == null:
|
||||
push_error("CurrencyPanel: No LevelGameState found in parent hierarchy")
|
||||
return
|
||||
_build_currency_tiles()
|
||||
_game_state.ready.connect(_on_game_state_ready)
|
||||
|
||||
func _build_currency_tiles() -> void:
|
||||
# Clear existing children
|
||||
for child in _tiles_container.get_children():
|
||||
child.queue_free()
|
||||
|
||||
if _game_state.currency_catalogue == null:
|
||||
return
|
||||
|
||||
for currency in _game_state.currency_catalogue.currencies:
|
||||
if currency == null:
|
||||
continue
|
||||
var tile: CurrencyTile = CURRENCY_TILE_SCENE.instantiate()
|
||||
# Set exports before add_child() so they're available in _ready()
|
||||
tile.currency = currency
|
||||
tile.game_state = _game_state
|
||||
_tiles_container.add_child(tile)
|
||||
|
||||
func _on_game_state_ready() -> void:
|
||||
pass
|
||||
```
|
||||
|
||||
**Why this works with existing CurrencyTile**: CurrencyTile uses `@export` for `currency` and `game_state`. When `instantiate()` is called, `_ready()` is NOT invoked yet - it fires when the node is added to the scene tree. By setting properties before `add_child()`, `_ready()` sees them as non-null. The DebugIncomeButton is preserved since CurrencyTile is unchanged.
|
||||
|
||||
### 2. Update tiny_sword.tscn scene
|
||||
|
||||
**Replace**: 9 individual CurrencyTile nodes under `LevelGameState/UI` with a single CurrencyPanel hierarchy.
|
||||
|
||||
**Remove from scene**:
|
||||
- All 9 individual CurrencyTile nodes: `GoldCurrencyTile`, `WorkerCurrencyTile`, `FoodCurrencyTile`, `WoodCurrencyTile`, `AscensionCurrencyTile`, `MagicGoldTile`, `ManaStoneTile`, `CogniteTile`, `PhilosoperStoneTile`
|
||||
- ExtResource `7_0cs5o` (currency_tile.tscn) - no longer referenced directly
|
||||
- All 9 individual currency resource ExtResources: `9_1363k` (gold), `10_i1cck` (worker), `11_hskcg` (food), `12_l6a68` (wood), `15_ascension`, `20_no27p` (magic_gold), `22_rbyxa` (mana_stone), `23_vrcrd` (cognite), `24_eaq6h` (philosoper_stone)
|
||||
|
||||
**Add to scene**:
|
||||
- ExtResource `8_cpnl` → `res://core/currency/currency_panel.gd`
|
||||
- New node hierarchy:
|
||||
```
|
||||
LevelGameState/UI (Control, layout_mode=3)
|
||||
CurrencyPanel (PanelContainer, layout_mode=1, pos 5,5 size 250x340, script=8_cpnl)
|
||||
CurrencyTiles (VBoxContainer, separation=4) ← script-less, populated at runtime
|
||||
GoalsDebugUI (repositioned: offset_left=265)
|
||||
```
|
||||
|
||||
**Keep**: GoalsDebugUI (repositioned slightly from offset_left=1275 to offset_left=265 to account for panel width)
|
||||
|
||||
## File Structure After Changes
|
||||
|
||||
```
|
||||
core/
|
||||
level_game_state.gd # unchanged (ready is built-in)
|
||||
currency/
|
||||
currency_panel.gd # NEW: dynamic panel widget
|
||||
docs/gyms/tiny_sword/
|
||||
tiny_sword.tscn # 9 tiles → 1 panel hierarchy (cleaner)
|
||||
```
|
||||
|
||||
## No Changes Needed
|
||||
- **`level_game_state.gd`**: The `ready` signal is built-in for Godot nodes - no addition needed.
|
||||
- **`currency_label.gd` (CurrencyTile)**: Unchanged - DebugIncomeButton preserved.
|
||||
|
||||
## Testing
|
||||
- Run Godot headless to verify scene loads without errors
|
||||
- Verify all 9 currencies appear in the CurrencyPanel
|
||||
- Verify currency values update on changes (currency_changed signal)
|
||||
- Verify DebugIncomeButton works on each tile
|
||||
- Verify the panel doesn't overlap with GoalsDebugUI
|
||||
Reference in New Issue
Block a user