godot-csharp
gamedev-skills/awesome-gamedev-agent-skills
Write Godot 4.7 game code in C# with type-safe nodes, signals as events, and GDScript interop.
What is godot-csharp?
Use C# and .NET 8 to script Godot 4.7 games with partial node classes, PascalCase lifecycle methods, [Export] fields, and [Signal] delegates. Install when you need to write game logic in C# instead of GDScript, convert GDScript patterns to C#, or integrate C# with existing GDScript nodes.
- Override Godot lifecycle methods (_Ready, _Process, _PhysicsProcess) in PascalCase with type-safe signatures
- Expose Inspector-editable fields using [Export] attributes
- Declare and emit signals as C# events with [Signal] delegates and type-safe SignalName constants
- Use GetNode<T>("Path") for type-safe node lookup and casting
- Instance PackedScene objects with typed Instantiate<T>() calls
- Call GDScript methods and access properties dynamically via Call/Get/Set for interop
How to install godot-csharp
npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-csharp- Godot 4.7 .NET build (not the standard build)
- The .NET 8 SDK installed and matching your Godot version
- A Godot project with C# enabled (creates .csproj/.sln on first C# script)
How to use godot-csharp
- 1.Install the Godot 4.7 .NET editor build and .NET 8 SDK for your platform
- 2.Create a new C# script in the Godot editor, which auto-generates the .csproj and .sln files
- 3.Write node classes as `public partial class YourNode : NodeType` extending the appropriate Godot node type
- 4.Override lifecycle methods in PascalCase: _Ready(), _Process(double delta), _PhysicsProcess(double delta)
- 5.Use [Export] public fields for Inspector-editable parameters and [Signal] public delegates for events
- 6.Call GetNode<T>("NodePath") to retrieve child nodes with type safety, or use % for unique names
- 7.Build with `dotnet build` or the Godot editor, then run the game to test
Use cases
- Writing a complete game in C# with Godot's .NET build instead of GDScript
- Converting an existing GDScript project to C# for better IDE support and type safety
- Building a player controller with [Export] speed/jump parameters editable in the Inspector
- Wiring game events (health changes, score updates) as C# events between nodes
- Spawning bullets or enemies from a C# spawner that loads and instances PackedScene files
- C# developers new to Godot who want to use their primary language
- Game developers migrating from Unity to Godot
- Teams preferring static typing and IDE tooling over GDScript's dynamic approach
- Projects mixing C# and GDScript that need interop patterns
godot-csharp FAQ
You must use the Godot 4.7 .NET build; the standard build cannot execute C# scripts. If you try to use C# with the standard build, you will get build errors.
Your class must be declared `partial` so the Godot source generator can extend it. Without `partial`, the generator cannot inject the required code and you will see confusing build errors.
Use PascalCase names (_Ready, _Process, _PhysicsProcess) with the exact signature: _Process and _PhysicsProcess take a `double delta` parameter, not `float`. Mismatched names or signatures will not be called.
Use `GetNode("path").Connect("signal_name", Callable.From(MyMethod))` to dynamically connect to GDScript signals, or call GDScript methods with `GetNode("path").Call("method_name", args)`.
No; Vector2, Color, Transform2D, and other Godot structs are value types. You must assign to a local copy, modify it, then reassign: `var v = Velocity; v.X = 10; Velocity = v;`
Full instructions (SKILL.md)
Source of truth, from gamedev-skills/awesome-gamedev-agent-skills.
name: godot-csharp description: > Use C#/.NET in Godot 4.7: partial classes extending nodes, the PascalCase lifecycle (_Ready/_Process/_PhysicsProcess), [Export] fields, [Signal] delegates as C# events, type-safe node lookup, and calling between C# and GDScript. Use when writing Godot game code in C# (.cs files, .csproj), needing the Godot .NET build, converting GDScript patterns to C#, or wiring Godot signals as C# events.
Godot C# / .NET (4.x)
Write Godot game code in C#: node subclasses, the engine lifecycle, exports, signals as events, and GDScript interop. Targets Godot 4.7 (.NET / C#) and .NET 8.
When to use
- Use when scripting a Godot game in C# (
.cs+.csproj), translating GDScript idioms to C#, exposing[Export]fields, or wiring[Signal]delegates and GetNode<T>.
When not to use: GDScript-specific syntax → godot-gdscript; engine concepts that
are language-neutral (scenes, physics, animation) → the relevant godot-* skill. You need
the Godot .NET build + the .NET SDK installed; the standard build can't run C#.
Core workflow
- Use the Godot .NET editor build and install the matching .NET 8 SDK. Creating the first C#
script generates a
.csproj/.sln. Build with the editor ordotnet build. - Every node script is a
partialclass extending a Godot type (the source generator relies onpartial). The file/class name should match the node script. - Override lifecycle methods in PascalCase with
doubledelta:_Ready(),_Process(double delta),_PhysicsProcess(double delta). - Expose tunables with
[Export]; they show in the Inspector like GDScript@export. - Declare signals as
[Signal]delegates namedXxxEventHandler; emit withEmitSignal(SignalName.Xxx, ...)and subscribe with the generated C#event. - Get nodes with
GetNode<T>("Path")(or%Unique), and call into GDScript withCall/Get/Setwhen needed.
Patterns
1. A node script: lifecycle, [Export], GetNode<T>
using Godot;
public partial class Player : CharacterBody2D
{
[Export] public float Speed = 200.0f; // editable in the Inspector
[Export] public float JumpVelocity = -400.0f;
private const float Gravity = 1200.0f;
private AnimatedSprite2D _sprite;
public override void _Ready()
{
_sprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
}
public override void _PhysicsProcess(double delta)
{
Vector2 v = Velocity; // Velocity is a property here
if (!IsOnFloor())
v.Y += Gravity * (float)delta; // delta is double; cast for float math
if (Input.IsActionJustPressed("jump") && IsOnFloor())
v.Y = JumpVelocity;
float dir = Input.GetAxis("move_left", "move_right");
v.X = dir != 0 ? dir * Speed : Mathf.MoveToward(v.X, 0, Speed);
Velocity = v;
MoveAndSlide(); // no args, like GDScript 4.x
}
}
2. Signals as C# events
using Godot;
public partial class Health : Node
{
// Delegate name MUST end with "EventHandler"; generator creates the event + SignalName.
[Signal] public delegate void HealthChangedEventHandler(int current, int max);
private int _hp = 100;
public void TakeDamage(int amount)
{
_hp = Mathf.Max(_hp - amount, 0);
EmitSignal(SignalName.HealthChanged, _hp, 100); // type-safe signal name
}
public override void _Ready()
{
HealthChanged += OnHealthChanged; // subscribe like a normal C# event
}
private void OnHealthChanged(int current, int max) => GD.Print($"HP {current}/{max}");
}
3. Instancing a scene in C#
public partial class Spawner : Node2D
{
// Load once; PackedScene is the C# equivalent of preload's result.
private readonly PackedScene _bullet = GD.Load<PackedScene>("res://bullet.tscn");
public void Shoot(Vector2 at)
{
var b = _bullet.Instantiate<Node2D>(); // typed instantiate
b.GlobalPosition = at;
AddChild(b);
}
}
4. Interop with GDScript nodes
public override void _Ready()
{
Node gd = GetNode("GDScriptNode");
// Call a GDScript method and read/write its properties dynamically.
gd.Call("take_damage", 10);
int score = (int)gd.Get("score");
gd.Set("score", score + 5);
// Connect to a GDScript signal by name:
gd.Connect("died", Callable.From(OnDied));
}
private void OnDied() => GD.Print("entity died");
Pitfalls
- Forgetting
partial. Withoutpartial, the Godot source generator can't extend the class and[Export]/[Signal]break with confusing build errors. - Wrong method case/signature. C# overrides are
_Ready,_Process(double),_PhysicsProcess(double)— PascalCase anddoubledelta (GDScript uses snake_case andfloat). A mismatched name just won't be called. [Signal]delegate naming. It must end withEventHandler; the engine exposes the signal as the name without that suffix and generatesSignalName.Xand a C#event.GD.PrintvsConsole.WriteLine. UseGD.Print/GD.PrintErrto reach the Godot output panel;Consoleoutput may not appear.- Value-type structs.
Vector2,Color,Transform2Dare structs — mutate a local copy (var v = Velocity; v.X = ...; Velocity = v;); editingVelocity.Xdirectly won't compile/persist. - Needs the .NET build + SDK. The non-.NET editor can't run C#; mismatched/missing .NET SDK causes build failures. Godot 4.7 targets .NET 8; check current platform export notes because Android and other AOT targets can require newer SDK tooling.
QueueFree()vsFree()— same rules as GDScript; preferQueueFree(). Disposed objects throwObjectDisposedExceptionif used after freeing.- Export to some platforms differs for .NET (e.g. extra steps for web/mobile); check the .NET export notes for your target.
References
- For export attribute variants (
[ExportGroup], ranges, typed arrays), async withawait ToSignal(...),Godot.Collectionsvs System collections, custom Resources in C#, and project/build setup, readreferences/csharp-setup-and-interop.md.
Related skills
godot-gdscript— the GDScript equivalents of these patterns.godot-signals-groups— signal/event architecture (language-neutral).godot-resources— data resources; the C#[Export]+Resourcepattern.unity-csharp-scripting— C# in Unity, for developers coming from there.
Related skills
More from gamedev-skills/awesome-gamedev-agent-skills and the wider catalog.

godot-export
Export and build Godot 4.x projects for Windows, macOS, Linux, Web, Android, and headless servers.

godot-gdscript
Write idiomatic GDScript 2.0 for Godot 4.7 with static typing, lifecycle callbacks, and signals.

godot-multiplayer
Build networked Godot 4.7 games with ENet, RPCs, and state replication.

godot-nodes-scenes
Structure Godot 4.x games with scenes, nodes, and runtime instancing.

godot-physics
Configure Godot 4.x physics bodies, collision layers/masks, overlap detection, and raycasts in 2D and 3D.

godot-resources
Design data-driven Godot 4.7 games with custom Resource classes and .tres/.res files.