5.0 KiB
AGENTS.md
Godot 4.6 idle-game; code is GDScript + .tscn scenes.
Build, Lint, And Test Commands
Use GODOT_BIN for your local editor binary (e.g. godot, godot4, or full path).
Run project: "$GODOT_BIN" --path .
Headless smoke/lint parse: "$GODOT_BIN" --headless --path . --quit
Script syntax check (single script): ./scripts/check_syntax.sh <path> (e.g. ./scripts/check_syntax.sh res://core/level_game_state.gd)
Run single test: ./scripts/run_test.sh res://tests/<file>.gd
Run all tests: ./scripts/run_all.sh
Tests are custom headless scripts in tests/ using LevelGameState simulation (no GUT).
Architecture And Structure
No Autoloads
There are no autoload singletons. All state lives in scene nodes. The project was fully decoupled from globals.
Main Scene
run/main_scene points to docs/gyms/tiny_sword/tiny_sword.tscn (uid dadeowsvaywpp). This is the canonical playable scene. docs/museums/big_number_museum.tscn is a secondary prototype/testing scene.
Core Systems (core/)
core/big_number.gd—class_name BigNumber: numeric API for huge-value math, comparisons, formatting, and serialization ({m: float, e: int}scientific notation).core/level_game_state.gd—class_name LevelGameState(extendsNode): the central runtime state node. Owns all currency balances, generator states, buff levels, goal completion, research XP, prestige buff unlocks, and save/load. Assigned catalogue resources via@export:currency_catalogue→CurrencyCatalogue(defines all currencies)buff_catalogue→BuffCatalogue(generator buffs)goal_catalogue→GoalCatalogue(achievement goals)research_catalogue→ResearchCatalogue(research tracks)prestige_buff_catalogue→PrestigeBuffCatalogue(permanent prestige upgrades)
core/edge_scroll_camera.gd— camera with edge-scrolling and zoom.
Subsystems (core/<name>/)
Each subsystem has its own directory with a README.md:
core/currency/—Currencyresource,CurrencyCatalogueresource,currency_panel.gdUI.core/generator/—CurrencyGenerator(production node),CurrencyGeneratorData(balancing resource),GeneratorBuffData(upgrades),ResearchBuffCalculator(static utility),generator_container.gdUI.core/goals/—GoalData(achievement resource),GoalRequirementData(individual criteria),current_goal_panel.gdUI.core/prestige/—PrestigeManager(child node ofLevelGameStatemanaging resets + multipliers),PrestigeConfig,PrestigeBuffNode(DAG graph node),PrestigeBuffCatalogue, UI panels (prestige_panel,prestige_progress_bar,prestige_buff_graph_panelwith tiles).core/research/—ResearchDataresource (XP thresholds, production multipliers per level),ResearchCatalogue,research_panel.gd+research_row.gdUI.
Content Is Data-Driven (docs/gyms/)
All gameplay content (currencies, generators/buildings, buffs, goals, research, prestige config) is defined as .tres resource files under docs/gyms/tiny_sword/ and composed in tiny_sword.tscn. No hardcoded JSON data files.
Root-Level UI Helpers
currency_label.gd,currency_tile.tscn— reusable currency display components.big_number_progress_bar.gd/.tscn— progress bar for BigNumber values.generator_buff_tile.gd/.tscn— individual buff upgrade tile.goals_debug_ui.gd/.tscn— debug overlay for goal state.
Persistence
Local JSON only: LevelGameState saves to the path set in its save_file_path export (e.g. user://tiny_sword_save.json). No external DB/server/backend. Save format version is currently 8.
Testing
Custom headless test scripts in tests/ that instantiate LevelGameState directly (no scene tree needed). Helper scripts in scripts/:
check_syntax.sh— single-file Godot syntax check.run_test.sh— run a single test script headless.run_all.sh— run all tests.
Code Style And Conventions
Prefer typed GDScript (var x: Type, func f() -> void) and keep shared models/components as class_name scripts.
Naming: snake_case for vars/functions/signals, PascalCase for classes, UPPER_SNAKE_CASE for constants.
Follow existing Godot style: tabs/consistent indentation, early returns, and short functions grouped by purpose.
When reading files/JSON, always guard FileAccess.open(...) and validate parsed types before indexing.
Use signals (emitted by LevelGameState) for UI updates instead of polling or cross-node direct mutation.
No Cursor/Claude/Windsurf/Cline/Goose/Copilot rule files were found in this repository, so this file is the canonical agent guidance.
Avoid trivial one-line wrapper/helper functions that only forward or repack data. Inline the logic at the real call site unless the wrapper adds meaningful abstraction or is reused enough to justify it.
Resource type safety: Use the specific resource type. Avoid the bare Resource type. Prefer Currency, CurrencyGeneratorData, GeneratorBuffData, GoalData, ResearchData, PrestigeBuffNode, etc.