---
description: Godot 4 C# conventions
globs: ["**/*.cs"]
alwaysApply: false
---

# Godot 4 (C#)

- Scripts are `public partial class Player : CharacterBody2D`. The class name must match the file name, and the class must be `partial`.
- Use Godot's lifecycle: `_Ready` for setup, `_Process(double delta)` for frame logic, `_PhysicsProcess` for movement and physics. Multiply by `delta`.
- Node references: `[Export]` fields assigned in the editor, or `GetNode<T>("%UniqueName")` cached in `_Ready`. Don't call `GetNode` every frame.
- Signals: declare with `[Signal] public delegate void HealthChangedEventHandler(int value);`, emit with `EmitSignal(SignalName.HealthChanged, hp)`. Prefer the generated `SignalName`/`MethodName` constants over strings.
- Unsubscribe C# `+=` event handlers in `_ExitTree` to avoid leaks and calls on freed objects.
- Use `Godot.Collections` only when crossing into the engine; use `System.Collections.Generic` inside C# logic.
- Avoid allocations in `_Process` (no LINQ, no `new` per frame). Check `IsInstanceValid` before touching nodes that may be freed.
- Free nodes with `QueueFree()`. Load resources with `GD.Load<T>` once, or preload in exports.
- Input via actions defined in Project Settings (`Input.IsActionPressed("jump")`), not raw keys.
- After adding exported properties or signals, rebuild (`dotnet build`) so the editor sees them.

## Don't
- Don't edit `.tscn`/`.tres` files by hand beyond simple property changes.

## Done when
`dotnet build` succeeds with no warnings, and the scene runs.
