Files
idle/TODO.md

6.6 KiB

TODO

Ascension Buff Tree — Needs Review Before Implementation

Goal

Add a permanent buff tree system:

  • Separate from existing GeneratorBuffData (which resets on prestige).
  • Permanent — prestige does NOT reset ascension buff state.
  • Unlocked by spending ascension currency (earned during prestige).
  • Tree/DAG-structured — nodes have prerequisites (parent_ids) that must be met before a node can be purchased.
  • Multi-level — nodes can be one-shot unlocks (max_level=1) or repeatable upgrades (max_level>1 or -1 for infinite).

Data Structure

AscensionBuffNode (Resource)

Single node in the tree.

Field Type Notes
id StringName Unique node ID
display_name String UI label
description String (multiline) Tooltip
icon Texture2D Visual
parent_ids Array[StringName] Prerequisites (DAG, not strict tree — multiple parents allowed)
effect_type enum EffectType What this buff does
effect_value float Base effect magnitude
effect_per_level float Extra effect per level beyond first (default 0.0)
target_id StringName Target generator/currency for type-specific effects (empty = global)
cost_mantissa float Ascension currency cost base
cost_exponent int
cost_multiplier float Cost scaling per level
max_level int How many times it can be upgraded (1 = one-time, -1 = infinite)
tier int Row in tree UI (visual grouping)
x_position float Column in tree UI

Effect types (extensible enum):

GLOBAL_PRODUCTION_MULTIPLIER      → multiply all generator output
GENERATOR_PRODUCTION_MULTIPLIER   → multiply one generator's output
CURRENCY_PER_RUN                  → start each prestige with this currency
COST_REDUCTION                    → reduce all generator purchase costs
PRESTIGE_GAIN_MULTIPLIER          → earn more ascension currency per prestige
GENERATOR_COUNT_MULTIPLIER        → scaling based on owned generator count
RESEARCH_XP_MULTIPLIER            → faster research leveling

AscensionBuffCatalogue (Resource)

Flat list of nodes. The tree emerges from parent_ids. Follows existing catalogue pattern (BuffCatalogue, GoalCatalogue, etc.).

Field Type
nodes Array[AscensionBuffNode]

State in LevelGameState

@export var ascension_buff_catalogue: AscensionBuffCatalogue
var _ascension_buff_levels: Dictionary = {}  # {StringName: int} — node_id → unlock count
  • Never cleared by reset_for_prestige() (unlike _buff_levels for generator buffs, which IS cleared).
  • Normalized/sanitized on load (like generator states).

Save Format

  • Bump CURRENT_SAVE_FORMAT_VERSION from 7 → 8.
  • New key: "ascension_buff_levels"{ "node_id": level_int, ... }.

API on LevelGameState

Method Purpose
purchase_ascension_buff(buff_id) → bool Spend ascension currency, increment level, emit signal, save
can_purchase_ascension_buff(buff_id) → bool All parent_ids met? Under max_level? Enough currency?
get_ascension_buff_cost(buff_id) → BigNumber Cost for the NEXT level (scaled by cost_multiplier)
get_ascension_buff_level(buff_id) → int Current unlock count
get_ascension_buff_multiplier(effect_type, target_id) → float Walk tree, compute combined effect
get_available_ascension_buffs() → Array[AscensionBuffNode] Nodes with prerequisites met

Signals

signal ascension_buff_changed(buff_id: StringName, new_level: int)
signal ascension_currency_changed(new_unspent: BigNumber)

Prestige Integration

No changes needed to PrestigeManager._reset_all_buff_levels() — it only touches _buff_levels (generator buffs), not _ascension_buff_levels. The new dictionary naturally survives the reset.

Purchase Flow

Player clicks upgrade node
  → can_purchase_ascension_buff(node_id)
    → All parent_ids at required level?  (max_level for prerequisite, or just ≥1)
    → Current level < max_level?
    → Enough ascension currency?
  → YES: spend_currency_by_id(ascension_currency, cost)
  → _ascension_buff_levels[node_id] += 1
  → emit ascension_buff_changed
  → save_game()

Example Tree Content (Illustrative)

Tier 0 (roots):
  strong_start          → +10 gold/run           cost: 1   parents: []
  efficiency            → +10% global prod       cost: 1   parents: []
  thrifty               → -5% gen costs          cost: 2   parents: []

Tier 1:
  better_start          → +100 gold/run          cost: 3   parents: [strong_start]
  enhanced_efficiency   → +25% global prod       cost: 3   parents: [efficiency]
  double_dip            → +50% gold from forestry cost: 5   parents: [strong_start, efficiency]

Tier 2:
  power_surge           → +100% global prod      cost: 10  parents: [better_start, enhanced_efficiency]

Files to Create/Modify

File Action Purpose
core/ascension/ascension_buff_node.gd Create Node resource
core/ascension/ascension_buff_catalogue.gd Create Catalogue resource
core/ascension/ascension_buff_tree_panel.gd Create UI panel (or integrate into prestige panel)
core/level_game_state.gd Modify Add catalogue ref, _ascension_buff_levels, purchase/query methods, save/load, signals
core/prestige/prestige_manager.gd Modify (light) Emit ascension_currency_changed on spend/earn
docs/gyms/tiny_sword/ascension/*.tres Create .tres resources for actual tree content

Open Questions for Review

  1. Prerequisite level requirement: Should a parent need to be at max_level, or is level 1 sufficient? (Leaning: max_level is required, otherwise the tree loses structural meaning.)
  2. Effect stacking: For GLOBAL_PRODUCTION_MULTIPLIER, should separate nodes multiply together or add? (Leaning: multiply — consistent with the existing generator buff multiplier pattern.)
  3. UI placement: Should the tree panel be a tab in the prestige panel, a separate screen, or inlined somewhere?
  4. Ascension currency unspent tracking: Currently PrestigeManager.current_prestige_unspent tracks unspent prestige currency. Should the buff tree consume from this directly, or should ascension currency be a proper Currency in the catalogue that the tree spends via LevelGameState.spend_currency_by_id()? (Leaning: use spend_currency_by_id() for consistency — ascension currency is already added to the currency catalogue.)
  5. Content: What actual buffs and tree shape should the first version ship with?