neon-sprawl/.cursor/rules/godot-client-script-organiz...

39 lines
2.1 KiB
Markdown

---
description: Godot client — keep main.gd thin; split scripts by concern (Neon Sprawl).
globs: "client/**/*.gd"
alwaysApply: false
---
# Godot client script organization (Neon Sprawl)
Avoid a single **monolithic `main.gd`**. Treat the main scene root as a **composer**: wire nodes, `@export` references, and signals—not every subsystem.
## Where logic lives
- **`main.gd` (scene root):** Bootstrapping only—attach children, connect signals, optional high-level toggles. If a block grows past ~50 lines or a clear concern appears, **extract** it.
- **Avatar / props:** Keep behavior on the node that owns it (e.g. `player.gd` on `CharacterBody3D`).
- **Cross-cutting features:** Prefer a **child `Node`** (or `Node3D`) with its own script, e.g. ground picking → `ground_pick.gd`, server HTTP sync → `position_authority_client.gd`. Use **signals** or small public methods so `main` does not call into deep implementation details.
## `class_name` vs headless / CI
**`class_name`** registers global types only after Godot has imported the project (`.godot/`). That folder is **gitignored** here, so **`godot --headless --path client`** on a fresh clone **fails** if `main.gd` annotates types with `class_name` aliases. Prefer **`Node` / `Node3D` + `connect("signal", …)`** and **`call("method", …)`** for thin composition from the scene root unless the project guarantees a prior editor import.
## Autoloads
Use **sparingly** (e.g. shared config many scenes need). Default to **scene-local nodes** until duplication proves an autoload.
## Granularity
- **One obvious concern per script** (picking vs network vs locomotion)—not one file per tiny helper.
- **New work:** add `res://scripts/<feature>.gd` (or a subfolder when a feature set grows) rather than extending `main.gd` by default.
## Examples
```text
✅ main.gd: _ready() → get_node, connect ground_pick.target_selected to _on_target
✅ ground_pick.gd: raycast + walkable check → emit target_selected(Vector3)
❌ main.gd: 300 lines of HTTP + ray math + player tuning in one file
```
Aligns with [GDScript style](gdscript-style.md) (small virtual overrides, extract `_` helpers).