Snake arcade con estética vaporwave/synthwave de los 90. Comer no solo alarga: hay cajas sorpresa cuyo botín mejora según tu racha, bloques letales que terminan la partida, y 13 niveles con identidad visual y sonora propia.
Cero archivos de assets. No hay sprites, ni música, ni fuentes en disco: los fondos, las entidades, la tipografía bitmap y la banda sonora completa se generan en runtime desde código.
| Capa | Tecnología | Versión | Por qué |
|---|---|---|---|
| Motor | Phaser 3 | 3.90.0 |
Pipelines de shader propios, escenas paralelas para el HUD, control fino de render texture. |
| Lenguaje | TypeScript | 7.0.2 |
Modo strict en toda la lógica de juego. Target ES2020, módulos ESNext. |
| Build | Vite | 8.1.5 |
HMR instantáneo en desarrollo, bundle estático para producción. |
| Renderer | WebGL (Phaser.WEBGL forzado) |
— | Los shaders de bloom y CRT son obligatorios; no hay fallback a Canvas. |
| Gráficos | GLSL (shaders escritos a mano) | — | Bloom, CRT y glitch como pipelines propios de Phaser. |
| Audio | Web Audio API | nativa | Motor de síntesis propio: secuenciador, osciladores y filtros. Cero archivos de audio. |
| Persistencia | localStorage |
nativa | Récords por modo, nivel máximo y ajustes. Degrada sin romper si no está disponible. |
| Runtime de dev | Node.js | 24.x |
Solo para el toolchain; el juego corre 100% en el navegador. |
Dependencias de producción: una sola (phaser). Sin librerías de física, tweening, partículas, UI ni audio. Todo lo demás es código del proyecto.
- 13 niveles — MIAMI SUNSET · NEON GRID · TERMINAL · AQUA / 水 · TOKYO NIGHT · PRISM PEAK · OUTRUN · DIGITAL VOID · VAPOR TEMPLE · SYSTEM OVERLOAD · PIXEL POCKET · GRID HORIZON · LIGHTFALL. Cada uno con su paleta, fondo, efectos ambientales, velocidad y perfil sonoro.
- 3 modos —
NORMAL(5 vidas, tiene final) ·RUNNER(sin vidas, un golpe y se acabó) ·RANDOM(infinito, niveles al azar, 3 vidas). - 20 botines en 4 rarezas (
MALO/COMÚN/RARO/ÉPICO), con reglas de stacking y máximo de 3 efectos simultáneos. - Sistema de racha con combo meter que se drena en tiempo real. Cuanto más larga la racha, mejores las probabilidades de botín — y el blip de comer sube un semitono por punto.
- Game feel — screen shake basado en trauma (curva cuadrática, offset redondeado a píxel entero), hit-stop, zoom punch, partículas y flashes por evento.
- Accesibilidad — respeta
prefers-reduced-motion, más un ajuste manual de intensidad de efectos (0% / 50% / 100%). Los bloques letales se distinguen por color y rayas diagonales y contorno parpadeante, así que se leen sin visión cromática.
Todo el juego se dibuja a 480 × 270 px internos (16:9 exacto) y se escala por números enteros (×2 → 960×540, ×4 → 1920×1080) con nearest neighbor. Grilla de celdas de 16×16, tablero base de 30×15 celdas que cada nivel puede recortar con su propio boardInset, y banda de HUD de 30px arriba.
El HUD vive en su propia escena paralela para que el screen shake nunca lo mueva.
GameScene → capa de emisión → BloomPipeline (threshold + blur de 2 pasadas)
→ upscale ×N nearest → CRTPipeline (scanlines, aberración, viñeta)
El bloom va antes del upscale para que el halo respete la escala del pixel art; el CRT va después, en espacio de pantalla, para que las scanlines se vean como un monitor real y no como bandas gigantes.
Secuenciador de 16 pasos con 4 canales (bajo, lead, pad, percusión). Cada nivel define un AudioProfile con BPM, escala, forma de onda por canal, patrón de notas, cutoff y delay. Los SFX se construyen como osciladores efímeros con envolventes; la estática es ruido blanco filtrado.
El AudioContext arranca solo tras el primer input del usuario, por la política de autoplay de los navegadores. De ahí el > PRESS ANY KEY TO INITIALIZE de la pantalla de título.
src/
config/ resolución, grilla, paletas, los 13 niveles, tabla de botín, sets musicales
core/ máquina de estados, grilla, bus de eventos tipado, persistencia, modos
systems/ serpiente, spawns, racha, power-ups, puntuación, niveles, juice, partículas, audio
pipelines/ BloomPipeline, CRTPipeline, GlitchPipeline (GLSL)
scenes/ TitleScene, GameScene
ui/ fuente bitmap dibujada a mano, banners, marcos estilo Win9x
debug/ consola de debug en pantalla
tools/ scripts de análisis de paleta de las referencias (no entran al build)
Requiere Node 20+ y pnpm.
pnpm install
pnpm dev # servidor de desarrollo en http://localhost:5173
pnpm typecheck # tsc --noEmit en modo strict
pnpm build # typecheck + bundle de producción en dist/
pnpm preview # sirve el build de producciónDurante la partida, la tecla ` abre una consola en pantalla que permite disparar cualquiera de los 20 botines, forzar el fin del nivel o saltar al nivel 10, con un panel de estado en vivo (racha, tier, efectos activos, bloques, meter). Está disponible también en el build de producción.
Flechas o WASD. En táctil, swipe con umbral de 20px. El input tiene un buffer de 2 entradas: podés encolar dos giros en un mismo tick y ambos se ejecutan en ticks consecutivos.
pnpm buildDespués hay que empaquetar el contenido de dist/ en un zip con index.html en la raíz (no dentro de una subcarpeta), subirlo como proyecto de tipo HTML y marcar la casilla "This file will be played in the browser". Viewport recomendado: 960 × 540.
Cuidado con
Compress-Archiveen Windows. PowerShell 5.1 escribe las rutas internas del zip con barra invertida (assets\index.js), lo cual viola el formato ZIP — que exige/. itch.io lo extrae como un único archivo llamado literalmenteassets\index.jsen la raíz, el<script src="./assets/index.js">da 404 y el juego queda en pantalla negra. Usá una herramienta que respete el formato (7-Zip,zip, o la API de .NET controlando los nombres de entrada).
vite.config.ts ya define base: './', necesario para que las rutas funcionen dentro del iframe de itch.io.
Las carpetas de referencia visual de la fase de diseño (refs/, ilustraciones-niveles/) están fuera del repo: no entran al build y pesan más que el código entero. El juego compila y corre sin ellas.