Files
idle/core/generator-unlock-goals/TECH_SPEC.md

2.6 KiB

Generator-Embedded Unlock Goals - Technical Specification

Document Status

  • Version: 2.0
  • Date: 2026-03-21
  • Scope: Unlock generators from CurrencyGeneratorData.unlock_goal when goal thresholds are reached.

Problem Statement

Generator unlock progression should be authored where generator behavior lives: CurrencyGeneratorData. The previous scene-level target mapping layer increased setup complexity and created mismatch risk between goal targets and scene content.

Current Baseline

  1. Generator state persists in GameState.generator_states (owned, purchased_count, unlocked, available).
  2. CurrencyGenerator already gates interactions using is_available_to_player().
  3. Goal primitives remain reusable and data-driven:
    • GoalRequirementData
    • GoalData
  4. Generator data now owns unlock definition via unlock_goal: GoalData.

Functional Requirements

  1. A generator may define one optional unlock goal (CurrencyGeneratorData.unlock_goal).
  2. Goal completion uses logical AND across requirements.
  3. Requirement checks use total acquired currency (GameState.get_total_currency_acquired_by_id).
  4. Unlock evaluation runs:
    • once on generator _ready()
    • on every GameState.currency_changed
  5. When a goal is met, runtime sets:
    • GameState.set_generator_unlocked(generator_id, true)
    • GameState.set_generator_available(generator_id, true)
  6. Unlock transitions are idempotent.
  7. Unlock completion emits CurrencyGenerator.goal_achieved(generator_id, goal_id) for hooks/UI.

Runtime Design

  1. CurrencyGeneratorData exposes:
    • has_unlock_goal()
    • is_unlock_goal_met()
    • get_unlock_goal_id()
  2. CurrencyGenerator executes _evaluate_generator_unlock_goal().
  3. No scene-level unlock controller is required.
  4. Goals debug UI discovers goals from scene generators instead of external target-mapping resources.

Data Authoring Rules

  1. Configure locked generators with starts_unlocked = false and starts_available = false.
  2. Set unlock_goal directly on that generator .tres resource.
  3. Keep GoalData.id unique and stable.
  4. Goal data can still be shared across systems (generator unlocks, buff unlocks).

Save/Load Behavior

  1. Unlock persistence remains unchanged because GameState stores unlocked/available.
  2. Re-evaluation after load is safe due to idempotent state writes.

Validation

  1. Run headless parse: "$GODOT_BIN" --headless --path . --quit
  2. Manual smoke test in generator_museum:
    • verify locked generator starts unavailable
    • grant required currency
    • verify generator unlocks automatically
    • verify state persists after restart