Sin LLM, hacer un juego toma 3 meses; con LLM, 3 días
(marianogappa.github.io)- Un ingeniero de software con 15 años de experiencia comparte su experiencia de desarrollar en Go un juego de cartas de su infancia
- Al desarrollar “Truco” sin LLM (modelo de lenguaje grande), resolvió manualmente todos los problemas, como el diseño de la UI y el despliegue serverless, y le tomó 3 meses
- Al crear “Escoba”, usó un LLM para convertir código de backend y acelerar mucho la implementación, y la mayor parte funcionó desde el primer prompt
- En la parte final del artículo ofrece una guía paso a paso para que cualquiera pueda crear un juego, usando un ejemplo de Tic-Tac-Toe con backend en Go, conversión a WASM e integración con React
- Aun así, el frontend en React y la gestión del estado del juego basada en WASM siguen requiriendo depuración e implementación manuales
Introducción
- Un ingeniero de software con 15 años de experiencia se dio cuenta de que en realidad nunca había creado ni desplegado un juego por su cuenta
- Decidió desarrollar en Go uno de los juegos de cartas que disfrutaba con sus amigos en Argentina cuando era niño
Truco: 3 meses sin LLM
- El 18 de junio de 2024 empezó a desarrollar el juego de cartas Truco con un backend en Go. Escribió el frontend con apenas conocimientos mínimos de React
- La implementación de la UI fue el mayor desafío y, para evitar ofrecer un servidor, usó TinyGo para transpilar a WASM (WebAssembly) y luego desplegó los archivos estáticos en GitHub Pages
- Como no tenía LLM en ese momento, tuvo que investigar cada detalle por su cuenta y avanzar a prueba y error durante unos 3 meses hasta terminarlo
- No lo hizo con fines publicitarios ni de monetización, sino solo con el objetivo de completar el juego, y sigue jugándose de forma constante incluso 1 año después de su lanzamiento
- Jugar Truco: https://marianogappa.github.io/truco-argentino
- Backend (Golang): https://github.com/marianogappa/truco
- Frontend (React): https://github.com/marianogappa/truco-argentino
Escoba: 3 días con LLM
- Un año después, durante una visita a Argentina para ver a su familia, le enseñó a su sobrino Escoba, el segundo juego de cartas más popular
- Esta vez usó LLM (Claude): duplicó el backend de Truco, explicó las reglas de Escoba en el prompt y pidió refactorizar el código
- Casi quedó perfecto desde el primer prompt, y solo tuvo que corregir manualmente algunos bugs menores y agregar funciones adicionales
- El frontend sí requirió varios días de implementación y depuración manual. Las limitaciones del LLM, sus habilidades con React y el entorno particular de manejar el estado del juego en WASM fueron factores desafiantes
- Jugar Escoba: https://marianogappa.github.io/escoba-de-15
- Backend (Golang): https://github.com/marianogappa/escoba
- Frontend (React): https://github.com/marianogappa/escoba-de-15
Paso a paso: cómo crear tu propio juego
- Presenta una guía práctica mínima y código de ejemplo para que cualquiera pueda intentar desarrollar su propio juego
- Ofrece un repositorio de ejemplo de Tic-Tac-Toe que se puede usar como base mediante un fork
Desarrollo del backend
- En un backend por turnos, las funcionalidades pueden diseñarse con claridad
- Mantener una arquitectura serverless y evitar una estructura donde personas jueguen entre sí es una decisión realista si no se cuenta con un servidor comercial
Desarrollo del frontend
- El frontend necesita realizar tareas como las siguientes
- Solicitar al backend la creación de un nuevo
GameState - Mostrar el estado en la UI
- Proveer una interfaz para elegir acciones válidas
- Enviar comandos al backend al aplicar una acción
- Pedir al backend el turno del bot cuando corresponda
- Solicitar al backend la creación de un nuevo
Conversión del backend a WASM
- Para compilar código Go a WASM, se usa
GOARCH=wasm GOOS=js go build - Puede haber problemas por el gran tamaño del binario, así que usa TinyGo para reducirlo
- Para exportar las funciones que se conectarán con el frontend, escribe en Go un punto de entrada separado (por ejemplo,
main_wasm.go) y lo maneja con bifurcación en el proceso de build - En la función principal hace falta bloquear con
select {}para evitar que el programa termine de inmediato
Integración de datos entre backend y frontend
- Los structs de forma libre de Go, como
GameState, no pueden serializarse/deserializarse directamente en WASM - Es necesario intercambiar todos los datos en formato JSON
- Siguiendo la documentación de TinyGo, tanto la entrada como la salida se manejan mediante serialización JSON
Interfaz entre frontend y backend
- En el frontend se llaman directamente las funciones del backend
GameStatese administra solo dentro de WASM y el frontend no puede mutarlo; el backend es siempre la fuente de verdad- Después de recompilar WASM hay que reemplazar el archivo, y se muestra un ejemplo de automatización mediante Makefile
Entorno de ejecución de WASM
- Para ejecutarlo, hay que incluir
wasm_exec.jsen elhead, y usar ese script para crear la instancia y ejecutarla
Conclusión
- Hacer juegos fue una experiencia divertida, y la combinación de Go, WASM y React es un enfoque que cualquiera puede intentar
- La ayuda de los LLM mejoró mucho la productividad, pero las habilidades de frontend y la experiencia depurando siguen siendo importantes
- Cualquiera puede animarse a desarrollar su propio juego con esta estructura, así que vale la pena intentarlo
4 comentarios
Si se generó código que usa
document.getElementByIden React, ¿qué LLM habrán usado....Se siente casi como un título clickbait para llamar la atención..
"Si lo haces desde cero, 3 meses; si vuelves a hacer algo parecido, 3 días"
Parece que el autor original es alguien que normalmente ni sabe qué hace.
Comentarios de Hacker News
Lo que me gusta de esta publicación es que señala algo que muchos desarrolladores pasan por alto. En el desarrollo de juegos, pocas veces la programación en sí ha sido el cuello de botella. Incluso alguien que desarrolla en solitario puede crear mecánicas rápido sin IA. La parte realmente difícil son varias capas invisibles por encima de eso: por ejemplo, balancear el game loop, ajustar la dificultad, crear assets que no se sientan fuera de lugar y pulir lo suficiente como para mantener el interés del usuario por más de 5 minutos. Por eso, después de los LLM, Steam no se ha llenado de juegos sobresalientes. La tecnología bajó una barrera, pero las barreras más grandes siguen intactas. Pasó lo mismo con la llegada de Unity en los 2010. El motor democratizó el desarrollo de juegos, pero en vez de una explosión de buenos juegos, lo que aumentó fue la cantidad de intentos. Los LLM están provocando el mismo fenómeno en el código, y los modelos de imagen en el arte, pero estas herramientas no pueden decirte qué juego es realmente divertido. La pregunta que me parece interesante es qué pasaría si la IA no solo implementara, sino que también hiciera playtesting. Es decir, si evolucionara hasta el punto de correr miles de loops y decirte qué mecánicas mantienen enganchados a jugadores simulados, entonces su rol se expandiría de hack de productividad a socio de diseño. Aún no estamos en esa etapa, pero este post se siente como un dato inicial que apunta en esa dirección
Sobre la idea de que la IA no solo implemente sino que también haga playtesting, corriendo miles de loops para medir cuánto más inmerso mantiene al jugador, me surge la duda de cómo podría la IA simular a un jugador y por qué sería capaz de juzgar correctamente en qué se engancharía una persona real
Quisiera cuestionar la objeción de que en el ejemplo del auge de Unity en los 2010 realmente no hubo tantos juegos muy buenos. De hecho, comparado con la era de XBLA, el enorme volumen de juegos que tenemos hoy habría sido imposible sin herramientas como Unity, Godot, Gamemaker, Renpy y RPG Maker. O sea, hubo claramente un crecimiento enorme no solo en cantidad, sino también en calidad
Para mí, la prueba de fuego de la IA generativa es que pueda crear un spritesheet completo para un juego de acción 2D pixel art. Por ejemplo, aunque sea sacar perfecto el movimiento de un tanque o de un protagonista, y hasta ahora no he visto ningún caso exitoso
Creo que la observación de que "la IA no puede decirte si tu juego es realmente divertido" es la idea clave. La IA no puede experimentar un juego de la misma forma en que lo hace un ser humano, ni puede vivir ninguna otra experiencia como un humano. A lo mucho puede hacer ciertas predicciones viendo datos de evaluaciones humanas sobre juegos parecidos. O sea, la IA no puede disfrutar tu juego. Esta esencia va a definir el rol del trabajo humano en la era de la IA. La IA puede redactar documentos o código más o menos como una persona basándose en datos del pasado, pero demuestra que existe una integración significativa y una experiencia que solo un humano puede lograr. Hay un punto del valor humano que no puede ser reemplazado, aunque sí tendremos que replantearnos cómo mirar ese valor
Este patrón también aplica fuera del desarrollo de juegos. Como cualquiera esperaría, hay muchísimo potencial en la programación basada en agentes, pero por ahora solo resuelve a una velocidad abrumadora algunas tareas concretas, como demos rápidas de webapps o conectar librerías pequeñas, y todavía se queda corta en software grande del mundo real. Tanto la forma en que se entrenaron los modelos como nuestro know-how para usarlos siguen siendo insuficientes. Esto no sorprende. Incluso git, durante 5 años después de aparecer, solo fue adoptado bien por empresas de élite, y luego tardó otros 5 años en masificarse. Al final hoy ya estamos muy acostumbrados, pero yo diría que los LLM son incluso más difíciles de usar bien que git. Si cada producto, OSS o post de blog no exagerara tanto con eso de "ya se acabó, todo fue revolucionado", quizá avanzaría más rápido. Seguimos en una etapa de prueba y error y experimentación, y eso toma tiempo. No hay que apresurarse a juzgar. Si de verdad ya estuviéramos en una etapa donde todo estuviera resuelto, al menos deberíamos estar enterrados bajo software muchísimo mejor, pero por ahora apenas estamos encontrando un equilibrio. Aun así, para una tecnología nueva con apenas 1 o 2 años, esto ya es bastante impresionante
La ventaja de 3 meses del LLM se apoyó en el código, en usar el juego anterior como plantilla y, sobre todo, en toda la experiencia y los errores acumulados al programarlo a mano
Al principio pensé que sería un título sensacionalista, pero sí me sorprendió la parte de "copié el backend de Truco y le expliqué largamente a Claude las reglas de Escoba antes de pedirle que refactorizara el código". Me da curiosidad cuánto tardaría una persona en hacer ese refactor. Siento que podría tomar más de 3 días, aunque también podría no ser así
Otra cosa importante es que este juego era el primero del participante. O sea, cuando uno intenta algo por primera vez tiene que lidiar con muchísimas variables desconocidas, pero si vuelve a empezar con los aprendizajes y el know-how de haberlo hecho una vez, podría construirlo en mucho menos de 3 meses incluso sin LLM
De hecho, lo he vivido: cuando repites el mismo proyecto dos o tres veces, algo que al inicio tomaba varios meses la siguiente vez se reduce como a un tercio
<i>Cof</i> yo también he desarrollado cosas en menos de 24 horas, hay ejemplos en nordicgamejam.com. Quiero decir que en la época en que no existían los LLM, GenAI ni Unity, lo mejor que había era Microsoft XNA y C#. El arte también solía ser, en su mayoría, dibujos hechos a mano en Paint. Aun así, cada año salían suficientes juegos divertidos, y algunos incluso se volvieron conocidos por el público, como Baba is You o Braid. El código no era el cuello de botella y, personalmente, estoy convencido de que el verdadero bottleneck es la comunicación entre los miembros del equipo
Viendo este hilo de comentarios, parece que hay muchos escritos por gente sin experiencia en desarrollo de juegos. En realidad, el tipo de proyecto donde se usan LLM ya existe en grandes cantidades dentro de los datos de entrenamiento. Por ejemplo, también es el tipo de proyecto que se ve en cursos introductorios de programación, y en países del sur de Europa hay muchísimos juegos parecidos al juego de cartas del que habla este blog. Yo mismo implementé Moon Patrol desde cero en Python en primer año de universidad, sin experiencia previa, y me tomó 2 o 3 meses, trasnochando 3 noches por semana. Hacer un juego de cartas es todavía más fácil que eso. Claro que los LLM son útiles en ciertas cosas, pero este tipo de ejemplo simple no sirve para evaluar la productividad de programación ni la utilidad de los LLM
Yo hice algo así dedicándole unos cuantos días sueltos con LLM: stacky. En la práctica fueron como dos días reales de trabajo. Al principio lo hice desde cero y luego de forma brownfield, sin intención de tomármelo demasiado en serio. Pero conforme fui agregando más detalles y funciones, me siguieron saliendo ideas (super rotation, DAS, etc.). Sigue incompleto, tal vez apenas en 10 a 20% del juego total. También corre una versión WebGL. Pero sentí que si intentaba hacer el Tetris definitivo me iban a demandar, y tampoco tengo dinero para pagar una licencia, así que me detuve. Al final me dejó confianza y experiencia. Hace poco vi en HN un enlace sobre funciones paramétricas y en 1 o 2 horas también armé el playground graphy. Igual, uno termina invirtiendo un montón de tiempo en los detalles. Si tienes claro qué quieres, hacer estas cosas con LLM puede ser bastante disfrutable
Llevo mucho tiempo haciendo desarrollo de juegos como hobby a cierto nivel y también he terminado varios juegos. Pero viendo el hilo completo, siento que mucha gente aquí no tiene tanta experiencia real en desarrollo de juegos. No puedo estar de acuerdo con la idea de que programar sea la parte fácil del desarrollo de juegos. Pensar una idea fresca o una variación mecánica de un género más bien me parece fácil; lo mucho más difícil es la parte de código para implementarlo de verdad. Por ejemplo, imaginar un Vampire Survivors multijugador con personalización de battlemechs es fácil, pero implementarlo solo con LLM es prácticamente imposible. Este caso, en cambio, es un juego de cartas con reglas ya completamente conocidas, así que es tan simple como un juego de serpiente. No es un ataque al autor del texto; solo quiero señalar que mucha gente está juzgando el desarrollo sin haber desarrollado juegos de verdad
No estoy de acuerdo con que programar sea la parte difícil del desarrollo de juegos. Claro que puede serlo, pero lo realmente difícil es idear algo nuevo y divertido. Si tienes una buena idea, puedes dividirla en piezas pequeñas e iterar hasta implementarla. El verdadero obstáculo es ese momento de decidir qué hacer frente a una hoja en blanco. Salir a caminar, probar mil cosas, eso es un problema que el arte lleva miles de años repitiendo. En cambio, programar al final es una labor de ingeniería. Yo también estoy estudiando desarrollo de juegos últimamente, incluso junto con matemáticas, y aprender matemáticas vectoriales o cuaterniones me resultó mucho más fácil que decidir "¿qué juego quiero hacer?"
Básicamente estoy de acuerdo, pero para mí siempre ha sido más difícil pensar ideas nuevas o hacer intentos creativos. Puedo programar casi cualquier mecánica de juego, pero la parte de escritura/creatividad sí se me hace realmente dura. Si a alguien eso le sale fácil, de verdad está bendecido. No es algo natural para todo el mundo
Si lo que se quiere hacer es un juego totalmente client-side, me pregunto por qué lo plantean como si necesitara un "backend", y también por qué usarían una tecnología distinta solo para el backend en vez de para toda la app
Siento que en la industria del software casi ya no quedan áreas donde una idea pueda hacerse realidad fácil y rápido. La competencia ya es tan feroz que, incluso si apuntas a un mercado muy pequeño, terminas compitiendo directamente con VC global y con IA global. Antes al menos podías encontrar un nicho que no interesara a las grandes empresas. Hoy, seas gran VC o nicho, igual compites contra todo el mundo, así que al final solo quedan mercados pequeños que requieren tecnología extremadamente compleja, o sectores con baja rentabilidad, alta probabilidad de fracaso y ciclos de vida cortos —y la mayoría de los juegos cae justo ahí—. En el primer caso, necesitas un marketing casi de salir uno por uno a explicar el producto. Por mi experiencia en la industria del juego, incluso antes de entrar en la etapa de desarrollo, un caso de "éxito enorme" ya significa algo como "consiguió un millón de vistas y 6 meses después quedó completamente muerto". Como casi no hay ingresos recurrentes, empezar ya de por sí desmotiva muchísimo. Hacer un juego como Minecraft es casi como ganarse la lotería. Pero la industria del juego, aun así, es relativamente meritocrática frente a otros sectores del software. La calidad y lo divertido sí se relacionan en cierta medida con la adopción. En otras industrias todo es un laberinto de regulación, monopolios por efectos de red o control estatal. Casi preferiría que al inicio el gobierno te dijera: "este sector ya lo tiene dominado tal empresa, no fundes una startup aquí y vete a otra parte", para no perder un año
Me pregunto cuándo se darán cuenta de que los proyectos greenfield (totalmente nuevos) son el peor caso posible para medir la capacidad de los agentes de programación
Me gustan los LLM porque me ayudan a tratar el código de una forma más cercana a cómo abstraigo los programas en mi cabeza. Cuando leo código, lo entiendo casi como si fuera un AST, convirtiendo funciones y llamadas en nodos abstractos de entrada y resultado. Gracias a los LLM, el trabajo de llevar eso de vuelta a código se volvió absurdamente sencillo. Ya no tengo que andar buscando ejemplos de código que encajen con mi idea ni hurgando en la memoria; solo le pido al LLM que escriba código repetitivo como una inicialización de WiFi. Al final, eso me permite ensamblar programas como si fueran bloques de Lego. Antes de los LLM también era posible trabajar así, pero requería muchísimo más esfuerzo. Gracias a eso hoy desarrollo con facilidad saltando entre varios lenguajes. No aprendo demasiado sobre la estructura interna o la sintaxis de cada lenguaje, pero justamente ese es el punto. El lenguaje y la sintaxis son detalles secundarios que no tienen que ver con el flujo lógico del programa. Así como pasamos de lenguaje máquina a ensamblador, a C y luego a lenguajes cada vez de más alto nivel, ahora nos iremos acercando cada vez menos al coding y más al 'programming' en sí. Nadie sabe cuál será la forma final, pero está claro que cada vez pasaremos menos tiempo en la 'escritura' y más tiempo concentrados en programar