- 添加 _Core/components/ 和 _Core/utils/ 目录 - 重新组织 scenes/ 目录结构,按功能分类 - 迁移 StringUtils.gd 到新的 _Core/utils/ 位置 - 迁移 AuthScene.gd 到新的 scenes/ui/ 位置 - 添加 AI 文档支持目录 docs/AI_docs/ - 添加开发参考文档 claude.md
4.2 KiB
🎯 CLAUDE.md - WhaleTown Project Instructions
1. Project Vision & Context
- Project: "WhaleTown" - A 2D top-down pixel art RPG.
- Engine: Godot 4.2+ (Strictly NO Godot 3.x syntax).
- Architecture: Strictly layered:
_Core(Framework),Scenes(Gameplay),UI(Interface). - Core Principle: "Signal Up, Call Down". High decoupling via
EventSystem.
2. 🛠 Command Reference & Setup
- Input Map (Required Configuration):
move_left,move_right,move_up,move_down(WASD / Arrows)interact(E Key / Space)pause(ESC)
- Run Game:
godot --path . - Run Tests (GUT):
godot --headless -s addons/gut/gut_cmdline.gd -gdir=res://tests/ -ginclude_subdirs - Init Structure:
mkdir -p _Core/managers _Core/systems Scenes/Maps Scenes/Entities Scenes/Components UI/Windows UI/HUD Assets/Sprites tests/unit tests/integration
3. 📂 File Path Rules (STRICT LOWERCASE)
Claude: Root folders MUST be lowercase. Scripts and Scenes MUST stay together.
- Core Managers:
_Core/managers/[Name].gd - Core Systems:
_Core/systems/[Name].gd - Entities:
Scenes/Entities/[EntityName]/[EntityName].tscn(Script.gdin same folder). - Maps:
Scenes/Maps/[map_name].tscn - Components:
Scenes/Components/[ComponentName].gd(Reusable logic nodes). - UI Windows:
UI/Windows/[WindowName].tscn - Tests:
tests/[unit|integration]/test_[name].gd(Folder is lowercasetests).
4. 📋 Coding Standards (The Law)
- Type Safety: ALWAYS use strict static typing:
var speed: float = 100.0,func _ready() -> void. - Naming Conventions:
class_name PascalCaseat the top of every script.- Variables/Functions:
snake_case. Constants:SCREAMING_SNAKE_CASE. - Private members: Prefix with underscore
_(e.g.,var _health: int).
- Node Access: Use
%UniqueNamefor UI and internal scene components. - Signals: Use "Signal Up, Call Down". Parent calls child methods; Child emits signals.
- Forbidden Patterns:
- ❌ NO
yield()-> Useawait. - ❌ NO
get_node()in_process-> Cache with@onready. - ❌ NO Linear Filter -> All Sprite2D/TileMap resources MUST use Nearest filter.
- ❌ NO
5. 🏛 Architecture & Communication
- EventSystem: Use
_Core/systems/EventSystem.gdfor cross-module messaging. - Event Registry: Use
class_name EventNamesin_Core/EventNames.gd.class_name EventNames const PLAYER_MOVED = "player_moved" const INTERACT_PRESSED = "interact_pressed" const NPC_TALKED = "npc_talked"
Singletons: Only GameManager, SceneManager, EventSystem allowed as Autoloads. Decoupling: Low-level entities MUST NOT reference GameManager. Use events. 6. 🏗 Implementation Details Player: CharacterBody2D. Must include Camera2D with position_smoothing_enabled = true. NPC/Interactables: Use Area2D named InteractionArea. Trigger via EventSystem. TileMap Layers: Layer 0: Ground (No collision). Layer 1: Obstacles (Physics Layer enabled). Layer 2: Decoration (Y-Sort enabled). Camera: Must auto-calculate limits via TileMap.get_used_rect(). 7. 🧪 Testing Requirements (MANDATORY) Coverage: Every Manager/System in Core/ MUST have a GUT test. Naming: Test files must start with test and extend GutTest. Example: code Gdscript extends GutTest func test_event_emission(): var sender = Node.new() watch_signals(EventSystem) EventSystem.emit_event(EventNames.PLAYER_MOVED, {}) assert_signal_emitted(EventSystem, "event_raised") 8. 🧘 The Zen of Development Juice or Death: Every interaction (UI popup, NPC talk) MUST have a Tween placeholder. Zero Magic Numbers: All speeds/timers MUST be @export or defined in Config/. Simplicity: If a function does two things, split it. Back of the Fence: Hidden logic (like ResponseHandler.gd) must be as clean as the HUD. 9. 📝 Code Template (Entity Pattern) code Gdscript extends CharacterBody2D class_name Player
1. Exports & Constants
@export var move_speed: float = 200.0
2. Node References
@onready var sprite: Sprite2D = %Sprite2D
3. Lifecycle
func _physics_process(delta: float) -> void: _move(delta)
4. Private Methods
func _move(_delta: float) -> void: var dir := Input.get_vector("move_left", "move_right", "move_up", "move_down") velocity = dir * move_speed move_and_slide()