Back to Blog
Game DevelopmentFebruary 9, 202610 min read

Why I Chose Godot 4 + C# for My Tactical RPG

DR

Doug Ribeiro

10 min read

Building a game as a side project while working as a senior developer during the day is an exercise in deliberate choice-making. Every tool decision has compounding consequences. The wrong engine or the wrong language will cost you hundreds of hours over the lifetime of a project. I spent about three months researching and prototyping before committing to Godot 4 with C# for my tactical RPG, and I want to document that decision process honestly, including what has surprised me, both positively and negatively. The counts in this post are a snapshot I took in February 2026: 123+ scripts, 334+ tests across unit, integration and performance suites, and 28 shaders.

The Engine Decision: Unity vs Unreal vs Godot

When I started this project, I evaluated three engines seriously: Unity, Unreal Engine 5, and Godot 4. I did not evaluate GameMaker or other 2D-focused engines because my game has a 3D isometric view with a significant amount of custom shader work, and I needed an engine with a strong 3D pipeline.

Unity was the obvious first candidate. It has the largest ecosystem, the most tutorials, the most asset store content, and a massive community. I have colleagues who swear by it. But I investigated Unity with the runtime fee saga still fresh: announced in September 2023, softened within weeks, and cancelled in September 2024. Even with the fee gone, the incident revealed something I could not ignore: Unity is a publicly traded company with shareholder obligations that can conflict with developer interests. For a long-term personal project where I am investing significant time, I need confidence in the platform's stability and alignment with my interests as an indie developer.

Unreal Engine 5 is genuinely impressive from a technology standpoint. Nanite, Lumen, the new animation system. The engineering is extraordinary. But UE5 is designed for teams with full-time technical artists, specialized animators, and multiple programmers. The complexity overhead for a solo developer building a tactical RPG is enormous. The engine is optimized for AAA first-person or third-person 3D action games. Using it for a turn-based tactical game with isometric perspective would mean fighting the engine's assumptions at every step.

Godot 4 was the choice I committed to, and the reasons were: it is fully open source under an MIT license (no licensing concerns, no policy changes that can retroactively affect me), it is architecturally well-suited to the type of game I am building, and the 4.0 release brought significant improvements specifically to the 3D pipeline and to the C# integration.

Unity / Unreal Engine 5Unity: runtime fee controversy …UE5: overkill for a solo tactic…Both: heavy editor, slow iterat…Unity: C# but complex project s…UE5: C++ primarily, Blueprints …Both: large binary assets in gitGodot 4 + C#MIT license. No runtime fees ev…Lightweight editor, fast iterat…Vulkan-based 3D renderer since …C# with .NET 8. Familiar for we…GDScript alternative for rapid …Small binary size, git-friendlyVS

Why C# Over GDScript

Godot's native scripting language is GDScript, and it is excellent for many use cases. It is Python-adjacent in syntax, deeply integrated with the engine, and the tooling has improved substantially in Godot 4. If I were building a casual 2D game as a first game project, I would probably use GDScript.

For my project, C# was the right choice for several reasons that are specific to my background and to the complexity of what I am building.

First: type safety at scale. A tactical RPG has a lot of interacting systems. A combat system, a movement system, a stat calculation system, an AI decision tree, an inventory system, an equipment system, a skills system, a unit progression system. When these systems interact, type errors are a major source of bugs. C# with its strong static typing catches entire categories of bugs at compile time that GDScript would surface at runtime, often in an obscure edge case during gameplay. With 123+ scripts in the project, the type safety dividend is significant.

Second: tooling. I work in JetBrains Rider, which has first-class C# support. Refactoring, symbol navigation, find usages, inline documentation. These tools work at full capability for C#. GDScript support in external editors is improving but is still meaningfully inferior. For a project where I might refactor a core data structure that is referenced across 40 files, good tooling is not a luxury.

Third: transferable patterns. My background is TypeScript and Angular. C# is syntactically close to TypeScript and shares many patterns. Generics, LINQ is similar to array methods, async/await, interfaces, dependency concepts. The learning curve was manageable because I was learning Godot's patterns, not an entirely new programming paradigm and a new language simultaneously.

csharp
// Example: A typed unit stat system in C#
public sealed partial class UnitStats : Resource
{
    [Export] public int BaseHealth { get; set; } = 100;
    [Export] public int BaseAttack { get; set; } = 10;
    [Export] public int BaseDefense { get; set; } = 5;
    [Export] public int BaseMovementRange { get; set; } = 4;
    [Export] public int BaseActionPoints { get; set; } = 2;

    public int ComputeEffectiveHealth(IReadOnlyList<StatModifier> modifiers)
    {
        var total = (float)BaseHealth;
        foreach (var modifier in modifiers.Where(m => m.Stat == StatType.Health))
        {
            total = modifier.Type == ModifierType.Flat
                ? total + modifier.Value
                : total * (1f + modifier.Value / 100f);
        }
        return Mathf.RoundToInt(total);
    }
}

What Surprised Me About Godot 4

There are things about Godot that I expected and things that genuinely surprised me. I expected the scene system. I expected nodes and signals. I expected a lighter-weight engine than Unity or Unreal. Here is what I did not expect.

The shader language is excellent. I have written 28 shaders for this project, including procedural terrain shaders, unit outline effects, tile highlight overlays, fog of war implementation, and various visual effect shaders. Godot's shader language is a GLSL dialect that is well-documented and well-behaved. I came in expecting shader development to be a painful part of the project. It has been one of the most enjoyable parts.

The Resource system is more powerful than it first appears. Resources in Godot are data containers that can be serialized, referenced across scenes, and extended with custom behavior. Once I understood how to use typed Resources as configuration objects, essentially data-driven game design, it unlocked a pattern that has made the game dramatically more maintainable. Ability definitions, unit templates, terrain types, equipment blueprints. All of these are Resources stored as .tres files, editable in the Godot inspector without touching code.

The C# integration is good, but it has rough edges. The fact that GDScript and C# coexist in the same project means there are occasional interoperability friction points. Signals work across the language boundary but require different syntax depending on which side you are on. Some Godot features that are first-class in GDScript are accessed through slightly awkward APIs in C#. The rough edge that actually constrains the decision is platform support: Godot 4 cannot export a C# project to the web at all, and C# export to Android and iOS is still experimental. If a browser build is part of your plan, GDScript is the only option today. I am targeting desktop, so I took that trade knowingly, but it is the first thing to check before you commit to the C# path.

The Tactical RPG Genre Choice

I want to explain why I chose to build a tactical RPG specifically, because the genre choice has significant implications for the engineering complexity of the project.

I have been a fan of the genre since playing Final Fantasy Tactics as a kid and later discovering Fire Emblem, Disgaea, and Into the Breach. Tactical RPGs are a genre where design depth comes from system interaction rather than from content volume. A well-designed tactical RPG can provide hundreds of hours of meaningful gameplay from a relatively small content set, because the combination space of units, skills, enemies, and terrain generates emergent complexity.

From an engineering standpoint, tactical RPGs are systems-heavy games. They require: a grid-based movement system with pathfinding and movement range calculation, a turn order system, a combat calculation system with multiple interacting variables, an AI decision system for enemy units, a skill and ability system with diverse and interacting effects, a unit progression system, and an inventory and equipment system. All of these systems need to interact with each other correctly. This is exactly the type of problem I find genuinely interesting from a software design perspective.

Current State of the Project

As of February 2026, the project has 123+ scripts, 334+ tests across unit, integration and performance suites, and 28 shaders. That test count is something I want to comment on explicitly: I write tests for game logic, and I am convinced this is the right approach for a complex game project even though it is not the industry norm for indie games.

Combat calculations, pathfinding results, stat modifier stacking, turn order calculations. These are all deterministic logic that can and should be tested. Every time I make a change to the combat system, my test suite tells me immediately whether I have broken something elsewhere. In a game where every unit class, ability and terrain type can interact with every other, the combinatorial complexity of manual testing is not tractable. Automated tests are not optional at this scale. They are how I maintain confidence in the system as it grows.

Two frameworks cover that suite, and the line between them is the engine. Pure logic, the classes that never touch a node, a scene or a Resource, runs under plain xUnit with no Godot process at all, which is what the test below does. Anything engine-facing runs under GdUnit4 inside Godot.

csharp
// Movement range calculation, pure logic suite (xUnit, no Godot runtime)
public class MovementRangeCalculatorTests
{
    private readonly MovementRangeCalculator _calculator;
    private readonly InMemoryGrid _testGrid;

    public MovementRangeCalculatorTests()
    {
        // InMemoryGrid implements the same IGridQuery interface as the
        // GridMap-backed service the battle scene uses at runtime
        _testGrid = GridMapFactory.CreateFlat(10, 10);
        _calculator = new MovementRangeCalculator(_testGrid);
    }

    [Fact]
    public void GetReachableTiles_BasicMovement_ReturnsCorrectDiamond()
    {
        var origin = new Vector2I(5, 5);
        var movementRange = 3;

        var result = _calculator.GetReachableTiles(origin, movementRange);

        Assert.Equal(25, result.Count); // Diamond with range 3
        Assert.Contains(new Vector2I(5, 8), result); // North
        Assert.Contains(new Vector2I(8, 5), result); // East
        Assert.DoesNotContain(new Vector2I(5, 9), result); // Out of range
    }

    [Fact]
    public void GetReachableTiles_WithObstacle_ExcludesBlockedTiles()
    {
        _testGrid.SetCellTerrain(new Vector2I(5, 6), TerrainType.Impassable);
        var origin = new Vector2I(5, 5);

        var result = _calculator.GetReachableTiles(origin, movementRange: 3);

        Assert.DoesNotContain(new Vector2I(5, 7), result); // Behind obstacle
    }
}

The Honest Assessment After Months of Development

Godot 4 with C# is a genuinely excellent choice for a solo developer building a complex, systems-heavy game. The open source nature removes a real category of long-term risk. The engine is capable, improving rapidly, and well-suited to the type of development I am doing. The C# tooling gives me the productivity infrastructure I need to manage a project of this complexity.

What I underestimated: the time required to build robust game tooling. The game itself requires custom editor plugins for things like map editing, unit placement, and encounter configuration. Building these tools as C# editor scripts takes real time and is not something any tutorial prepares you for adequately. Tooling is at least 20% of the total project effort, and it was closer to 10% in my initial estimates.

Choosing an engine is choosing a set of constraints. The question is not which engine is best. It is which constraints you can live with and which ones align with what you are trying to build.

If you are a developer from a web or enterprise software background considering game development, Godot 4 with C# is an accessible and powerful entry point for desktop games. The patterns are different from web development but not alien, especially if you are already comfortable with TypeScript and component-based architectures. The learning investment is real, but it is tractable, and the creative payoff of building a game from scratch is unlike anything I have experienced in professional software development.

References

GodotC#Game DevelopmentIndie Dev