diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..cceecec --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,77 @@ +# Claude Code Rules - Godot 4.x Town Project + +## Project Overview +A 2D top-down pixel art RPG built in Godot 4.x using a layered architecture. +- **Core**: `_Core/` (SceneManager, EventSystem, GameManager) +- **Gameplay**: `Scenes/` (Maps, Entities, Components) +- **UI**: `UI/` (Windows, Overlays) + +## Coding Standards (GDScript) +- **Type Safety**: Use static typing strictly (e.g., `var speed: float = 100.0`, `func _ready() -> void`). +- **Naming Conventions**: + - Classes: `PascalCase` (using `class_name`). + - Variables/Functions: `snake_case`. + - Constants: `SCREAMING_SNAKE_CASE`. + - Signals: `snake_case` (e.g., `signal player_interacted(data)`). +- **Node Access**: Use `@onready var name = $Path` or `%UniqueName`. Prefer `%UniqueName` for UI and internal scene components. +- **Best Practices**: + - Use `await` for signals and timers instead of `yield`. + - Use `Callable` for callbacks. + - Follow the "Signal Up, Call Down" rule: Parent calls methods on children; children emit signals to parents. + - Use `Input.get_vector("left", "right", "up", "down")` for 2D movement. + +## Project Architecture Rules +- **Decoupling**: Never reference singleton managers directly in low-level entities. Use `EventSystem` to communicate across modules. +- **Scene Management**: All scene transitions must go through `SceneManager.change_scene(scene_key)`. +- **Components**: Logic like "Health", "Interactions", or "Movement" should be encapsulated in `Scenes/Components/` as reusable nodes. + +## Implementation Specifics (Town Map) + +### 1. Entity Structure +- **Player**: Must be a `CharacterBody2D`. Include a `Camera2D` with `position_smoothing_enabled = true`. +- **NPC**: Must be a `StaticBody2D` or `CharacterBody2D` with an `Area2D` named `InteractionArea`. +- **Interactables**: Use a shared `InteractableComponent` (Area2D based) for building entrances and NPCs. + +### 2. Interaction System +- NPC/Entrance interaction must trigger via `EventSystem`. +- Interaction logic: + 1. Player enters `InteractionArea`. + 2. Player presses "E" or "UI_Accept". + 3. Emit `EventSystem.notify_interaction_triggered(interactable_data)`. + +### 3. TileMap Rules +- Use `TileMap` (or `TileMapLayer` if Godot 4.3+). +- Layer 0: Ground (No collision). +- Layer 1: Obstacles/Walls (With Physics Layer collision). +- Layer 2: Decorations (Y-Sort enabled). + +## File Organization +- New maps: `Scenes/Maps/[map_name].tscn` +- New entities: `Scenes/Entities/[entity_name]/[entity_name].tscn` +- New scripts: Same folder as their scene files. +- Assets: Always reference assets from `res://Assets/Sprites/`. + +## Command Reference +- Build/Run: `godot --path .` +- Export (Linux): `godot --path . --export-release "Linux/X11"` + +## Testing Standards +- **Framework**: Use GUT (Godot Unit Test) for all tests. +- **Test Location**: All test scripts must be in `res://test/unit/` or `res://test/integration/`. +- **File Naming**: Test files must start with `test_` and end with `.gd` (e.g., `test_player_movement.gd`). +- **Class Structure**: Every test file must `extends GutTest`. +- **Requirements**: + - Every new core logic (in `_Core`) must have a corresponding unit test. + - Player movement and NPC interactions must have integration tests using `yield_for` or `await`. + - Use `assert_eq`, `assert_true`, and `assert_signal_emitted` for validations. + +## Commands +- **Run all tests**: `godot --headless -s addons/gut/gut_cmdline.gd -gdir=res://test/ -ginclude_subdirs` +- **Run specific test**: `godot --headless -s addons/gut/gut_cmdline.gd -gtest=res://test/unit/test_example.gd` + +## The Zen of Development (Pro Tips) +- **Simplicity is the ultimate sophistication**: If a function does two things, it's one thing too many. Split it. +- **The "Back of the Fence" Rule**: Even parts the player never sees (like the EventSystem logic) must be clean and beautiful. No "quick hacks". +- **Feedback Loop**: Every interaction MUST have a placeholder for juice (Tween, Sound, or Particle). Code is the skeleton, but juice is the soul. +- **Zero Hard-Coding**: All paths, configuration values, and magic numbers must be defined as constants or @export variables. +- **The "It Just Works" Camera**: Camera logic must automatically find TileMap limits. The player should never see the "gray void" outside the map. \ No newline at end of file