Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
The English summary is being prepared. Showing the original description.
Use when a Godot project uses or considers C# (.NET) or native code - when C# is the right call and its export limits (no web export), C# node patterns with generated SignalName/StringName caching, plain C# rule libraries tested with dotnet test, and GDExtension (godot-cpp, godot-rust) pinning and build hygiene.
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
Godot runs GDScript, C# (.NET) and native code through GDExtension (C++ via godot-cpp, Rust via godot-rust, and others). Each has a cost: C# needs the .NET build of the editor and cannot export to the web; GDExtension needs a native build per target platform. The repository's existing choice wins; adding a second language is a decision, not a convenience.
Core principle: GDScript by default, C# where the project already is .NET or the team needs it and the web is not a target, GDExtension only for measured hot spots or native libraries.
| Need | Choice |
|---|---|
| Web export required | GDScript (C# web export is still unsupported in Godot 4.7) |
| Team is C#, heavy algorithms, .NET libraries | C# — on desktop and mobile targets |
| A measured hot loop GDScript cannot meet the budget with | GDExtension (C++ or Rust), or move it to C# if the project is .NET |
| Binding an existing native SDK | GDExtension |
Mixing GDScript and C# in one project works (cross-language calls go through Call, Get, signals), but keep one language per feature and a clear boundary.
using Godot;
public partial class Player : CharacterBody2D
{
[Signal] public delegate void HealthChangedEventHandler(int current, int maximum);
[Export] public PlayerDefinition Definition { get; set; }
static readonly StringName JumpAction = "jump";
static readonly StringName MoveLeft = "move_left";
static readonly StringName MoveRight = "move_right";
AnimatedSprite2D _sprite;
int _health;
public override void _Ready()
{
_sprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
_health = Definition.MaxHealth;
}
public override void _PhysicsProcess(double delta)
{
var v = Velocity;
v.X = Input.GetAxis(MoveLeft, MoveRight) * Definition.MoveSpeed;
if (IsOnFloor() && Input.IsActionJustPressed(JumpAction)) v.Y = -Definition.JumpSpeed;
v.Y += Definition.Gravity * (float)delta;
Velocity = v;
MoveAndSlide();
}
public void TakeDamage(int amount)
{
_health = Mathf.Max(0, _health - amount);
EmitSignal(SignalName.HealthChanged, _health, Definition.MaxHealth);
}
}
partial (source generators fill in the rest); the file name matches the class name.SignalName, PropertyName and MethodName members instead of string literals.StringNames. Passing a C# string to Input.IsActionPressed("jump") converts it to a StringName on every call — an allocation per frame per call.Godot.Collections.Array/Dictionary marshal on every access and belong only at the engine boundary (exports, signals)._Ready; never GetNode inside _Process.delta is a double in Godot 4 C#.Game.Core/ net8.0 class library — no Godot reference; rules, math, state machines
Game.Core.Tests/ xUnit or NUnit, references Game.Core
Game/ the Godot project (.csproj references Game.Core)
dotnet test Game.Core.Tests runs anywhere, with or without Godot installed (testable-game-logic). Engine-level C# tests go through gdUnit4Net (godot-testing).
; res://bin/pathfinding.gdextension
[configuration]
entry_symbol = "pathfinding_library_init"
compatibility_minimum = "4.7"
[libraries]
macos.debug = "res://bin/libpathfinding.macos.template_debug.framework"
macos.release = "res://bin/libpathfinding.macos.template_release.framework"
linux.debug.x86_64 = "res://bin/libpathfinding.linux.template_debug.x86_64.so"
windows.debug.x86_64 = "res://bin/pathfinding.windows.template_debug.x86_64.dll"
scons platform=macos target=template_debug) or the CMake setup the repository uses; register classes in the init function.godot crate version and its API feature to the project's Godot minor; cargo build; #[derive(GodotClass)] types appear as nodes..gdextension file and the source; commit built binaries only if the repository already does (otherwise CI builds them).cargo test) without the engine; test the binding from GDScript with gdUnit4.[libraries] means the feature silently fails on that platform — test the export for every target the task names, or say which you could not build..csproj appearing in a GDScript-only project, or GDScript files appearing in a C#-only one, for a task that did not ask for it.GetNode inside _Process / _PhysicsProcess..gdextension file with platforms listed whose binaries are not built anywhere.No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
The English summary is being prepared. Showing the original description.
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
The English summary is being prepared. Showing the original description.
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
The English summary is being prepared. Showing the original description.
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
The English summary is being prepared. Showing the original description.
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
The English summary is being prepared. Showing the original description.
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
The English summary is being prepared. Showing the original description.