⏱️ Lectura: 14 min

Un desarrollador independiente está construyendo Catlantean 3D, un shooter en primera persona hecho enteramente a mano con las restricciones de los gráficos VGA de 1993: resolución de 320×240, una paleta de 256 colores y un motor de raycasting sin aceleración por hardware. El proyecto lleva más de un año en desarrollo y apunta a Steam en 2027.

📑 En este artículo
  1. TL;DR
  2. ¿Qué es Catlantean 3D y qué pasó?
  3. Mode 13h y Mode-X: los gráficos VGA de 320×240
  4. La paleta: 768 bytes que definen todo
  5. El colormap: iluminación sin shaders
  6. Crear assets bajo 256 colores
  7. El raycaster y el algoritmo DDA
  8. Por qué los límites producen mejor arte
  9. Cómo probar un raycaster vos mismo
  10. Qué sigue
  11. Preguntas frecuentes
    1. ¿Qué es un raycaster y en qué se diferencia de un motor 3D moderno?
    2. ¿Por qué solo 256 colores si las PC de los 90 podían más?
    3. ¿Qué es un colormap y para qué sirve?
    4. ¿Puedo escribir un raycaster en cualquier lenguaje?
    5. ¿Cuándo sale Catlantean 3D?
  12. Referencias

Más allá del juego, el caso reabre una pregunta que vale para cualquier programador: ¿por qué imponerse los límites del pasado produce, a veces, mejores resultados que la libertad infinita del hardware actual?

TL;DR

  • Catlantean 3D es un FPS hecho desde cero (gráficos, audio y motor) con técnicas comunes en la PC de principios de los 90.
  • Restricciones autoimpuestas: 320×240, 256 colores, renderizado y mezcla de audio a mano, y nada de contenido generado por IA.
  • El motor es un raycaster clásico estilo Wolfenstein 3D, con algoritmo DDA por cada columna de pantalla.
  • La paleta son 768 bytes: 256 colores por 3 canales RGB, elegidos a mano tras muchas iteraciones.
  • La iluminación usa un colormap: una tabla precalculada que oscurece colores según la distancia para dar profundidad.
  • Usa punto fijo para la lógica de juego (determinismo) y punto flotante para el renderizado.
  • El autor planea lanzarlo en Steam en 2027; el diario de desarrollo se publicó el 9 de junio de 2026.

¿Qué es Catlantean 3D y qué pasó?

El 9 de junio de 2026, el desarrollador Marko Stanic publicó el primer diario de desarrollo de Catlantean 3D, un juego que describe como «hacer gráficos como si fuera 1993». La premisa es un ejercicio de disciplina técnica: construir un FPS completo, pulido y divertido —no una demo técnica— usando las técnicas que dominaban la PC de principios de los 90, pero con la comodidad de un compilador moderno y una capa de abstracción de plataforma mínima.

Las reglas que se autoimpuso son severas. Todo el juego debe hacerse desde cero, incluidos los assets. Todo el renderizado se programa a mano, pixel por pixel. Toda la mezcla de audio se hace a mano, muestra por muestra. El objetivo es 320×240 con 256 colores. Y una restricción que en 2026 suena casi a manifiesto: «no AI slop», nada de contenido generado automáticamente por IA. La única libertad que se permite es una capa de plataforma —framebuffer, entrada de teclado y mouse, buffer de audio y E/S de archivos— que debe tratar como si fuera muy limitada.

La ambientación ayuda a entender las decisiones técnicas: el juego ocurre en Catlantis, una parodia del antiguo Egipto poblada por gatos y ocupada por hombres-perro cibernéticos. Esa premisa absurda condiciona la paleta, las texturas y hasta el diseño de niveles, como veremos.

📌 Nota: «Slop» es jerga para contenido generado en masa por IA sin curaduría. Que un desarrollador lo prohíba explícitamente en sus reglas dice mucho del momento cultural de la industria en 2026.

Mode 13h y Mode-X: los gráficos VGA de 320×240

Para entender el proyecto hay que volver a los gráficos VGA. El famoso Mode 13h fue el modo gráfico de 320×200 y 256 colores que definió a una generación de juegos de PC. Desde la perspectiva del programador era maravillosamente simple: tenías un framebuffer lineal donde cada pixel se representaba con un solo byte, y ese byte era un índice dentro de una paleta de 256 colores.

Para dibujar un pixel escribías un byte en una dirección de memoria. No había shaders, ni VRAM dedicada, ni pipelines programables. Un byte por pixel, y ese byte apunta a un color RGB real en la paleta. Esa simplicidad impone una limitación fascinante: cuando hacés assets para un juego moderno podés tirar millones de colores a una imagen, pero cuando cada pixel en pantalla solo puede ser uno de 256 colores, la creación de assets se vuelve un problema completamente distinto. Cada elección de color tiene que ser deliberada.

Catlantean 3D no usa exactamente Mode 13h sino algo más cercano a Mode-X, que ofrece 320×240. La razón es práctica: 320×200 en una pantalla 4:3 produce pixeles no cuadrados. Sería lo más auténtico, pero el autor prefirió pixeles cuadrados. Así se escribe un pixel en el framebuffer indexado:

// El framebuffer es un arreglo lineal: un byte por pixel.
// Cada byte es un indice (0-255) dentro de la paleta.
uint8_t framebuffer[320 * 240];

void put_pixel(int x, int y, uint8_t color_index) {
    framebuffer[y * 320 + x] = color_index;
}

Juegos como Doom y Duke Nukem 3D son ejemplos de esto bien hecho. Hay una nitidez y una claridad en esos gráficos que nace gracias a las limitaciones, no a pesar de ellas. La restricción fuerza decisiones deliberadas, y las decisiones deliberadas tienden a verse bien.

Captura estilo VGA de 256 colores con pasillos y texturas pixeladas
Los gráficos VGA limitan cada pixel a uno de 256 colores.

La paleta: 768 bytes que definen todo

Todo empieza con 768 bytes: 256 colores por 3 canales (rojo, verde, azul). Esa paleta no apareció de golpe; se construyó con muchísima prueba y error durante la creación de assets. El razonamiento detrás de los colores elegidos revela cómo se piensa el arte bajo restricción.

  • Un color reservado para transparencia — el clásico rosa vibrante (magenta) que el motor interpreta como «no dibujar».
  • Blanco puro y negro puro reservados, porque se necesitan como referencias fijas.
  • Muchos rojos — el juego iba a tener mucha sangre.
  • Verdes y azules para llaves y puertas codificadas por color (rojo, verde, azul).
  • Amarillos y marrones — Catlantis evoca el desierto egipcio.
  • Muchos grises para las instalaciones técnicas de los hombres-perro cibernéticos.
  • Beiges para romper la monotonía de los grises y servir como reemplazo cálido al oscurecer.

El resto de los colores se llenó según hacía falta al crear texturas, algo que el propio autor admite que es «altamente subjetivo e imposible de explicar, salvo que se veía bien». Esa honestidad es valiosa: gran parte del arte retro vive en decisiones que no se pueden justificar con una métrica.

💭 Clave: En una paleta de 256 colores cada color es un recurso escaso. Reservar uno para transparencia y dos para blanco y negro deja 253 índices para todo el juego: paredes, enemigos, sangre, llaves y cielo.

El colormap: iluminación sin shaders

Acá está, según el autor, el aspecto más subestimado del raycasting: la iluminación. Si renderizáramos el mundo usando solo la paleta, sin efectos, el resultado se vería plano y poco interesante. Lo que queremos es que la luz disminuya con la distancia y que un lado de cada tile sea apenas más oscuro que el otro, para dar sensación de profundidad.

En hardware moderno esto se resuelve con un shader que multiplica el color por un factor de luz. Pero en un motor de paleta no podés multiplicar un índice: el índice 50 por 0.5 no significa nada. La solución de los 90, que Catlantean 3D reproduce, es el colormap: una tabla precalculada que, para cada nivel de luz y cada color de la paleta, dice qué otro índice representa ese color oscurecido.

// colormap[nivel][color] -> indice mas oscuro equivalente en la paleta
// 32 niveles de luz, 256 colores
uint8_t colormap[32][256];

for (int level = 0; level < 32; level++) {
    float factor = (float)level / 31.0f; // 0 = negro, 1 = brillo pleno
    for (int c = 0; c < 256; c++) {
        RGB target = {
            palette[c].r * factor,
            palette[c].g * factor,
            palette[c].b * factor
        };
        colormap[level][c] = nearest_palette_index(target);
    }
}

Doom usaba exactamente esta técnica con 32 niveles de luz. En tiempo de ejecución, iluminar un pixel no es una multiplicación de punto flotante sino una simple búsqueda en tabla: colormap[nivel_de_luz][color_original]. Es rapidísimo y determinista, justo lo que necesitabas en una CPU sin FPU potente. Aquí también se explica por qué el autor incluyó beiges en la paleta: al oscurecer ciertos grises, un reemplazo cálido evita que la imagen se vuelva gris-azulada y muerta.

Crear assets bajo 256 colores

El artículo destaca algo que casi ningún blog de desarrollo cubre: cómo se crean los assets. Hay tres caminos, y Catlantean 3D usa los tres.

  • Sprites pre-renderizados — modelar en 3D y renderizar a 2D, luego cuantizar a la paleta. Es la técnica de Donkey Kong Country y de los enemigos de Doom.
  • Sprites y texturas dibujados a mano — pixel art directo, color por color, con la paleta fija como restricción.
  • Sprites y texturas generados proceduralmente — ruido, patrones y algoritmos para texturas que serían tediosas de hacer a mano.

La cuantización a paleta es el paso crítico común a varios de estos flujos. Tomás una imagen de millones de colores y la reducís a 256 índices buscando, para cada pixel, el color más cercano de la paleta. Un esquema típico de difuminado (dithering) reparte el error entre pixeles vecinos para simular colores intermedios. Bajo estas reglas, el dithering no es un truco estético opcional: es la herramienta principal para fingir profundidad cromática que la paleta no tiene.

Comparación de una textura a todo color frente a su versión cuantizada a 256 colores
La cuantización reduce millones de colores a 256 índices con dithering.

El raycaster y el algoritmo DDA

Catlantean 3D es un raycaster tradicional. El mapa es una grilla de tiles del mismo tamaño; algunos son paredes y otros son vacíos con piso y techo. Para renderizar, el motor usa el algoritmo DDA (Digital Differential Analyzer) en cada columna de la pantalla: avanza por la grilla determinando dónde el rayo golpea la geometría, y según eso dibuja una columna de pared con la textura correspondiente, muestreada en las coordenadas adecuadas. Pisos y techos se rellenan después como líneas horizontales.

El flujo conceptual del renderizado por columna se ve así:

graph LR
    A[Columna de pantalla] --> B[DDA sobre el tilemap]
    B --> C[Impacto con pared]
    C --> D[Muestrear textura]
    D --> E[Aplicar colormap por distancia]
    E --> F[Escribir columna al framebuffer]

Y el núcleo del bucle, muy simplificado, combina el raycasting con el colormap que vimos antes:

// Por cada columna x de la pantalla lanzamos un rayo
for (int x = 0; x < SCREEN_W; x++) {
    float camera_x = 2.0f * x / SCREEN_W - 1.0f;
    // ... calcular direccion del rayo y ejecutar DDA sobre el tilemap ...
    int light = clamp(31 - (int)(perp_dist * 2.0f), 0, 31);
    uint8_t texel = sample_texture(tex_id, tex_x, tex_y);
    draw_column(x, wall_height, colormap[light][texel]);
}

Hay un detalle de ingeniería elegante en las reglas del proyecto: la lógica de juego usa punto fijo para garantizar comportamiento determinista entre plataformas, mientras que el renderizado usa punto flotante porque ahí el determinismo no importa tanto. Esa separación es una decisión de diseño que muchos motores modernos también toman para replays y multijugador.

💡 Tip: Si querés determinismo (replays, netcode lockstep, tests reproducibles), evitá el punto flotante en la lógica que afecta el estado del juego. El punto fijo con enteros es predecible en cualquier CPU.

Por qué los límites producen mejor arte

El hilo conductor de todo el proyecto es una tesis: la restricción fuerza decisiones deliberadas, y las decisiones deliberadas tienden a verse bien. No es nostalgia vacía. Cuando podés usar cualquier color, cualquier resolución y cualquier polígono, el espacio de decisiones es tan grande que es fácil perderse en él. Cuando tenés 256 colores y 320×240, cada elección importa y el resultado tiene una identidad coherente.

Para el desarrollador en LATAM esto tiene una lectura práctica más allá del pixel art. Imponerse límites artificiales —un presupuesto de dependencias, una sola base de datos, un único lenguaje, un binario que arranca en menos de 100 ms— suele producir software más nítido que la libertad de usar lo que sea. La restricción es una herramienta de diseño, no un castigo.

También hay una lección sobre el oficio. Programar el renderizado y la mezcla de audio a mano no es eficiente en horas de trabajo, pero obliga a entender qué pasa en cada capa. En una era de motores que esconden todo detrás de abstracciones, reconstruir lo básico es una de las mejores formas de aprender de verdad cómo funciona una computadora.

Cómo probar un raycaster vos mismo

No hace falta esperar a Catlantean 3D para experimentar con estas técnicas. El camino más accesible hoy es usar una capa de plataforma mínima como SDL2, que te da exactamente lo que el autor se permitió: un framebuffer, entrada y audio. Instalación según tu sistema:

# Windows (vcpkg)
vcpkg install sdl2

# macOS (Homebrew)
brew install sdl2

# Linux (Debian / Ubuntu)
sudo apt install libsdl2-dev

Con SDL2 podés crear una textura del tamaño de tu framebuffer indexado, escribir bytes a mano y volcarla a pantalla cada frame. A partir de ahí, implementar el bucle DDA de la sección anterior es un fin de semana de trabajo para un primer raycaster funcional. El tutorial clásico de Lode Vandevenne (en Referencias) sigue siendo la mejor guía paso a paso, y es perfectamente vigente en 2026.

Qué sigue

Según el autor, lo mostrado es trabajo en progreso y sujeto a cambios. El plan es lanzar Catlantean 3D en Steam en 2027, y el diario de desarrollo continuará cubriendo otros aspectos del motor. El primer artículo se concentró deliberadamente en la creación de assets y el renderizado de paleta, dos temas que la mayoría de los blogs de desarrollo pasan por alto a favor de explicar, una vez más, las matemáticas del raycasting.

Para la comunidad hispana de desarrollo de juegos, el proyecto es un recordatorio oportuno: con herramientas modernas y disciplina técnica, una sola persona puede construir un juego completo con una identidad visual que ningún asset store puede replicar. La restricción, bien usada, es una ventaja competitiva.

📖 Resumen en Telegram: Ver resumen

Preguntas frecuentes

¿Qué es un raycaster y en qué se diferencia de un motor 3D moderno?

Un raycaster lanza un rayo por cada columna de la pantalla sobre una grilla de tiles 2D y dibuja una columna de pared por impacto. No procesa polígonos en 3D real ni usa la GPU: todo el cálculo ocurre en la CPU. Wolfenstein 3D popularizó la técnica; un motor moderno, en cambio, rasteriza triángulos con aceleración por hardware.

¿Por qué solo 256 colores si las PC de los 90 podían más?

Es una restricción autoimpuesta que reproduce el modo VGA de la época. El límite obliga a elegir cada color con cuidado y genera una estética coherente y nítida, igual que en Doom o Duke Nukem 3D.

¿Qué es un colormap y para qué sirve?

Es una tabla precalculada que, para cada nivel de luz y cada color de la paleta, guarda qué índice representa ese color oscurecido. Permite iluminar la escena con una simple búsqueda en lugar de multiplicar colores, algo imposible cuando trabajás con índices de paleta.

¿Puedo escribir un raycaster en cualquier lenguaje?

Sí. La técnica es independiente del lenguaje: hay implementaciones en C, C++, Rust, JavaScript y Python. Solo necesitás poder escribir pixeles en un framebuffer; una librería como SDL2 te da esa capa en casi cualquier plataforma.

¿Cuándo sale Catlantean 3D?

El autor planea lanzarlo en Steam en 2027. Todo lo mostrado en el diario de desarrollo del 9 de junio de 2026 es trabajo en progreso y puede cambiar.

Referencias

📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.

Categorías: Noticias Tech

Andrés Morales

Desarrollador e investigador en inteligencia artificial. Escribe sobre modelos de lenguaje, frameworks, herramientas para devs y lanzamientos open source. Cubre papers de ML, ecosistema de startups tech y tendencias de programación.

0 Comentarios

Deja un comentario

Marcador de posición del avatar

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.