Skip to content
Development
Skill

/csharp-godot

Use when working with C# in Godot — conventions, GodotSharp API differences from GDScript, project setup, and interop

From plugin
godot-prompter
90361 skills9 agents1 hook

Claude Code

$ npx -y skills add jame581/GodotPrompter --skill csharp-godot --agent claude-code

SKILL.md

csharp-godot.SKILL.md
name: csharp-godot
description: Use when working with C# in Godot — conventions, GodotSharp API differences from GDScript, project setup, and interop

C# in Godot 4.3+

This skill covers C#-specific conventions, API differences from GDScript, project setup, and interop patterns. All examples are C# only. Target Godot 4.3+ with the GodotSharp NuGet package.

> **Related skills:** **csharp-signals** for C# signal patterns, **godot-project-setup** for C# project scaffolding, **godot-testing** for C# testing with gdUnit4, **gdextension** for native C++ when C# is not enough, **multithreading** for C# concurrency.

---

1. C# vs GDScript Syntax Comparison

| GDScript | C# Equivalent | Notes | |---|---|---| | `var x = 5` | `var x = 5;` or typed `int x = 5;` | C# `var` infers type at compile time | | `func MyMethod() -> void:` | `public void MyMethod() { }` | Methods are PascalCase in C# | | `signal health_changed(amount: int)` | `[Signal] delegate void HealthChangedEventHandler(int amount);` | Must use `EventHandler` suffix | | `@export var speed: float = 100.0` | `[Export] public float Speed { get; set; } = 100f;` | PascalCase, property syntax | | `@onready var label = $Label` | `private Label _label;` + `_label = GetNode<Label>("Label");` in `_Ready()` | No `@onready` equivalent; use `_Ready()` | | `match value:` | `switch (value) { case X: break; }` | C# switch also supports pattern matching | | `class_name MyClass` | `[GlobalClass] public partial class MyClass : GodotObject { }` | Requires `[GlobalClass]` attribute | | `extends Node` | `public partial class MyScript : Node { }` | Inheritance via `:` | | `preload("res://scene.tscn")` | `GD.Load<PackedScene>("res://scene.tscn")` | Loaded at runtime, not compile time | | `push_error("msg")` | `GD.PushError("msg");` | Prints to Godot error log | | `print("msg")` | `GD.Print("msg");` | Also: `GD.PrintS()`, `GD.PrintT()` | | `node is CharacterBody2D` | `node is CharacterBody2D` | Same keyword, same semantics | | `node as CharacterBody2D` | `node as CharacterBody2D` | Returns `null` on failure in both | | `await signal_name` | `await ToSignal(source, SignalName.X);` | Must use `ToSignal()` wrapper | | `Array` | `Godot.Collections.Array` | Not `System.Collections.Generic.List<T>` | | `Dictionary` | `Godot.Collections.Dictionary` | Not `System.Collections.Generic.Dictionary<K,V>` |

---

2. Project Setup

.csproj and Solution

Godot auto-generates the `.csproj` when you create the first C# script via **Script > New Script > C#**. Do not edit the generated file structure manually — let the editor manage it.

MyProject/
├── MyProject.csproj          # Auto-generated, edit only for NuGet packages
├── MyProject.sln             # Auto-generated solution file
├── project.godot
└── scripts/
    └── Player.cs

NuGet Packages

Add packages in `MyProject.csproj` inside `<ItemGroup>`:

<Project Sdk="Godot.NET.Sdk/4.3.0">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>
  <ItemGroup>
    <!-- Example: add a third-party NuGet package -->
    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
  </ItemGroup>
</Project>

Run `dotnet restore` or let the IDE restore automatically after editing.

Godot.NET Preview Bindings (Godot 4.7+)

Godot 4.7's `Godot.NET.Sdk` accepts an opt-in MSBuild property that switches the project from the classic GodotSharp bindings to the preview Godot.NET bindings (the `Godot.Bindings` assembly instead of `GodotSharp`):

<PropertyGroup>
  <EnableGodotDotNetPreview>true</EnableGodotDotNetPreview>
</PropertyGroup>

The preview bindings are experimental — leave the property unset for production projects. See [GH-118001](https://github.com/godotengine/godot/pull/118001).

IDE Setup

| IDE | Setup Required | Notes | |---|---|---| | JetBrains Rider | Install Godot plugin (bundled in Rider 2023.3+) | Best Godot C# support; debugger works out of the box | | VS Code | Install **C# Dev Kit** + **Godot Tools** extensions | Requires `launch.json` for debugger attachment | | Visual Studio | Install **Godot Visual Studio** extension | Windows only; debugger via `Tools > Attach to Process` |

For all IDEs, open the `.sln` file (not just a folder) to get full solution resolution.

---

3. The `partial class` Requirement

Every class that extends a Godot type **must** be declared `partial`. This is not optional.

Why

Godot uses C# source generators to emit the signal registration, property binding, and RPC code alongside your class. Source generators require `partial` to inject into the same class declaration.

Error When Forgotten

error GD0001: Missing partial modifier on declaration of type 'Player'
that derives from 'Godot.GodotObject'

The build fails, so a missing `partial` cannot slip through.

Rule

// CORRECT
public partial class Player : CharacterBody2D { }

// WRONG — will cause source generator errors
public class Player : CharacterBody2D { }

This applies to every class in the inheritance chain that extends a Godot type, including intermediate base classes.

---

4. Naming Conventions

| Element | Convention | Example | |---|---|---| | Methods | PascalCase | `public void TakeDamage(int amount)` | | Properties | PascalCase | `public float MaxHealth { get; set; }` | | Signals (delegate) | PascalCase + `EventHandler` suffix | `HealthChangedEventHandler` | | `[Export]` properties | PascalCase | `[Export] public float Speed { get; set; }` | | Private fields | `_camelCase` with underscore prefix | `private float _currentSpeed;` | | Local variables | camelCase | `var newPosition = ...` | | Parameters | camelCase | `void SetHealth(int newHealth)` | | Godot API names | Match Godot's PascalCase exactly | `GlobalPosition` not `global_position` | | Enums | PascalCase type, PascalCase members | `enum State { Idle, Running, Dead

Read more
@jame581
Ships withgodot-prompter

Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.

90361 skills9 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
903
Star history of jame581/GodotPrompter on GitHub, a chart by star-history.com

Other skills on godot-prompter.

2d-essentials

2d-essentials

Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D,…

3d-essentials

3d-essentials

Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion…

ability-system

ability-system

Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc11d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about csharp-godot.

Which coding agents can use csharp-godot?
csharp-godot installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.