Astra ha mejorado mucho en convertir lo que tengo en mente en mecánicas de juego y dirección artística. Lo he estado usando en Codex para crear Void Explorer, un juego de exploración espacial en el que puedes viajar desde estrellas lejanas hasta paisajes extraterrestres.
Una recopilación de momentos de juego de Void Explorer.
El juego tiene 2048 sistemas estelares y más de 10 000 planetas generados de forma procedural, incluidos mundos del tamaño de la Tierra. Cada estrella visible forma parte del universo y se puede seleccionar como destino. Puedes elegir un punto de luz a lo lejos y viajar hasta él.
Puedes acercarte a un planeta desde el espacio, atravesar su atmósfera y seguir descendiendo hasta sobrevolar una costa. Puedes aterrizar, salir de la nave, caminar por los alrededores y volver a despegar. Lograr que ese recorrido funcionara exigió resolver en conjunto la escala, el terreno, los controles y el renderizado.
Incluí algunos prompts que usé durante el desarrollo, editados para hacerlos más breves y claros. Muestran cómo describí lo que quería y cómo se desarrolló el trabajo técnico a partir de ahí.
Empieza por la experiencia
Mi propuesta inicial describía lo que el jugador debía poder hacer:
Debería poder llegar a todo lo que veo. Mantén las distancias reales y luego haz que los viajes funcionen mediante la escala y la velocidad. Quiero volar desde el espacio, entrar en la atmósfera de un planeta y descender hasta el suelo. Los planetas pueden ser tan grandes como la Tierra, así que necesitaremos terreno procedural y un renderizador por bloques.
Eso le dio a Astra algunas restricciones concretas. Una estrella no podía ser solo un punto pintado en el fondo. Un planeta no podía convertirse en un nivel aparte al acercarme. Los viajes tenían que cubrir distancias reales, y los mecanismos ficticios de viaje por pulsos e hiperpropulsión debían permitir recorrerlas de forma práctica.
También usé la generación de imágenes para definir el aspecto visual antes de desarrollar gran parte del juego. Los primeros conceptos eran demasiado realistas. La siguiente propuesta era demasiado simple. Esta fue una de mis correcciones:
Ahora esto es un poco demasiado simple. Necesitamos un punto medio: mejores colores, luz de neón y más contraste que evoque el espacio profundo. Muéstrame cómo se ve a gran velocidad, con estrellas y polvo alrededor de la nave.
Cuando las imágenes me gustaron, le pedí a Astra que las guardara y convirtiera esa dirección artística en referencias para el juego. Teníamos objetivos específicos para el vuelo orbital, el vuelo a gran velocidad, la entrada atmosférica y el aterrizaje. Esas imágenes hicieron mucho más fácil evaluar la siguiente versión.

Arte conceptual generado que definió la paleta y la dirección visual del juego.
Deja que Astra proponga la arquitectura
Yo definí las restricciones y Astra propuso la implementación. La aplicación usa TypeScript y Vite, con Three.js para el renderizado. Eso permite controlar directamente desde el código las mallas, los materiales, la iluminación y la geometría procedural, que concentran la mayor parte del trabajo visual de este juego.
El renderizador de la primera versión jugable usaba WebGL2. Más adelante, pregunté si Three.js estaba limitando la calidad visual. Astra recomendó conservar la simulación y migrar el renderizador a la arquitectura WebGPU de Three.js. Mantuvimos los sistemas del universo, la navegación y el terreno, y cambiamos la capa de renderizado.
El renderizador usa los materiales basados en nodos de Three.js y Three.js Shading Language (TSL) para definir en código la atmósfera, el agua y los efectos de iluminación.
La generación de terreno se ejecuta en Web Workers para preparar la geometría fuera del hilo que procesa la entrada y el dibujo. Vitest cubre aspectos como la generación reproducible, los cálculos de coordenadas y los contratos del terreno. Playwright prueba el juego en un navegador. Esto le dio a Astra formas de verificar los sistemas subyacentes mientras yo seguía evaluando la experiencia de juego.
La dirección artística siguió siendo el objetivo durante todo el proceso. La atmósfera que rodea un planeta, el brillo de sus anillos, la luz de colores de las estrellas y el efecto Neon Phosphor contribuyen al aspecto visual. El filtro añade una textura de pantalla retro sin dejar de mantener legible la información de navegación.

Una captura del juego con el efecto Neon Phosphor activado.
Dale a Astra una forma de inspeccionar y jugar
Yo seguía jugando por mi cuenta, pero Astra también necesitaba formas de investigar un problema más allá de leer mi descripción. El juego expone una pequeña interfaz JavaScript, window.__VOID_EXPLORER__, que las pruebas en el navegador pueden llamar para inspeccionar el estado actual: a qué cuerpo celeste me estoy acercando, el modo de vuelo, si el terreno está listo y la cámara activa. También expone contadores de renderizado y streaming, incluidas las llamadas de dibujo, los recuentos de triángulos, los trabajos de terreno en cola y los datos de terreno almacenados en el búfer.
El juego tiene escenas de prueba con nombre para la órbita, el viaje por pulsos, el descenso atmosférico y el aterrizaje en la costa. Estas permiten que Astra vuelva a un punto de partida útil sin tener que volar por todo el universo cada vez. Playwright puede cargar una escena, esperar a que el terreno esté listo, tomar una captura de pantalla y verificar el estado subyacente. Otras pruebas de recorrido usan los controles reales y registran las posiciones y los cambios de estado mientras se ejecuta el juego, de modo que preparar una escena de aterrizaje no sustituye probar el aterrizaje en sí.
Estas pruebas cubren el aterrizaje, salir de la nave, caminar, guardar y volver a cargar la partida, subir a la nave y despegar. Pueden detectar problemas que una captura de pantalla por sí sola no revelaría, como una superficie de colisión que aún no está lista o una nave que salta entre posiciones durante una transición.
También podía pedirle a Astra que inspeccionara la pestaña del navegador en la que estaba jugando. Cuando pregunté si las nubes de Aurelia seguían visibles, tomó una captura de mi vista actual y leyó la información de vuelo en pantalla. Eran verificaciones en momentos concretos; Astra no estaba observando continuamente cada fotograma de mi vuelo.
El ciclo consistía en reproducir un problema, inspeccionar capturas de pantalla y el estado, rastrear el código relevante, hacer un cambio y volver a ejecutar la verificación. Si desarrollara otro juego, crearía estas herramientas desde el principio: algunas escenas reproducibles, información de estado y contadores de rendimiento útiles, y pruebas en el navegador para las interacciones principales. Le dan a Astra formas de investigar y probar cambios de manera independiente mientras yo sigo evaluando el aspecto visual y la respuesta de los controles.
Representa el universo a varias escalas
Tener miles de planetas no significa cargar miles de mallas detalladas. Un planeta comienza como una descripción: su radio, órbita, atmósfera y semilla. La semilla permite reproducir su terreno. El juego genera la geometría alrededor de la zona a la que me acerco y puede volver a generar el mismo paisaje cuando regreso.
Las coordenadas requieren un cuidado similar. Las distancias de años luz y una persona de pie junto a una nave corresponden a escalas muy distintas. Enviar esas posiciones de valores enormes directamente a la GPU haría que se perdiera la precisión necesaria cerca del suelo.
Astra separó la ubicación física de la posición usada para dibujar. El universo usa celdas con valores enteros grandes y desplazamientos locales más pequeños. Antes de renderizar, el juego resta la posición del observador, de modo que la cámara permanece en el origen y los objetos cercanos tienen coordenadas pequeñas. Las distancias mostradas y los tamaños relativos mantienen su coherencia.
Los elementos en movimiento también deben estar sincronizados en el tiempo. Las estrellas, los planetas y las lunas siguen órbitas analíticas, y el renderizador evalúa sus posiciones en el mismo instante de la simulación que la del observador. Una nave estacionada permanece fija sobre el planeta mientras este gira. Las posiciones y los colores de las estrellas determinan la iluminación, de modo que los dos soles de un atardecer binario son las mismas estrellas que vi desde la órbita.
Haz que el descenso sea continuo
Vuelo desde el espacio hacia la superficie de una luna en Void Explorer.
La transición del espacio al suelo requirió muchas iteraciones. Uno de mis prompts surgió al acercarme a un planeta con un ángulo de descenso muy bajo:
Cuando me acerco casi en paralelo a la superficie de un planeta, todavía puedo llegar demasiado rápido, y el planeta casi desaparece mientras se carga el terreno. Tenemos que corregir la curva de velocidad y el streaming del terreno en conjunto. ¿Podría la atmósfera suavizar la transición entre el LOD lejano y el terreno detallado? El planeta nunca debería desaparecer durante la aproximación.
El controlador de vuelo ahora aplica un límite de velocidad independiente a las aproximaciones con un ángulo de descenso bajo, basado en la altitud y en una estimación de la velocidad orbital calculada a partir del radio y la gravedad del planeta. Más cerca del suelo, también toma muestras del terreno que hay por delante para ajustar el frenado.
El juego usa varios niveles de detalle, o LOD. Desde lejos, un planeta es una esfera facetada de bajo costo computacional, llamada proxy. A medida que ocupa más espacio en pantalla, el renderizador añade detalle. Al acercarse a la superficie, se activa un terreno construido a partir de seis caras de un cubo proyectadas sobre una esfera. Cada cara puede dividirse repetidamente en cuatro cuadrados más pequeños: un árbol cuaternario.
Eso permite que el juego refine el terreno de la zona visible y en la dirección del viaje sin generar una superficie del tamaño de la Tierra con la resolución necesaria para recorrerla a pie. Cerca del suelo, las porciones locales de terreno aportan geometría más detallada alrededor de la nave y del jugador.
Todas esas representaciones toman muestras del mismo planeta subyacente. Una función compartida combina continentes, cordilleras, cráteres y relieves menores. Proporciona elevación, agua, bioma y otras señales que usa el paisaje. Las mallas de menor y mayor detalle aproximan esos datos a distintas resoluciones, con una política de color compartida para mantener un aspecto coherente del planeta.
El cambio entre representaciones importa tanto como la generación. El planeta distante permanece visible hasta que las seis caras del terreno de bajo detalle están listas. Una tesela de terreno permanece en su lugar hasta que sus cuatro teselas hijas están listas. Durante una transición, unas máscaras de píxeles complementarias asignan cada píxel a la superficie anterior o a la nueva. Eso evita que todo el planeta se vuelva transparente mientras se carga su reemplazo.
La atmósfera cambia con la altitud física y las nubes se desplazan sobre la geografía del planeta. Ayudan a conectar la vista orbital con el paisaje. El renderizador solo retira la cobertura de bajo detalle donde ya está listo el terreno más detallado. Las siluetas de las montañas aún pueden cambiar a medida que aparece una geometría más detallada.
El aterrizaje añade un requisito más estricto. El suelo visible, los triángulos de colisión y los peligros por líquidos de una zona de contacto deben provenir de la misma generación y estar listos al mismo tiempo. Para caminar, se usa Rapier en un pequeño mundo local de simulación física. La lógica de aterrizaje de la nave verifica por separado sus apoyos, la pendiente y el espacio libre respecto al terreno.
Aquí hay un límite deliberado: los planetas usan campos de altura, con una única elevación en cada dirección de la superficie. Eso funciona bien para paisajes extensos, pero no permite crear cuevas, salientes ni túneles destructibles.
Mide el trabajo detrás de un fotograma lento
Algunos de mis comentarios combinaban el aspecto visual y el rendimiento, porque veía ambos problemas durante el mismo vuelo:
¿Puedes revisar cómo cargamos y renderizamos un planeta mientras vuelo desde el espacio hacia el suelo? El globo distante y el terreno detallado no tienen un aspecto coherente, y la transición es brusca, especialmente cuando cambian los colores. Quiero entender qué causa esos saltos visuales y dónde podemos reducir el trabajo necesario para cargar más detalle, para que el descenso se vea mejor y sea fluido.
Astra usó los contadores del renderizador de Three.js para inspeccionar las llamadas de dibujo, los triángulos, las geometrías y las texturas. Una prueba de Playwright recopiló 90 intervalos entre fotogramas e informó los tiempos promedio y por percentil junto con esos recuentos. Para los problemas visuales, las pruebas también podían comparar los píxeles renderizados con un efecto específico activado y desactivado, como el terreno con y sin la máscara que oculta el suelo superpuesto. Eso ayudó a aislar la causa de la desaparición del suelo, en lugar de depender únicamente de una captura de la escena con el error.
Una iteración anterior de la nave mostró por qué estas mediciones eran útiles. Reemplazar la nave procedural por el primer modelo AURORA creado en Blender aumentó el número de triángulos de la escena, pero redujo sus llamadas de dibujo. Astra ejecutó la misma prueba orbital de 90 fotogramas antes y después del cambio en el backend de WebGPU:
| Medición | Antes | Después |
|---|---|---|
| Total de llamadas de dibujo de la escena | 119 | 77 |
| Total de triángulos de la escena | 48 809 | 61 092 |
| Intervalo promedio entre fotogramas | 251,48 ms | 199,26 ms |
Esta comparación se hizo con Chromium sin interfaz gráfica y renderizado por software con SwiftShader, antes de crear la nave de cuatro alas que se muestra más adelante. Mide el cambio en ese entorno de prueba, no la tasa de fotogramas de mi GPU. Las herramientas le proporcionaron a Astra mediciones de tiempos del navegador, imágenes renderizadas y recuentos de recursos; no midieron comandos individuales de la GPU ni tiempos de ejecución de shaders.
Astra investigó el trabajo que se realizaba durante la carga y el descenso: cuánta geometría se generaba, cuántos datos se transferían entre los workers y el renderizador, y con qué frecuencia se descartaban tareas de terreno antes de que llegaran a ser útiles.
Uno de los cambios fue asignar el nivel de detalle de los planetas distantes según su tamaño en pantalla. Un planeta que ocupa toda la vista necesita una silueta bien definida de inmediato. Uno más pequeño que un píxel no necesita la misma geometría. En una comparación controlada de la escena inicial, la política revisada usó 7040 triángulos para las representaciones simplificadas en lugar de 51 200. Ambas políticas usaron el mismo generador de geometría, lo que permitió aislar el efecto de la decisión de carga.
Otra mejora mantuvo exactamente la misma cantidad de triángulos del terreno. Las mallas indexadas reutilizan los vértices que comparten los triángulos vecinos, en lugar de repetir sus datos de posición, color y normales. En las seis capas de suelo de la prueba con calidad de terreno Alta, el volumen de los búferes transferidos bajó de unos 35 MB a 15 MB, conservando los 241 952 triángulos. El suelo y los elementos del escenario también pasaron a generarse en tareas separadas, de modo que la geometría del suelo pudiera estar lista sin esperar a la decoración.
También se desperdiciaba trabajo en el selector de terreno. Podía solicitar fragmentos, cambiar de decisión, descartarlos y solicitar otros. Astra estabilizó esas decisiones de refinamiento e hizo que una tesela solo se refinara cuando el presupuesto de recursos permitiera generar sus cuatro teselas hijas. En una simulación controlada con latencia fija de los workers, seis segundos de descenso seguidos de tres segundos de estabilización produjeron 13 tareas descartadas en lugar de 6074.

En una simulación controlada con dos workers y una latencia simulada de 100 ms por worker, las tareas programadas que se descartaron bajaron de 6074 a 13. Esto mide la programación de tareas de terreno, no la tasa de fotogramas.
Los workers por sí solos no resuelven todas las pausas. La generación de terreno de respaldo en el hilo principal también necesitaba ceder el control. Astra dividió la generación en pasos reanudables con un presupuesto de aproximadamente 4 ms por fotograma, para que una tarea grande de terreno no tuviera que completarse en un solo bloque sin interrupciones. El renderizador también limita la resolución del mundo por separado de la interfaz, lo que mantiene nítido el texto de navegación cuando se reduce la calidad visual.
Estas mediciones del terreno muestran menos geometría, menos datos transferidos y menos trabajo descartado. No son pruebas de rendimiento de la tasa de fotogramas del hardware. Probar el juego en el navegador sigue siendo importante para evaluar la compilación de shaders, las transferencias a la GPU, el movimiento y cómo se ve realmente la transición.
Mi aporte consistía en comentarios después de jugar: qué se sentía lento, qué se veía mal y qué quería mejorar. Astra rastreó el código, escribió scripts para pruebas de terreno repetibles y registró las mediciones. Una vez que aprobé el enfoque, implementó los cambios y volvió a ejecutar las mismas pruebas para comparar los resultados. Llevó a cabo esa investigación e implementación sin que yo tuviera que indicar cada paso, mientras seguía revisando cómo se veía y se sentía el juego.
Convierte el arte conceptual en recursos para el juego
La mayor parte del universo se genera con código: planetas, terreno, nubes, anillos y estrellas. La nave del jugador es el principal recurso 3D modelado, y con ella seguí un enfoque diferente.
Usé diseños conceptuales generados y renders de Blender para revisar la nave antes de incorporarla al juego. Cuando las alas no coincidían con lo que tenía en mente, pedí referencias más útiles:
Genera vistas claras de esta nave desde varios ángulos. Presta atención a las alas delanteras y traseras. Usaremos esas imágenes para rehacer el modelo 3D. No me gustan las alas unidas y redondeadas del modelo actual.
Elegí la referencia con cuatro alas separadas, una forma simétrica y luces rosas en las puntas. Luego le pedí a Astra que creara un nuevo modelo en Blender, mantuviera el estilo artístico del juego y lo incorporara.
Eso implicó convertir la referencia en geometría, revisar la silueta y los materiales, y preparar un recurso para usar durante la ejecución. El archivo fuente de Blender tiene 193 mallas editables. La nave exportada tiene 14 968 triángulos, agrupados en ocho lotes de materiales opacos. Podía pedir más detalle en el modelo mientras Astra mantenía bajo control el costo de renderizado del recurso exportado.

El diseño conceptual generado de la nave que aprobé.

Un render de Blender del modelo utilizado en el juego.
Experimenta con agua procedural
También dediqué mucho tiempo a experimentar con el agua en Sunwake, un juego en el que se pilota una pequeña embarcación por un océano procedural. Quería olas facetadas, un movimiento suave y los colores de un vitral. Astra creó un renderizador de agua personalizado en Three.js, con el mismo modelo de olas para controlar el mar visible y la flotación de la embarcación. El casco sube, cabecea y se balancea con las olas, mientras una simulación local transporta ondulaciones y espuma, y la embarcación deja estelas y salpicaduras. Más adelante, le pedí a Astra que creara una embarcación más detallada en Blender y la incorporara al juego. Es el mismo enfoque de Void Explorer: un entorno procedural con un vehículo modelado, conectados mediante la simulación.

Sunwake combina un océano procedural con una embarcación modelada en Blender.
Hollowflux llevó esta idea en otra dirección: un pequeño RPG de acción en 2D centrado en un río subterráneo luminoso. Las cuevas, los personajes y el equipo se dibujan con código, sin hojas de sprites importadas. Le seguí pidiendo a Astra que hiciera que caminar, desplazarse con rapidez y atacar alteraran el agua de forma más convincente. Una cuadrícula de celdas registra la altura del agua, las corrientes, la espuma y la carga eléctrica. Los pasos dejan ondulaciones, las estocadas de lanza abren estelas estrechas y los golpes de martillo generan anillos. Las corrientes se curvan a lo largo de las orillas y llevan la espuma río abajo, mientras ese mismo flujo empuja al jugador y a los enemigos. El agua también influye en el combate: la descarga de una anguila se propaga por el agua conectada, así que pisar una piedra seca protege al jugador de esa descarga.

Hollowflux dibuja los gráficos del juego con código, con agua que reacciona al movimiento y al combate.
Crear y compartir juegos
Lo que me gusta de trabajar con Astra es que puedo partir de la experiencia que quiero, usar imágenes para concretar la dirección visual y dar comentarios después de jugar. Una queja sobre un planeta que desaparece puede llevar a cambios en el streaming, la geometría y el movimiento. Pedir agua más convincente puede dar lugar a una simulación compartida por los gráficos y la jugabilidad. Todavía me toca decidir si el resultado se siente bien, pero Astra puede llevar esas decisiones al código, los recursos y las pruebas.
Compartir un juego de navegador también es sencillo. Con el complemento Sites, puedes pedirle a Astra:
Publícalo con acceso público y cualquiera podrá jugar directamente en su navegador.
Puedes jugar Void Explorer, Sunwake y Hollowflux en tu navegador.
Si tienes una idea para un juego, intenta crear una pequeña versión jugable con Astra. Empieza por un aspecto que quieras que se sienta bien, dale algunas referencias visuales y prueba el resultado. Una embarcación, una habitación o una sola interacción bastan para empezar. Juega, especifica qué quieres cambiar y sigue construyendo a partir de ahí.