mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 06:45:33 +00:00
11 KiB
11 KiB
CLAUDE.md - AI Assistant Guidelines for Godot 4 C# Development
File Creation Guidelines
Files AI CAN Create/Edit
.csfiles - All C# script files (preferred for game logic).tscnfiles - Scene files with basic/logical structure.cfgfiles - Configuration files (like .ini format)
Files AI Should Create WITH CAUTION
.gdfiles - Only for EditorScript tools (preferred over C# for editor extensions).tresfiles - Simple resources CAN be created as text:
BUT: Complex resources with node references or nested resources are better created in editor[gd_resource type="Resource" script_class="Recipe" path="res://scripts/Recipe.cs"] id = "fire_water_steam" ingredients = ["fire", "water"] instability_cost = 20.0
Files AI Should RARELY Create
.jsonfiles - Only for external data exchange or modding support- Use
.tresfor all game data instead (type-safe, Inspector-editable)
- Use
.mdfiles - Documentation files, only when specifically requested
Files AI Should NOT Create
.importfiles - Godot manages these automaticallyproject.godot- Only modify through Project Settings UI.gdshaderfiles - Visual shader editing is more efficient- Binary files - Images, sounds, models, etc.
Scene File (.tscn) Guidelines
AI CAN Generate in .tscn
# Basic node structure
[node name="Player" type="CharacterBody2D"]
unique_name_in_owner = true
script = ExtResource("1")
# Node hierarchy
[node name="Sprite2D" type="Sprite2D" parent="."]
# Signal connections
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
# Simple collision shapes
[sub_resource type="RectangleShape2D" id="1"]
size = Vector2(32, 32)
Human Handles in Editor
- Sprite textures and animations
- Precise collision shape adjustments
- Animation tracks in AnimationPlayer
- Particle system parameters
- Complex UI layouts with exact positioning
- Tilemap painting
- Navigation mesh baking
- Audio bus assignments
Division of Labor
AI Handles (Logic & Structure)
- Game logic and systems in C#
- Node hierarchy structure
- Script functionality
- Basic scene composition
- Export variable definitions
- Signal method implementations
- Resource class definitions
Human Handles (Visual & Feel)
- Sprite assignment and animation
- Collision shape fine-tuning
- Visual effects and particles
- UI precise positioning
- Audio integration
- Testing game feel
- Input mapping
C# Code Best Practices
Node References
// GOOD - Unique names (set in .tscn with unique_name_in_owner = true)
private Node player;
public override void _Ready()
{
player = GetNode("%Player");
}
// GOOD - Relative paths for direct children
private Sprite2D sprite;
public override void _Ready()
{
sprite = GetNode<Sprite2D>("Sprite2D");
}
// AVOID - Fragile absolute paths
var player = GetNode("/root/Main/World/Player");
Signals
// For static connections (nodes in same scene):
// AI provides the method, human connects in editor OR AI adds to .tscn
private void _OnButtonPressed()
{
GD.Print("Button pressed!");
}
// For dynamic connections (runtime created nodes):
// AI writes the connection code
public override void _Ready()
{
if (!enemy.Died.IsConnected(Callable.From(_OnEnemyDied)))
{
enemy.Died.Connect(Callable.From(_OnEnemyDied));
}
}
Export Variables
// AI defines them with sensible defaults
[Export] public float MoveSpeed { get; set; } = 300.0f; // Human tweaks in Inspector
[Export] public PackedScene EnemyScene { get; set; } // Human assigns in Inspector
// Group related exports
[ExportGroup("Movement")]
[Export] public float Speed { get; set; } = 100.0f;
[Export] public float Acceleration { get; set; } = 10.0f;
Scene Instantiation
// Always check if assigned
[Export] public PackedScene ProjectileScene { get; set; }
private void Shoot()
{
if (ProjectileScene == null)
{
GD.PrintErr("ProjectileScene not assigned in Inspector");
return;
}
var bullet = ProjectileScene.Instantiate();
}
Standard C# Code Structure
using Godot;
public partial class Player : CharacterBody2D
{
// Signals
[Signal] public delegate void HealthChangedEventHandler(int newValue);
// Constants
private const float MaxSpeed = 400.0f;
// Export variables
[ExportGroup("Combat")]
[Export] public int Damage { get; set; } = 10;
[Export] public float AttackRate { get; set; } = 1.0f;
// Private variables
private string _currentState = "idle";
private Vector2 _velocity = Vector2.Zero;
// Node references (initialized in _Ready)
private Sprite2D _sprite;
private Control _healthBar;
// Godot callbacks
public override void _Ready()
{
_sprite = GetNode<Sprite2D>("Sprite2D");
_healthBar = GetNode<Control>("%HealthBar"); // Unique name
}
public override void _PhysicsProcess(double delta)
{
// Physics logic
}
// Public methods
public void TakeDamage(int amount)
{
// Implementation
}
// Private methods
private void UpdateHealthBar()
{
// Implementation
}
// Signal callbacks
private void _OnAreaEntered(Area2D area)
{
// Implementation
}
}
Resource Creation
// AI provides the Resource class definition
using Godot;
[GlobalClass]
public partial class Recipe : Resource
{
[Export] public string Id { get; set; } = "";
[Export] public string[] Ingredients { get; set; } = Array.Empty<string>();
[Export] public float InstabilityCost { get; set; } = 0.0f;
}
// Human creates instances: Right-click > Create Resource > Recipe
Testing & Debug Helpers
// Always include debug capability
[Export] public bool DebugMode { get; set; } = false;
// Debug methods
public override void _Ready()
{
if (DebugMode)
{
GD.Print($"[{Name}] Ready with speed: {MoveSpeed}");
}
}
// Unit test methods (can be called from debugger or test scenes)
public static float TestBrewingTiming()
{
float totalTime = 0.4f * 3 + 0.8f; // 3 ingredients + set time
System.Diagnostics.Debug.Assert(totalTime < 2.5f, "Brewing too slow!");
return totalTime;
}
Common C# Patterns
Object Pooling Setup
// AI provides the structure, human assigns the scene
[Export] public PackedScene PooledScene { get; set; } // Assign in Inspector
private readonly Queue<Node> _pool = new();
private Node GetInstance()
{
if (_pool.Count == 0)
return PooledScene.Instantiate();
return _pool.Dequeue();
}
State Machine
public enum State { Idle, Moving, Attacking }
private State _currentState = State.Idle;
private void TransitionTo(State newState)
{
_currentState = newState;
switch (newState)
{
case State.Idle:
_animationPlayer.Play("idle");
break;
case State.Moving:
_animationPlayer.Play("run");
break;
}
}
Instructions for Humans
When AI generates code/scenes, it should include clear TODO comments:
// TODO: In Godot Editor:
// 1. Assign EnemyScene in Inspector (drag Enemy.tscn)
// 2. Set up collision shape (Circle, radius ~16)
// 3. Add sprite texture
// 4. Connect hurt_box's area_entered signal
What to Avoid
DON'T
- Hardcode paths to scenes (use [Export])
- Create complex AnimationPlayer tracks in code
- Generate particle system parameters in code
- Edit .import files
- Assume node paths without proper initialization
- Use old Godot 3 syntax or GDScript patterns in C#
- Create collision polygons via code arrays
- Modify project.godot directly
- Create .gd files for game logic (use C# instead)
- Create documentation files unless specifically requested
- Use esotheric powershell one-liners for file manipulation (use the available tools or ask the user instead)
DO
- Use [Export] for all scene references
- Use % for unique named nodes with GetNode
- Include debug helpers
- Check for null before using nodes
- Use proper C# naming conventions (PascalCase for public, camelCase for private)
- Provide fallbacks and error messages
- Keep visual things in the editor
- Use C# for all game logic and scripts
File Organization Example
/project
├── /Scripts # All C# scripts organized by category
│ ├── /Resources # Resource class definitions (AI creates these)
│ │ └── Recipe.cs
│ ├── /Player # Player-related scripts
│ │ └── PlayerController.cs
│ ├── /Enemies # Enemy-related scripts
│ │ └── EnemyAI.cs
│ ├── GameManager.cs # Global scripts at root level
│ └── EventBus.cs
├── /Scenes # Mix of AI and human work, organized by category
│ ├── /Player # Player-related scenes
│ │ └── Player.tscn # AI creates structure, human adds visuals
│ ├── /Enemies # Enemy-related scenes
│ │ └── Enemy.tscn
│ └── /UI # UI scenes
│ └── MainMenu.tscn
├── /Resources # .tres resource files organized by category
│ ├── /Recipes # Based on AI's Resource classes
│ │ └── FireWaterSteam.tres
│ └── /Items # Item resources
│ └── Sword.tres
├── /Shaders # Shader files
│ ├── Water.gdshader
│ └── Fire.gdshader
└── /Sprites # Human manages visual assets
├── /Player
└── /Enemies
C# Specific Guidelines
Naming Conventions
- Classes: PascalCase (
PlayerController) - Public properties/methods: PascalCase (
MoveSpeed,TakeDamage()) - Private fields: _camelCase (
_currentHealth,_velocity) - Constants: PascalCase (
MaxHealth) - Enums: PascalCase (
PlayerState.Moving)
Property Usage
// Prefer properties over fields for exports
[Export] public float Speed { get; set; } = 100.0f;
// Use private fields for internal state
private float _currentSpeed;
Null Safety
// Always check exported scenes/nodes
if (ProjectileScene != null)
{
var projectile = ProjectileScene.Instantiate<Projectile>();
// Use the projectile
}
Project-Specific Notes
For Your game:
Summary
- AI handles: Logic, structure, systems in C#
- Human handles: Visuals, feel, precise adjustments
- .tscn files are human-readable and AI can generate them
- Always use [Export] and Inspector for scene/resource references
- Use C# for all game logic, GDScript only for EditorScript tools
- Include debug modes and clear TODOs
- Test core mechanics with static methods
- Avoid creating documentation unless requested