# Project Philosophy This project prioritizes **clarity, correctness, and maintainability** over defensive boilerplate or unnecessary abstraction. AI-generated code should: * follow existing architecture * keep logic simple and explicit * avoid hiding bugs * avoid speculative abstractions If uncertain, prefer **simple direct code** over generalized frameworks. ## Repository Guidelines ### Project Structure & Module Organization - `Assets/` contains all Unity assets and code. Game-specific content lives under `Assets/GameMain/`. - `Assets/GameMain/Scripts/` holds gameplay code organized by domain (`Procedure/`, `Entity/`, `UI/`, `Scene/`, `Sound/`, `Utility/`). - `Assets/GameMain/Scenes/` stores Unity scenes (start from `Assets/Launcher.unity`). - `Assets/GameMain/Configs/` and `Assets/GameMain/DataTables/` store runtime configuration and data tables. - `StreamingAssets/` is for runtime-loaded files that must be preserved on build. - `docs/` contains design notes (see `docs/GameDesign.md`). - `数据表/` is a top-level data table workspace; keep it in sync with `Assets/GameMain/DataTables/` when exporting. ### Build, Test, and Development Commands - Open the project with Unity Hub and load `GeometryTD` as a Unity project. - Play locally via the Unity Editor Play button (no custom CLI runner is defined in this repo). - Build via Unity: `File > Build Settings...` then choose target and build. - IDE support: open `GeometryTD.sln` or `Assembly-CSharp.csproj` for C# navigation and tooling. ### Coding Style & Naming Conventions - C# uses 4-space indentation and Allman braces (see `Assets/GameMain/Scripts/Procedure/ProcedureLaunch.cs`). - Types, methods, and public members use `PascalCase`; locals and parameters use `camelCase`. - Namespaces follow `GeometryTD.*` by feature area (example: `GeometryTD.Procedure`). - Keep Unity `.meta` files with their assets; do not delete or regenerate them manually. --- ## Code Design Principles ### 1. Prefer explicit logic over abstraction Do not introduce abstractions unless they are clearly justified. Avoid creating layers such as: ``` Manager Service Provider Repository Coordinator Bridge ``` unless the architecture explicitly requires them. Simple gameplay logic should remain simple. Bad example: ``` EnemyService -> EnemyManager -> EnemyRepository ``` Good example: ``` EnemySpawner Enemy EnemyAI ``` --- ### 2. Do not create abstractions for a single implementation Avoid introducing interfaces unless multiple implementations are expected. Bad: ``` IEnemyService EnemyService ``` Good: ``` EnemySystem ``` Interfaces are only appropriate when: * multiple implementations are required * plugin/mod systems are involved * testing requires mocking * architecture explicitly defines extension points --- ### 3. Avoid speculative generalization Do not design systems for hypothetical future use. Implement only what the current feature requires. Avoid: * generic service layers * premature plugin systems * unnecessary configuration frameworks --- ## Defensive Programming Policy ### Boundary validation only Validation is appropriate only at **true system boundaries**, such as: * user input * network input * file/config loading * inspector/external data * public API boundaries Internal gameplay logic should assume that invariants are already satisfied. Do not add redundant validation inside internal code. --- ### Do not hide errors Do not silently ignore invalid states. Avoid code such as: ``` if (enemy == null) return; ``` or ``` if (config == null) continue; ``` unless the behavior is intentionally designed. Unexpected states should be **visible**, not hidden. --- ### Prefer fail-fast over silent failure If a condition should never happen in correct execution: Use assertions. Example: ``` Debug.Assert(config != null); ``` Do not convert invariant violations into no-op behavior. Bad: ``` if (config == null) return; ``` Good: ``` Debug.Assert(config != null); ``` --- ### Do not weaken required dependencies Required references must remain required. Do not turn required dependencies into optional ones by adding defensive checks. Bad: ``` if (enemy.Config == null) return; ``` If a dependency is required by design, assume it exists. --- ## Error Handling Do not introduce `try/catch` blocks unless there is a **clear recovery strategy**. Avoid: ``` try { DoSomething(); } catch (Exception e) { Debug.LogError(e); } ``` Exceptions should generally propagate during development so bugs are visible. --- ## Early Return Policy Early returns are acceptable for **normal control flow simplification**. However, do not use early returns to hide invariant violations or missing required state. Bad: ``` if (enemy == null) return; ``` Good: ``` if (!enemy.IsAlive) return; ``` --- ## Logging Avoid excessive logging. Do not log inside per-frame loops unless necessary. Avoid logs like: ``` Debug.Log("Updating enemy"); ``` Use logging only when it provides meaningful debugging value. --- ## Utility Classes Avoid creating generic utility classes such as: ``` GameUtils CommonHelper MathHelper ``` Prefer placing behavior in the domain object responsible for it. Example: Bad: ``` DamageHelper.CalculateDamage(...) ``` Good: ``` enemy.CalculateDamage(...) ``` --- ## Data Structures Avoid large context objects with many loosely related fields. Bad: ``` EffectContext { int value; int count; float rate; object source; object target; } ``` Prefer explicit parameters or strongly typed structures. --- ## Code Generation Rules for AI Before adding any of the following: * null check * range check * fallback default * try/catch * abstraction layer First determine: 1. Is this a boundary input? 2. Is the value optional by design? 3. Is there a real recovery strategy? If the answer is **no**, do not add defensive code. --- ## Preferred Coding Style Prefer: * simple classes * explicit logic * minimal indirection * clear ownership of behavior Avoid: * unnecessary patterns * speculative architecture * defensive boilerplate --- ## Guiding Principle Prefer: **clear failure over hidden corruption** A bug should surface near its source rather than being silently ignored.