GDScript vs C# — Skill Instruction Comparison banner
htdt htdt

GDScript vs C# — Skill Instruction Comparison

Development community intermediate

Description

GDScript vs C# — Skill Instruction Comparison skill

Installation

This entry records only its repository, not the path inside it, so there is no exact command to give. Open the source below and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

Repository README

This is the README for htdt/godogen, shared by 8 entries in this directory. It describes the repository, not this entry specifically.

GDScript vs C# — Skill Instruction Comparison

What C# eliminated

**GDScript's type inference minefield is gone.** The GDScript quirks.md had a 28-line "Type Inference Errors" section documenting `:=` footguns — `instantiate()` returns Variant, polymorphic math functions (`abs`, `clamp`, `lerp`, `min`, `max`...) return Variant, array/dict element access returns Variant. All of these silently break type inference with `:=`. This entire class of errors doesn't exist in C#.

Other GDScript-specific issues removed:

  • preload() vs load() ordering trap during generation
  • await during --write-movie advancing frame counter
  • @onready timing with init() vs _ready()
  • get_path() name collision with Node built-in
  • Pass-by-value workarounds needing Array accumulators (C# has ref/out and return values)

**task-execution.md shrank 14%** — the GDScript version needed `--check-only -s` per-file pre-validation step; C# replaces it with a single `dotnet build` that catches everything at once.

What C# added

**One major quirk: `SetScript()` disposes the C# managed wrapper.** After calling `SetScript()` on a node, the C# variable is dead (`ObjectDisposedException`). This requires a "temp parent" pattern to re-obtain root nodes. It's well-contained — 12 lines of example code — and once the pattern is in the template, it's never a problem in practice.

Other C#-specific additions:

  • .csproj file (5 lines of boilerplate, but one more file to manage)
  • dotnet build step in the pipeline (replaces per-file --check-only)
  • partial class requirement on every Godot class
  • Signal delegates must end in EventHandler
  • C# enum names are unreliable in LLM output (training data is predominantly GDScript) — explicit godot-api lookup instruction added

Code comparison: asset loading

The game logic is conceptually identical — same nodes, same hierarchy, same engine API. The difference is how much the language fights you while writing it.

# GDScript — three traps in four lines
var scene: PackedScene = load("res://assets/glb/car.glb")  # MUST type, or load() returns Resource
var model = scene.instantiate()                              # MUST use = not :=, Variant inference
var found = find_mesh_instance(model)                        # MUST use = not :=, recursive return
// C# — just works
var scene = GD.Load("res://assets/glb/car.glb");  // generic returns PackedScene
var model = scene.Instantiate();                                // type flows through
var found = FindMeshInstance(model);                            // same

GDScript requires remembering where `var x :=` is forbidden and where explicit typing is needed. C# generics and type inference handle this automatically. The actual game logic — physics, input, camera rigs, collision setup, node hierarchy — is 1:1 identical between the two. PascalCase instead of snake_case, `new Vector3()` instead of `Vector3()`, braces instead of indentat