Cleanup and planning
This commit is contained in:
@@ -1,58 +0,0 @@
|
||||
# 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
|
||||
@@ -1,10 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://jeoiinukrrsp"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dtbxopw6ulhl8" path="res://core/generator/currency_generator.gd" id="1_4n4ca"]
|
||||
[ext_resource type="Resource" uid="uid://brqaojindcxa5" path="res://idles/currencies/magic.tres" id="2_5tmvy"]
|
||||
[ext_resource type="Resource" uid="uid://co0mcc2kvcpo5" path="res://idles/generators/orb.tres" id="3_wx13b"]
|
||||
|
||||
[node name="CurrencyGenerator" type="Node2D" unique_id=967969064]
|
||||
script = ExtResource("1_4n4ca")
|
||||
currency = ExtResource("2_5tmvy")
|
||||
data = ExtResource("3_wx13b")
|
||||
|
||||
@@ -10,6 +10,7 @@ enum BuffKind {
|
||||
const HUGE_EXPONENT: int = 1000000
|
||||
|
||||
@export var id: StringName = &""
|
||||
@export var target_ids: Array[StringName] = []
|
||||
@export var kind: BuffKind = BuffKind.AUTO_PRODUCTION_MULTIPLIER
|
||||
@export_multiline var text: String = ""
|
||||
@export var icon: Texture2D
|
||||
@@ -35,6 +36,18 @@ const HUGE_EXPONENT: int = 1000000
|
||||
@export var resource_purchase_base_exponent: int = 0
|
||||
@export var resource_purchase_increment_multiplier: float = 1.2
|
||||
|
||||
func targets_generator(generator_id: StringName) -> bool:
|
||||
if target_ids.is_empty():
|
||||
return false
|
||||
|
||||
if target_ids.has("*"):
|
||||
return true
|
||||
|
||||
return target_ids.has(generator_id)
|
||||
|
||||
func get_target_generators() -> Array[StringName]:
|
||||
return target_ids.duplicate()
|
||||
|
||||
func has_unlock_goal() -> bool:
|
||||
if unlock_goal == null:
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user