GDScript to C# Migration Guide
GDScript to C# Migration Guide
This guide provides comprehensive mapping between GDScript classes and their C# equivalents in Grid Building 6.0.
π Class Mappings
Core System Classes
| GDScript Class | C# Class | Namespace | Notes |
|---|
PlaceableDefinition | Placeable | GridBuilding.Core.Types | Concrete implementation |
PlaceableDefinition | IPlaceable | GridBuilding.Core.Interfaces | Interface for Core layer |
PlaceableCollection | PlaceableCollection | GridBuilding.Core.Systems.Data | Same name, different namespace |
GridPosition | GridPosition | GridBuilding.Core.Grid | Same name, different namespace |
Vector2i | Vector2I | Godot | Built-in Godot type |
Data Structure Classes
| GDScript Class | C# Class | Namespace | Notes |
|---|
Dictionary | Dictionary<TKey, TValue> | System.Collections.Generic | Generic typing required |
Array | List<T> | System.Collections.Generic | Generic typing required |
Node | Node | Godot | Same name, Godot namespace |
π Syntax Differences
Variable Declarations
GDScript:
1
2
3
| var name: String = "Building"
var position: Vector2i = Vector2i(0, 0)
var properties: Dictionary = {}
|
C#:
1
2
3
| public string Name { get; set; } = "Building";
public Vector2I Position { get; set; } = new Vector2I(0, 0);
public Dictionary<string, object> Properties { get; set; } = new();
|
Function Declarations
GDScript:
1
2
3
4
5
| func get_placeable(id: String) -> PlaceableDefinition:
return placeables[id]
func add_placeable(placeable: PlaceableDefinition) -> void:
placeables[placeable.id] = placeable
|
C#:
1
2
3
4
5
6
7
8
9
| public IPlaceable? GetPlaceable(string id)
{
return _placeables.GetValueOrDefault(id);
}
public void AddPlaceable(IPlaceable placeable)
{
_placeables[placeable.Id] = placeable;
}
|
Class Definitions
GDScript:
1
2
3
4
5
6
7
8
9
| class_name PlaceableDefinition
extends Resource
@export var id: String
@export var name: String
@export var category: String
func _init():
pass
|
C#:
1
2
3
4
5
6
7
8
9
10
| namespace GridBuilding.Core.Types;
public class Placeable : IPlaceable
{
public string Id { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public Placeable() { }
}
|
π§ Type System Changes
Dynamic vs Static Typing
GDScript (Dynamic):
1
2
| var value = get_value() # Type inferred at runtime
value = "now a string" # Can change type
|
C# (Static):
1
2
3
4
| var value = GetValue(); // Type inferred at compile time
// value = "now a string"; // Compilation error - wrong type
object value = GetValue(); // Can use object for dynamic behavior
value = "now a string"; // But requires casting for specific operations
|
Null Safety
GDScript:
1
2
3
| var placeable: PlaceableDefinition = null
if placeable:
placeable.do_something()
|
C#:
1
2
3
4
5
6
7
8
| IPlaceable? placeable = null;
if (placeable != null)
{
placeable.DoSomething();
}
// Or with null-conditional operators:
placeable?.DoSomething();
|
ποΈ Common Migration Patterns
1. Properties vs @export
GDScript:
1
2
| @export var id: String
@export var size: Vector2i = Vector2i(1, 1)
|
C#:
1
2
3
4
5
6
| public string Id { get; set; } = string.Empty;
public Vector2I Size { get; set; } = new Vector2I(1, 1);
// For Godot-specific exports:
[Export] public string Id { get; set; } = string.Empty;
[Export] public Vector2I Size { get; set; } = new Vector2I(1, 1);
|
2. Signals vs Events
GDScript:
1
2
3
4
5
| signal placeable_added(placeable: PlaceableDefinition)
signal placeable_removed(id: String)
func emit_placeable_added(placeable):
emit_signal("placeable_added", placeable)
|
C#:
1
2
3
4
5
6
7
| public event Action<IPlaceable>? PlaceableAdded;
public event Action<string>? PlaceableRemoved;
private void EmitPlaceableAdded(IPlaceable placeable)
{
PlaceableAdded?.Invoke(placeable);
}
|
3. Dictionary Usage
GDScript:
1
2
3
4
5
6
| var properties: Dictionary = {}
properties["tags"] = ["building", "military"]
properties["cost"] = 100
var tags = properties.get("tags", [])
var cost = properties.get("cost", 0)
|
C#:
1
2
3
4
5
6
7
8
9
10
| var properties = new Dictionary<string, object>();
properties["tags"] = new List<string> { "building", "military" };
properties["cost"] = 100;
var tags = properties.TryGetValue("tags", out var tagsObj)
? tagsObj as List<string>
: new List<string>();
var cost = properties.TryGetValue("cost", out var costObj)
? Convert.ToInt32(costObj)
: 0;
|
π― Interface Implementation
GDScript:
1
2
3
4
5
6
| # Duck typing - no explicit interfaces
func get_id() -> String:
return id
func get_name() -> String:
return name
|
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
| public class Placeable : IPlaceable
{
public string Id { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
// Interface implementation is explicit
public string FilePath { get; set; } = string.Empty;
public Vector2I Size { get; set; } = new Vector2I(1, 1);
public bool CanRotate { get; set; } = true;
public bool CanMirror { get; set; } = false;
public Dictionary<string, int> ResourceCost { get; set; } = new();
public Dictionary<string, object> Properties { get; set; } = new();
}
|
π Migration Checklist
Before Migration
During Migration
After Migration
Note on legacy tests: Some v5-era Core test suites (e.g. indicator calculation and manipulation “system” user-aware flows) depended on types that no longer exist in 6.0 and have been retired rather than mechanically ported. Their design intent is captured in the current 6.0 Core services and new xUnit tests, not via direct one-to-one test translations.
| Operation | GDScript | C# | Improvement |
|---|
| Loop iterations | ~10ms | ~2ms | 5x faster |
| Dictionary access | ~5ms | ~1ms | 5x faster |
| String operations | ~8ms | ~2ms | 4x faster |
| Mathematical calculations | ~12ms | ~3ms | 4x faster |
π Debugging Tips
Common Issues
- Missing using statements - Add required namespaces
- Type mismatches - Check generic type parameters
- Null reference exceptions - Use null-conditional operators
- Method signature changes - Update parameter types
- Visual Studio Debugger: Full breakpoint support
- IntelliTrace: Historical debugging
- Code Analysis: Built-in static analysis
- Unit Testing: Better test framework integration
π Additional Resources
Godot System Classes
| GDScript Class | C# Class | Namespace | Notes |
|---|
GridPositioner2D | GridTargetingController2D | GridBuilding.Godot.Systems.GridTargeting.GridPositioner | 6.0 targeting controller that replaces the legacy GDScript GridPositioner2D; reads GridMode via IModeService and delegates logic to pure C# utilities. |
These mappings are used by the GridBuilding migration tooling (Rust TypeMapper).
This table is the canonical source of truth; implementation code in
toolkits/rust/crates/gridbuilding_migration/src/type_mapper.rs must stay in sync.
| GDScript Class | C# Full Name | Notes |
|---|
GBValidation | GridBuilding.Core.GBValidation | Core validation utilities. |
GBEnums | GridBuilding.Core.GBEnums | Core enums container. |
GBCompositionContainer | GridBuilding.Core.GBCompositionContainer | Core composition/bootstrap container. |
GBLogger | GridBuilding.Core.GBLogger | Core logging helper. |
GBInjectorSystem | GridBuilding.Core.GBInjectorSystem | Core injector / composition helper. |
GBGridRotationUtils | GridBuilding.Utils.GBGridRotationUtils | Grid rotation utility helpers. |
GBSearchUtils | GridBuilding.Utils.GBSearchUtils | Search utilities used by grid systems. |
GBPlacementPersistence | GridBuilding.Persistence.GBPlacementPersistence | Persistence helpers for placement data. |
GBSystemsComponent | GridBuilding.Core.GBSystemsComponent | Core systems composition component. |
GridPositioner2D | GridBuilding.Godot.Systems.GridTargeting.GridPositioner.GridTargetingController2D | Legacy GDScript system node mapped to the new 6.0 controller. |
Placeable | GridBuilding.Core.Placeable | Canonical 6.0 placeable implementation. |
PlaceableBox | GridBuilding.Placeables.PlaceableBox | Demo/example placeable. |
PlaceableBlacksmithBlue | GridBuilding.Placeables.PlaceableBlacksmithBlue | Demo/example placeable. |
PlaceableHouseWoodenRed | GridBuilding.Placeables.PlaceableHouseWoodenRed | Demo/example placeable. |
PlaceableMillBigGreen | GridBuilding.Placeables.PlaceableMillBigGreen | Demo/example placeable. |
PlaceableIsometricBuilding | GridBuilding.Placeables.PlaceableIsometricBuilding | Demo/example isometric placeable. |
DemoTestEnvironment | GridBuilding.Testing.DemoTestEnvironment | Test/demo environment type. |
Manipulatable | GridBuilding.Core.Manipulatable | Core manipulatable entity type. |
ModeState | GridBuilding.Core.ModeState | Legacy multi-enum mode state. Migration-only; 6.0+ uses GridMode + IModeService. |
TileCheckRule | GridBuilding.Rules.TileCheckRule | Core tile rule used by placement/validation. |
Autoload Mappings
| GDScript Autoload | C# Full Name | Notes |
|---|
GridBuilding | GridBuilding.GridBuilding | GridBuilding autoload root; used by migration tooling for autoload references. |
The “GridBuilding Migration Tool Class Mappings (Authoritative)” table above is mirrored
into a small JSON config used by the Rust migration tool:
- Path:
toolkits/rust/crates/gridbuilding_migration/resources/gdscript_to_csharp_mappings.json - Role: machine-readable backing store for the same GDScriptβC# mappings
- Usage: loaded by
TypeMapper via include_str! so CLI and tests always use the
current mapping set.
When adding or changing mappings:
- Update the table in this guide first (human-facing source of truth).
- Then update the JSON config to keep the tool in sync.