2026-03-21 18:32:54 +01:00
2026-03-21 18:32:54 +01:00
2026-03-21 18:32:54 +01:00
2026-03-21 18:32:54 +01:00
2026-03-08 10:38:30 +01:00
2026-03-08 10:38:30 +01:00
2026-03-19 22:18:34 +01:00
2026-03-08 10:38:30 +01:00
2026-03-08 10:38:30 +01:00
2026-03-08 10:38:30 +01:00
2026-03-08 10:38:30 +01:00
2026-03-21 18:32:54 +01:00
2026-03-13 00:36:52 +01:00
2026-03-21 12:11:38 +01:00
2026-03-08 10:38:30 +01:00
2026-03-08 10:38:30 +01:00
2026-03-21 12:11:38 +01:00

Idles - Systems Architecture Report

Scope Covered

This report covers all tracked files in the repository (62 total at time of analysis), including:

  1. Project configuration.
  2. Core runtime scripts.
  3. Gameplay/economy systems.
  4. Goal/unlock systems.
  5. UI adapter scripts and scenes.
  6. Data resources (.tres).
  7. Technical docs and metadata/import files.

The focus below is on behavior-bearing files and how they interact.

Architecture Summary

  1. Global startup and singleton wiring is defined in project.godot.
  2. Two autoload services power the runtime: CurrencyDatabase and GameState.
  3. BigNumber is the numeric backbone used by currency amounts, costs, goals, production, and persistence.
  4. Generator behavior is runtime-driven by CurrencyGenerator, parameterized by CurrencyGeneratorData and GeneratorBuffData resources.
  5. Goal-based progression uses reusable goal primitives (GoalData, GoalRequirementData) directly on generator data (CurrencyGeneratorData.unlock_goal).
  6. UI scripts are thin adapters listening to GameState signals.

Core Systems

1) Numeric System (BigNumber)

File: core/big_number.gd

BigNumber stores values as mantissa + exponent (scientific notation style), normalizes them, and provides:

  1. Arithmetic operations (add, subtract, multiply, divide).
  2. In-place fast accumulation (add_in_place) for frame-loop performance.
  3. Safe comparisons (compare_to, is_greater_than, etc.).
  4. Ratio conversion for progress UI (get_ratio).
  5. Display formatting (to_string_sci, to_string_suffix).
  6. JSON-friendly serialization/deserialization.

This class is used everywhere currency values move.

2) Currency Catalog System

Files: core/currency/currency.gd, core/currency_database.gd, idles/currencies/*.tres

CurrencyDatabase scans res://idles/currencies, loads typed Currency resources, normalizes IDs, and resolves names/icons.

Current data assets:

  1. idles/currencies/magic.tres (id = magic).
  2. idles/currencies/knowledge.tres (id = knowledge).

This creates a data-driven currency catalog that GameState, goals, and UI can query consistently.

3) Global State + Persistence (GameState)

File: core/game_state.gd

GameState is the central state authority and signal bus.

It owns:

  1. Current currency map by currency ID.
  2. Total acquired currency map by currency ID.
  3. Generator states (owned, purchased_count, unlocked, available).
  4. Generator buff levels.
  5. Generator buff unlocked flags.
  6. last_save_time.

Important signals:

  1. currency_changed.
  2. generator_state_changed.
  3. generator_buff_level_changed.
  4. generator_buff_unlocked_changed.

Persistence:

  1. Save path: user://idle_save.json.
  2. Save payload includes currencies, generator states, buff levels, buff unlocked map, and timestamp.
  3. Load path includes defensive sanitization and backward-compatible defaulting.

4) Generator Economy Runtime

Files: core/generator/currency_generator.gd, core/generator/currency_generator_data.gd, core/generator/currency_generator.tscn

CurrencyGenerator implements active gameplay behavior:

  1. Auto production cycles (_process, cycle accumulation).
  2. Click/hover grants with cooldown.
  3. Buy-one and buy-max generator purchases.
  4. Buff purchase logic and buff effect application.
  5. State registration and lookup through GameState.

CurrencyGeneratorData provides formulas and tuning knobs:

  1. Exponential cost growth.
  2. Bulk-buy geometric cost.
  3. Max-affordable estimate.
  4. Milestone multipliers.
  5. Purchased-count multiplier.
  6. Production/cycle and production/second helpers.
  7. ROI-like helpers (payback_seconds, income_to_cost_ratio).
  8. Optional generator unlock goal (unlock_goal).

5) Buff System

Files: core/generator/generator_buff_data.gd, idles/buffs/*.tres

Buff kinds:

  1. Auto production multiplier.
  2. Manual click multiplier.
  3. Resource purchase (instant grant on buff buy).

Each buff resource defines:

  1. Unlock rules (unlocked and optional unlock_goal).
  2. Effect scaling (base_effect, effect_increment).
  3. Cost scaling (base_cost, cost_multiplier).
  4. Optional target currency and resource grant scaling.

6) Goals and Unlock Progression

Files:

  1. core/goals/goal_requirement_data.gd
  2. core/goals/goal_data.gd
  3. core/generator/currency_generator_data.gd
  4. core/generator/currency_generator.gd
  5. idles/goals/*.tres

Key behavior:

  1. Goal requirements validate currency + target amount.
  2. Requirement completion checks total acquired currency, not current wallet.
  3. Each CurrencyGenerator evaluates its own data.unlock_goal on startup and on currency_changed.
  4. If the goal is met, it sets both unlocked = true and available = true, then emits goal_achieved(generator_id, goal_id).

7) UI Adapter Layer

Files:

  1. generator_container.gd + generator_container.tscn.
  2. generator_buff_tile.gd + generator_buff_tile.tscn.
  3. currency_label.gd + currency_tile.tscn.
  4. big_number_progress_bar.gd + big_number_progress_bar.tscn.
  5. core/generator-unlock-goals/goals_debug_ui.gd + .tscn.

These scripts primarily:

  1. Subscribe to GameState and generator signals.
  2. Convert runtime values to UI strings/states.
  3. Trigger user actions (buy generator, buy buff, debug unlock).

The architecture is mostly event-driven and avoids polling for state refresh.

Scene Composition

Active Gameplay Prototype

File: docs/museums/generator_museum.tscn

It composes:

  1. MagicGenerator instance.
  2. KnowledgeGenerator instance (initially hidden and starts locked via data).
  3. Currency tiles for magic and knowledge.
  4. Goals debug UI panel.

Legacy/Secondary Museum

Files: docs/museums/big_number_museum.tscn, docs/museums/big_number_museum.gd

This appears to be an older/placeholder scene and not the current gameplay focus.

Data-Driven Content Snapshot

Generators

  1. primary_generator.tres: Magic Orb, active from start, includes 3 buffs.
  2. secondary_generator.tres: Library, starts locked/unavailable and unlocks via magic_total_30 goal.

Buffs (Magic)

  1. magic_auto_flux.tres: auto-production buff, unlocked by default.
  2. magic_click_focus.tres: manual-click buff.
  3. magic_supply_cache.tres: resource-purchase buff.

Goals

  1. magic_total_30.tres: reach total magic 30.
  2. magic_total_1300.tres: reach total magic 1300.

End-to-End Runtime Flow

  1. project.godot autoloads CurrencyDatabase and GameState.
  2. CurrencyDatabase builds currency catalog from idles/currencies.
  3. GameState initializes per-currency maps and loads save data.
  4. Scene nodes initialize and connect to GameState and local gameplay signals.
  5. Generators produce currency automatically and via click/hover paths.
  6. Currency updates emit currency_changed and drive UI refresh + unlock checks.
  7. Goal unlock evaluator may transition generator state to unlocked/available.
  8. Generator and buff purchases route all balance/state mutations through GameState.

Signal Guide (Emitters and Listeners)

Custom Gameplay Signals

Signal Declared In Emitted By Emitted When Listeners
currency_changed(currency_id, new_amount) core/game_state.gd GameState.add_currency_by_id, GameState.spend_currency_by_id Any currency balance increases/decreases CurrencyGenerator._on_currency_changed, GeneratorPanel._on_currency_changed, CurrencyTile._on_currency_changed, BigNumberProgressBar._on_currency_changed, GoalsDebugUI._on_currency_changed
generator_state_changed(generator_id, state) core/game_state.gd GameState.register_generator, GameState._set_generator_state Generator state created or changed (owned, purchased_count, unlocked, available) CurrencyGenerator._on_generated_state_changed, GeneratorPanel._on_generator_state_changed, GoalsDebugUI._on_generator_state_changed
generator_buff_level_changed(generator_id, buff_id, new_level) core/game_state.gd GameState.register_generator_buff, GameState.set_generator_buff_level Buff level created/sanitized/updated GeneratorPanel._on_generator_buff_level_changed
generator_buff_unlocked_changed(generator_id, buff_id, unlocked) core/game_state.gd GameState.register_generator_buff_unlocked, GameState.set_generator_buff_unlocked Buff unlock state created/sanitized/updated GeneratorPanel._on_generator_buff_unlocked_changed
purchase_completed(amount, total_owned, total_purchased, total_cost) core/generator/currency_generator.gd CurrencyGenerator.buy Generator purchase succeeds GeneratorPanel._on_generator_updated
purchase_failed(requested_amount, required_cost, available_currency) core/generator/currency_generator.gd CurrencyGenerator.buy Generator purchase fails for insufficient funds GeneratorPanel._on_generator_updated
production_tick(amount, cycle_count, total_owned) core/generator/currency_generator.gd CurrencyGenerator._grant_cycle_income One or more automatic production cycles complete GeneratorPanel._on_generator_updated
buff_purchased(buff_id, new_level, cost, cost_currency_id) core/generator/currency_generator.gd CurrencyGenerator.buy_buff Buff purchase succeeds GeneratorPanel._on_generator_updated
buff_purchase_failed(buff_id, required_cost, cost_currency_id) core/generator/currency_generator.gd CurrencyGenerator.buy_buff Buff purchase fails for insufficient funds GeneratorPanel._on_generator_updated
goal_achieved(generator_id, goal_id) core/generator/currency_generator.gd CurrencyGenerator._evaluate_generator_unlock_goal Generator unlock goal transitions that generator to unlocked+available None currently (available for gameplay/UI hooks)
buy_pressed(buff_id) generator_buff_tile.gd GeneratorBuffTile._on_buy_button_pressed User presses buff buy button in a buff row GeneratorPanel._on_buy_buff_pressed

Built-In Godot Signals Wired In This Project

Source Signal Connected In Listener Method Purpose
Area2D.mouse_entered core/generator/currency_generator.tscn CurrencyGenerator._on_area_2d_mouse_entered Enter generator hover zone; mark hover true and show generator panel
Area2D.mouse_exited core/generator/currency_generator.tscn CurrencyGenerator._on_area_2d_mouse_exited Exit generator hover zone; mark hover false and hide generator panel
BuyOneButton.pressed generator_container.tscn GeneratorPanel._on_buy_pressed Buy one generator
BuyMaxButton.pressed generator_container.tscn GeneratorPanel._on_buy_max_pressed Buy max affordable generators
GeneratorContainer.mouse_entered generator_container.tscn GeneratorPanel._on_mouse_entered Intended hover hook on panel container (method currently missing)
GeneratorContainer.mouse_exited generator_container.tscn GeneratorPanel._on_mouse_exited Intended hover hook on panel container (method currently missing)
BuyButton.pressed generator_buff_tile.tscn GeneratorBuffTile._on_buy_button_pressed Emit tile-level buy_pressed custom signal
DebugIncomeButton.pressed currency_tile.tscn CurrencyTile._on_debug_income_button_pressed Add debug income to the tile currency
Button.pressed (runtime-created unlock button) core/generator-unlock-goals/goals_debug_ui.gd GoalsDebugUI._on_unlock_pressed (bound with goal id) Manual debug unlock when a goal is ready

Common Signal Chains

  1. Currency gain/spend chain: generator or debug action mutates GameState currency, GameState emits currency_changed, UI widgets and unlock systems recompute and redraw.
  2. Generator purchase chain: panel button triggers CurrencyGenerator.buy, generator updates GameState state, generator emits purchase signal, panel refreshes stats and buttons.
  3. Buff purchase chain: buff tile emits buy_pressed, panel calls CurrencyGenerator.buy_buff, generator updates buff level/unlock and optionally grants currency, GameState emits buff/currency/state signals, panel and other listeners refresh.
  4. Goal unlock chain: currency_changed triggers generator-local unlock evaluator, evaluator sets generator unlocked/available, emits goal_achieved(generator_id, goal_id), GameState emits generator_state_changed, generator and UI become interactable/visible.

Key Findings and Risks

  1. project.godot has no explicit run/main_scene entry, so startup scene is not pinned in tracked config.
  2. Save/load is only partially wired: load_game() runs at startup, but save_game() is not invoked anywhere else in the repository.
  3. currency_label.gd and big_number_progress_bar.gd reference GameState.GOLD_CURRENCY_ID, but that constant does not exist in core/game_state.gd.
  4. generator_container.tscn connects mouse_entered/mouse_exited to methods that do not exist in generator_container.gd.
  5. Generator unlock goals now assume the target generator exists in-scene and owns its own unlock_goal.
  6. KnowledgeGenerator visibility logic may be inconsistent because currency_generator.gd sets visible = true whenever its generator state changes.
  7. Two buffs are configured locked with no unlock-goal path, so they remain permanently inaccessible under current logic.
  8. core/generator-unlock-goals/TECH_SPEC.md contains some outdated assumptions relative to current .tres-based implementation.

Additional Notes

  1. .uid files are identity metadata used by Godot and contain no runtime logic.
  2. icon.svg and icon.svg.import are standard icon/import metadata.
  3. Root config files (.editorconfig, .gitattributes, .gitignore) are minimal and conventional.
Description
No description provided
Readme 4.4 MiB
Languages
GDScript 99%
Shell 1%