# AGENTS.md Guidance for coding agents working in this repository. ## Project overview - Language: Lua (LÖVE game project) - Entry point: `main.lua` - Core code: `src/` - Assets: `assets/` - Runtime config present: `dosbox.conf` - Build system: none (run directly with LÖVE) - Test framework: none configured in-repo ## Repository structure - `main.lua`: top-level LÖVE callbacks and state switching - `src/states.lua`: game-state registry - `src/gstates/`: game states and menu flows - `src/ui/`: UI primitives and layout classes - `src/graphics/`: sprites/faders/drawable abstractions - `src/sound/`: sound managers/effects - `src/utils/`: class helper, settings parsing, assets manager, helpers ## Build, run, lint, and test commands This repo does not define a Makefile/npm scripts/CI workflow. Use direct commands. ### Run the game - Run locally with LÖVE: ```bash love . ``` - Run with debug/skip flags (project-defined args): ```bash love . -- -debug -skip-intro ``` ### Build/package - No packaging script is committed. - If packaging is needed, use standard LÖVE packaging flow externally. ### Lint - No linter config file is committed (`.luacheckrc` not found). - If `luacheck` is available locally, run: ```bash luacheck main.lua src ``` ### Format - No formatter config file is committed (`stylua.toml` not found). - If formatting is needed and `stylua` exists locally, use: ```bash stylua main.lua src ``` ### Tests - No automated tests are currently committed (no `tests/`, `spec/`, or framework config detected). - There is no native "single test" command in the current repo because no test suite exists yet. If you add Busted tests, use this convention: ```bash # all tests busted # single test file busted spec/path/to/file_spec.lua # single test by name filter busted spec/path/to/file_spec.lua --filter "case name" ``` ## Coding conventions Match existing style before introducing new patterns. ### Imports and module layout - Put imports at the top under a section banner. - Use `local X = require 'path'` with single-quoted module paths. - Keep related imports vertically aligned when practical. - Return module/class value at file end under `-- Module return` banner. ### Formatting - Use 4-space indentation (no tabs). - Keep blank lines between logical sections and method blocks. - Preserve section banner style used throughout the codebase: - `------------------------------------------------------------------------------` - `-- Section Name` - Prefer readable, compact methods; avoid deeply nested branches when simple guard clauses work. ### Types and annotations - Use EmmyLua-style annotations where helpful and already used: - `---@class` - `---@param` - `---@return` - Keep annotations accurate when signatures change. ### Naming conventions - Files/modules: lowercase with short names (e.g. `gstate.lua`, `sndmngr.lua`). - Class-like tables: PascalCase locals (e.g. `GameState`, `SoundEffect`). - Methods/functions: snake_case (except LÖVE callback names like `love.update`). - Fields: snake_case (`next_state`, `current_menu`, `all_loaded`). - Constants: UPPER_CASE for module constants (`SETTINGS_PATH`). - Existing globals in `main.lua` (`Current_state`, `Fade`, etc.) are intentional legacy style; avoid creating new globals unless required. ### Object model and inheritance - Use `make_class(...)` from `src/utils/classes.lua` for class-like inheritance. - Constructors are `_init(...)` methods. - Call base constructors explicitly (`Base._init(self, ...)`) when subclassing. - Use colon syntax for instance methods (`function Class:method(...)`). ### State-management patterns - Keep game-flow transitions explicit and deterministic. - For game states, maintain the established lifecycle shape: - `_init` - `load` - `update` - `draw` - `unload` - input handlers as needed - Return the next state index from `update` methods where applicable. ### Error handling and validation - Prefer fail-fast `error(...)` for invariant violations (unknown keys/states, invalid config shape). - Validate parsed external data before assignment (see `src/utils/settings.lua`). - Keep error messages specific and actionable. - Do not silently swallow invalid state transitions. ### Side effects and resources - Keep resource load/unload explicit for assets, sounds, and UI elements. - Ensure objects implementing asset-like behavior support `load`, `unload`, and `is_loaded` consistently. - Be careful with global/shared mutable state (focus handling, active state IDs, fade transitions). ### Agent editing rules for this repo - Prefer minimal, surgical changes that preserve existing architecture. - Do not introduce new third-party dependencies unless explicitly requested. - Do not rewrite naming/style globally unless asked. - When fixing a bug, align with existing state-machine and class patterns. - Update docs when behavior or developer workflow changes. ## Cursor and Copilot rules check - `.cursor/rules/`: not present - `.cursorrules`: not present - `.github/copilot-instructions.md`: not present If these files are added later, merge their guidance into this document and treat project-specific rules as higher priority.