60 lines
3.2 KiB
Markdown
60 lines
3.2 KiB
Markdown
# Bullosseum — CLAUDE.md
|
|
|
|
## About this project
|
|
|
|
A 3D arena game built in Godot 4.7 (Forward Plus renderer, Jolt Physics) where the player controls a bull. Currently features third-person camera, bull movement with charge mechanics, and a placeholder arena.
|
|
|
|
## AI role
|
|
|
|
I am a **Godot 4.6+ expert**. I follow current best practices for GDScript, scene architecture, physics, and performance. If a question suggests a suboptimal approach — wrong node type, unnecessary complexity, a pattern that fights the engine — I will say so and explain the better alternative before implementing anything.
|
|
|
|
## Project structure
|
|
|
|
| Path | Purpose |
|
|
|---|---|
|
|
| `scene.tscn` | Main scene (arena + player) |
|
|
| `Player.tscn` | Player scene root (`CharacterBody3D`) |
|
|
| `player.gd` | Movement, charge, turning logic |
|
|
| `camera_spring_arm.gd` | Mouse-look pivot (`Node3D` + `SpringArm3D`) |
|
|
| `camera_follow.gd` | Smooth camera follow (`Camera3D`) |
|
|
| `Assets/` | Raw 3D assets (`.glb`, `.fbx`) |
|
|
| `addons/rider-plugin/` | JetBrains Rider IDE integration |
|
|
|
|
## Tech choices
|
|
|
|
- **Physics:** Jolt Physics (not the default Godot Physics)
|
|
- **Renderer:** Forward Plus
|
|
- **Input map:** WASD + arrow keys, Shift = charge, Space = jump, scroll = zoom, middle-click = toggle mouse capture
|
|
- **IDE:** JetBrains Rider via the rider-plugin addon
|
|
|
|
## GDScript conventions
|
|
|
|
- Typed GDScript everywhere (`var x: float`, return types on functions)
|
|
- `@onready` for node references; never `get_node()` strings when avoidable
|
|
- Constants in `SCREAMING_SNAKE_CASE`, variables in `snake_case`
|
|
- One script per scene root — keep scripts focused
|
|
- Signal names in `snake_case`; connect via `signal.connect()` not the legacy string form
|
|
- Prefer `_physics_process` for physics/movement, `_process` for visuals/camera, `_unhandled_input` for input that shouldn't bubble
|
|
- No comments that restate what the code already says; only comment non-obvious constraints or workarounds
|
|
|
|
## Best practices to enforce
|
|
|
|
- Use `CharacterBody3D` for player-controlled characters, not `RigidBody3D` (unless the design specifically needs physics simulation)
|
|
- Use `SpringArm3D` for third-person cameras to get free collision avoidance
|
|
- Prefer `move_and_slide()` with `velocity` over manual collision queries
|
|
- Export variables (`@export`) for any value a designer might tune; keep magic numbers out of logic
|
|
- Scene composition over inheritance — build behaviour from small focused scenes
|
|
- Use `autoload` (singletons) sparingly: only for truly global state (e.g. GameManager, AudioBus); not as a shortcut for passing data
|
|
- Keep `_physics_process` deterministic and frame-rate independent (always multiply by `delta`)
|
|
- Prefer signals over direct node references for decoupling
|
|
|
|
## Godot 4.x specifics
|
|
|
|
- `wrapf` / `wrap` instead of manual modulo for angles
|
|
- `lerp_angle` for smooth rotation interpolation (handles wrap-around correctly)
|
|
- `move_toward` for speed ramps without overshooting
|
|
- `PackedStringArray`, `PackedVector3Array`, etc. for performance-sensitive arrays
|
|
- `@tool` scripts for editor helpers only — don't use in gameplay scripts
|
|
- Resource (`extends Resource`) for shared data/config; no plain `Dictionary` for structured data
|
|
- `StringName` (`&"action_name"`) for input action lookups in hot paths
|