Volver al Blog
Game Development9 de febrero de 202610 min de lectura

Por Qué Elegí Godot 4 + C# para Mi RPG Táctico

DR

Doug Ribeiro

10 min de lectura

Construir un juego como proyecto personal mientras trabajas como desarrollador senior durante el día es un ejercicio de toma de decisiones deliberada. Cada decisión de herramienta tiene consecuencias compuestas: el motor equivocado o el lenguaje equivocado te costará cientos de horas durante la vida de un proyecto. Pasé unos tres meses investigando y prototipando antes de comprometerme con Godot 4 con C# para mi RPG táctico, y quiero documentar ese proceso de decisión honestamente, incluyendo lo que me ha sorprendido, tanto positiva como negativamente. Los números de este post son una instantánea que tomé en febrero de 2026: 123+ scripts, 334+ tests entre las suites unitarias, de integración y de rendimiento, y 28 shaders.

La Decisión del Motor: Unity vs Unreal vs Godot

Cuando empecé este proyecto, evalué tres motores seriamente: Unity, Unreal Engine 5 y Godot 4. No evalué GameMaker u otros motores enfocados en 2D porque mi juego tiene una vista isométrica 3D con una cantidad significativa de trabajo de shaders personalizados, y necesitaba un motor con un pipeline 3D fuerte.

Unity era el primer candidato obvio. Tiene el ecosistema más grande, más tutoriales, más contenido en el asset store, y una comunidad masiva. Tengo colegas que juran por él. Pero investigué Unity con la saga de la tarifa de runtime todavía fresca: anunciada en septiembre de 2023, suavizada en cuestión de semanas y cancelada en septiembre de 2024. Incluso sin la tarifa, el incidente reveló algo que no podía ignorar: Unity es una empresa que cotiza en bolsa con obligaciones hacia accionistas que pueden conflictuar con los intereses de los desarrolladores. Para un proyecto personal a largo plazo donde estoy invirtiendo tiempo significativo, necesito confianza en la estabilidad y alineación de la plataforma con mis intereses como desarrollador indie.

Unreal Engine 5 es genuinamente impresionante desde el punto de vista tecnológico. Nanite, Lumen, el nuevo sistema de animación: la ingeniería es extraordinaria. Pero UE5 está diseñado para equipos con artistas técnicos a tiempo completo, animadores especializados y múltiples programadores. El overhead de complejidad para un desarrollador solo construyendo un RPG táctico es enorme. El motor está optimizado para juegos de acción AAA en primera o tercera persona 3D. Usarlo para un juego táctico por turnos con perspectiva isométrica significaría pelear contra las suposiciones del motor en cada paso.

Godot 4 fue la elección a la que me comprometí, y las razones fueron: es completamente open source bajo licencia MIT (sin preocupaciones de licenciamiento, sin cambios de política que puedan afectarme retroactivamente), está arquitectónicamente bien adaptado al tipo de juego que estoy construyendo, y el release 4.0 trajo mejoras significativas específicamente al pipeline 3D y a la integración con C#.

Unity / Unreal Engine 5Unity: controversia por el runt…UE5: excesivo para un RPG tácti…Ambos: editor pesado, iteración…Unity: C# pero setup de proyect…UE5: C++ principalmente, Bluepr…Ambos: assets binarios grandes …Godot 4 + C#Licencia MIT. Nunca hay runtime…Editor liviano, iteración rápidaRenderizador 3D basado en Vulka…C# con .NET 8. Familiar para de…GDScript como alternativa para …Tamaño binario pequeño, amigabl…VS

Por Qué C# Sobre GDScript

El lenguaje de scripting nativo de Godot es GDScript, y es excelente para muchos casos de uso. Es similar a Python en sintaxis, profundamente integrado con el motor, y el tooling ha mejorado sustancialmente en Godot 4. Si estuviera construyendo un juego casual 2D como primer proyecto de juego, probablemente usaría GDScript.

Para mi proyecto, C# fue la elección correcta por varias razones específicas a mi background y a la complejidad de lo que estoy construyendo.

Primero: type safety a escala. Un RPG táctico tiene muchos sistemas interactuando: un sistema de combate, un sistema de movimiento, un sistema de cálculo de stats, un árbol de decisión de IA, un sistema de inventario, un sistema de equipamiento, un sistema de habilidades, un sistema de progresión de unidades. Cuando estos sistemas interactúan, los errores de tipos son una fuente importante de bugs. C# con su tipado estático fuerte atrapa categorías enteras de bugs en tiempo de compilación que GDScript detectaría en runtime, frecuentemente en un edge case oscuro durante gameplay. Con 123+ scripts en el proyecto, el dividendo de type safety es significativo.

Segundo: tooling. Trabajo en JetBrains Rider, que tiene soporte C# de primera clase. Refactoring, navegación de símbolos, find usages, documentación inline: estas herramientas funcionan a capacidad completa para C#. El soporte de GDScript en editores externos está mejorando pero es aún significativamente inferior. Para un proyecto donde podría refactorizar una estructura de datos central referenciada en 40 archivos, buen tooling no es un lujo.

Tercero: patrones transferibles. Mi background es TypeScript y Angular. C# es sintácticamente cercano a TypeScript y comparte muchos patrones: generics, LINQ es similar a métodos de array, async/await, interfaces, conceptos de dependencias. La curva de aprendizaje fue manejable porque estaba aprendiendo los patrones de Godot, no un paradigma de programación completamente nuevo y un nuevo lenguaje simultáneamente.

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);
    }
}

Lo Que Me Sorprendió de Godot 4

Hay cosas sobre Godot que esperaba y cosas que genuinamente me sorprendieron. Esperaba el sistema de escenas. Esperaba nodos y signals. Esperaba un motor más ligero que Unity o Unreal. Esto es lo que no esperaba.

El lenguaje de shaders es excelente. He escrito 28 shaders para este proyecto, incluyendo shaders de terreno procedural, efectos de contorno de unidades, overlays de highlight de tiles, implementación de fog of war, y varios shaders de efectos visuales. El lenguaje de shaders de Godot es un dialecto de GLSL que está bien documentado y se comporta bien. Venía esperando que el desarrollo de shaders fuera una parte dolorosa del proyecto. Ha sido una de las partes más disfrutable.

El sistema de Resources es más poderoso de lo que parece inicialmente. Los Resources en Godot son contenedores de datos que pueden serializarse, referenciarse entre escenas, y extenderse con comportamiento personalizado. Una vez que entendí cómo usar Resources tipados como objetos de configuración, esencialmente diseño de juegos data-driven, desbloqueó un patrón que ha hecho el juego dramáticamente más mantenible. Definiciones de habilidades, plantillas de unidades, tipos de terreno, blueprints de equipamiento: todos estos son Resources almacenados como archivos .tres, editables en el inspector de Godot sin tocar código.

La integración de C# es buena, pero tiene bordes ásperos. El hecho de que GDScript y C# coexistan en el mismo proyecto significa que hay puntos de fricción de interoperabilidad ocasionales. Los signals funcionan a través de la frontera de lenguaje pero requieren sintaxis diferente dependiendo de qué lado estés. Algunas funcionalidades de Godot que son de primera clase en GDScript se acceden a través de APIs ligeramente incómodas en C#. El borde áspero que realmente condiciona la decisión es el soporte de plataformas: Godot 4 no puede exportar un proyecto C# a la web en absoluto, y la exportación C# a Android e iOS sigue siendo experimental. Si una build de navegador es parte de tu plan, GDScript es la única opción hoy. Yo apunto a escritorio, así que tomé ese intercambio a conciencia, pero es lo primero que hay que revisar antes de comprometerse con el camino de C#.

La Elección del Género RPG Táctico

Quiero explicar por qué elegí construir un RPG táctico específicamente, porque la elección de género tiene implicaciones significativas para la complejidad de ingeniería del proyecto.

He sido fan del género desde que jugué Final Fantasy Tactics de niño y luego descubrí Fire Emblem, Disgaea e Into the Breach. Los RPG tácticos son un género donde la profundidad de diseño viene de la interacción de sistemas en lugar del volumen de contenido. Un RPG táctico bien diseñado puede proveer cientos de horas de gameplay significativo de un set de contenido relativamente pequeño, porque el espacio de combinación de unidades, habilidades, enemigos y terreno genera complejidad emergente.

Desde un punto de vista de ingeniería, los RPG tácticos son juegos pesados en sistemas. Requieren: un sistema de movimiento basado en cuadrícula con pathfinding y cálculo de rango de movimiento, un sistema de orden de turnos, un sistema de cálculo de combate con múltiples variables interactuando, un sistema de decisión de IA para unidades enemigas, un sistema de habilidades y capacidades con efectos diversos e interactuando, un sistema de progresión de unidades, y un sistema de inventario y equipamiento. Todos estos sistemas necesitan interactuar correctamente entre sí. Este es exactamente el tipo de problema que encuentro genuinamente interesante desde una perspectiva de diseño de software.

Estado Actual del Proyecto

En febrero de 2026, el proyecto tiene 123+ scripts, 334+ tests entre las suites unitarias, de integración y de rendimiento, y 28 shaders. Ese conteo de tests es algo sobre lo que quiero comentar explícitamente: escribo tests para la lógica del juego, y estoy convencido de que este es el enfoque correcto para un proyecto de juego complejo aunque no sea la norma de la industria para juegos indie.

Cálculos de combate, resultados de pathfinding, apilamiento de modificadores de stats, cálculos de orden de turnos: toda esta es lógica determinista que puede y debe ser testeada. Cada vez que hago un cambio al sistema de combate, mi suite de tests me dice inmediatamente si he roto algo en otro lugar. En un juego donde cada clase de unidad, habilidad y tipo de terreno puede interactuar con todos los demás, la complejidad combinatoria del testing manual no es tratable. Los tests automatizados no son opcionales a esta escala: son la forma en que mantengo confianza en el sistema mientras crece.

Dos frameworks cubren esa suite, y la línea entre ellos es el motor. La lógica pura, las clases que nunca tocan un nodo, una escena o un Resource, corre bajo xUnit a secas sin ningún proceso de Godot, que es lo que hace el test de abajo. Todo lo que toca el motor corre bajo GdUnit4 dentro de 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
    }
}

La Evaluación Honesta Después de Meses de Desarrollo

Godot 4 con C# es una elección genuinamente excelente para un desarrollador solo construyendo un juego complejo y pesado en sistemas. La naturaleza open source elimina una categoría real de riesgo a largo plazo. El motor es capaz, mejora rápidamente, y está bien adaptado al tipo de desarrollo que estoy haciendo. El tooling de C# me da la infraestructura de productividad que necesito para gestionar un proyecto de esta complejidad.

Lo que subestimé: el tiempo requerido para construir tooling robusto para el juego. El juego en sí requiere plugins de editor personalizados para cosas como edición de mapas, colocación de unidades y configuración de encuentros. Construir estas herramientas como scripts de editor en C# toma tiempo real y no es algo para lo que ningún tutorial te prepara adecuadamente. El tooling es al menos el 20% del esfuerzo total del proyecto, y estaba más cerca del 10% en mis estimaciones iniciales.

Elegir un motor es elegir un conjunto de restricciones. La pregunta no es qué motor es el mejor, sino con qué restricciones puedes vivir y cuáles se alinean con lo que estás intentando construir.

Si eres un desarrollador de background web o software empresarial considerando el desarrollo de juegos, Godot 4 con C# es un punto de entrada accesible y poderoso para juegos de escritorio. Los patrones son diferentes del desarrollo web pero no alienígenas, especialmente si ya estás cómodo con TypeScript y arquitecturas basadas en componentes. La inversión de aprendizaje es real, pero es tratable, y la recompensa creativa de construir un juego desde cero es diferente a cualquier cosa que he experimentado en el desarrollo profesional de software.

Referencias

GodotC#Game DevelopmentIndie Dev