DevLog #01 — Empezando Raccoon: de la idea a un proyecto limpio
Probando la aceleración, salto y colisiones del juego indie en su estado más puro antes de agregar arte.
Este es el primer devlog de Raccoon, el juego de acción 2D que estamos haciendo como parte del equipo de nakama.
La idea de estos devlogs es ir documentando el proceso conforme vamos construyendo el juego. No queremos mostrar solamente el resultado final, sino también las decisiones que vayamos tomando, los problemas que nos encontremos y, sobre todo, ver cómo va evolucionando esto.
La verdad es que no tenemos idea de cómo va a terminar.
Pero empecemos.
El código está en GitHub: Hector0122/RacconCyberpunk.
Primero que nada: la idea
Antes de arrancar a programar tuvimos que hacer algo que parece bastante obvio: regresar al punto cero y dejar clara la idea.
Si no hacemos eso, el proyecto se vuelve caótico bastante rápido. Empiezas agregando una cosa, luego otra, después otra más... y cuando te das cuenta ya estás intentando hacer tres juegos diferentes al mismo tiempo.
Así que, por ahora, la idea es hacer un juego sencillo que cumpla con algunas cosas:
- Un juego 2D de plataformas como los de toda la vida. Nos estamos inspirando en juegos como Katana Zero, Blasphemous y Dead Cells.
- La mecánica principal será ir avanzando por niveles y encontrando máscaras que nos den habilidades especiales. Una podría permitirnos volvernos invisibles durante un tiempo, otra darnos más velocidad y otra permitirnos saltar mucho más alto. Básicamente, power-ups de toda la vida, pero con máscaras.
- Para el MVP de esta primera fase queremos que el jugador pueda correr, saltar y atacar, que tenga vida, que haya enemigos que patrullen y puedan ser destruidos, y que exista un punto de inicio y uno de final.
Por el momento, las máscaras pueden esperar.
Pero lo más importante fue definir una regla:
Antes de ponernos a dibujar píxeles, hacer la música o escribir una historia complicada —aunque, si soy honesto, ya tenemos una idea— el juego tiene que ser divertido. Para eso vamos a utilizar sprites temporales o simples figuras.
Esto puede parecer lo más obvio del mundo.
Pero al principio para nosotros no lo fue.
Y ver cuadritos moviéndose por la pantalla fue un pequeño golpe de realidad que no nos agradó del todo.
Preparar Unity
Con una idea más o menos aterrizada, tocaba crear el proyecto.
Había usado Unity anteriormente en un proyecto de la escuela, hace varios años, así que no empezábamos completamente desde cero. Pero tampoco es que tuviera experiencia haciendo videojuegos como tal.
Para este proyecto estamos usando Unity V6 y la plantilla Universal 2D.
Seguramente las versiones seguirán cambiando mientras hacemos Raccoon, así que iremos actualizando estos devlogs si algo importante cambia.
Desde el principio instalamos también los módulos de Web y Android.
La razón es sencilla: queremos poder publicar el juego en itch.io desde una etapa temprana, compartirlo con amigos y recibir comentarios mientras todavía estamos a tiempo de cambiar cosas.
No queremos esperar a terminar el juego para descubrir que algo que a nosotros nos parecía divertido en realidad no lo es.
Si estás empezando desde cero, realmente no hay mucho misterio aquí: creas un proyecto de Unity usando la plantilla Universal 2D y tienes una base bastante sólida para comenzar.

Esta es la pinta que tiene el juego en este momento.
No tenemos arte bonito. No hay efectos. No hay música.
Solo son cuadros que se mueven y se pegan.
Y por ahora sentimos que estamos bien.
Un mundo hecho de cuadritos
Lo primero que queríamos ver era algo moviéndose en pantalla.
No teníamos dibujos, así que decidimos que todo serían cuadros de colores: el jugador cyan, los enemigos rojos, la meta verde y el suelo gris.
En vez de acomodar cada cosa a mano en el editor, hicimos un script que arma el nivel completo cada vez que le damos Play.
Suena más complicado de lo que realmente es, y para nosotros terminó siendo bastante práctico. Si una plataforma quedaba demasiado alta, cambiábamos un número y volvíamos a probar.
La primera sorpresa llegó muy rapido.
Pusimos el suelo, pusimos al jugador, le dimos Play...
Y el cuadro cyan atravesó el suelo y desapareció.
Ahí aprendimos una de las primeras lecciones de Unity 2D:
Que algo se vea no significa que exista.
El dibujo es una cosa y lo que la física realmente puede tocar es otra: un collider.
Sin él, nuestro suelo era básicamente un dibujo muy bonito que no servía para detener absolutamente nada.
Desde entonces, cada cuadro que se puede pisar tiene su propia caja de colisión.

El cuadro que rodaba
Con el suelo ya firme, le pusimos gravedad al jugador.
Y apareció otro problema.
Cuando chocaba con la orilla de una plataforma, el cuadro se volteaba y empezaba a rodar como un dado.
Gracioso las primeras veces.
Después ya no tanto.
La física estaba haciendo exactamente lo que debería hacer con una caja. El problema es que nuestro personaje no es una caja.
Así que simplemente bloqueamos su rotación.

Después vino el salto.
Con la gravedad por defecto, el personaje subía demasiado lento y bajaba flotando como si estuviera en la Luna. No tenía nada que ver con la sensación rápida que buscábamos.
Así que empezamos a mover números.
Probamos una gravedad más alta, luego otra, luego otra...
Hasta que llegamos a un valor que nos gustó.
También teníamos otro problema: el personaje se quedaba atorado en las esquinas de las plataformas.
La solución fue hacer su caja de colisión un poquito más angosta que el dibujo.
A simple vista casi nadie lo nota.
Pero al jugarlo sí se siente.
Saltar... una y otra vez
Hacer que el personaje saltara fue relativamente fácil.
Al presionar el botón, le damos un empujón hacia arriba.
El problema era que podía saltar siempre.
También en el aire.
Presionabas el botón varias veces y el cuadro empezaba a volar hasta salirse de la pantalla.
Necesitábamos que el juego supiera si el personaje tenía los pies en el suelo.
Lo resolvimos con una pequeña caja invisible debajo de sus pies. Si esa caja toca el suelo, puede saltar. Si no, pues no.

Sencillo.
Después apareció un problema más raro.
A veces presionábamos el botón de salto y no pasaba nada.
No siempre.
Solo de vez en cuando.
Y eso es justamente lo peor cuando estás intentando encontrar un bug.
Resultó que Unity lee los botones a un ritmo y calcula la física a otro. En algunas situaciones el botón se estaba leyendo en un momento en el que la física todavía no había tenido oportunidad de reaccionar.
La solución fue hacer que el botón simplemente dejara una pequeña nota de “quiere saltar” y que la física leyera esa nota cuando le tocara.

Desde ahí no volvimos a perder un salto.
Los números finales —velocidad 8 y fuerza de salto 14— tampoco salieron de ninguna fórmula.
Los fuimos cambiando con el juego corriendo hasta que, simplemente, se sintió bien.
Caer para siempre
Con plataformas en el aire, alguien tenía que caerse.
Y se cayó.
El cuadro siguió bajando y bajando mientras la cámara lo veía desaparecer. El juego nunca terminaba porque, técnicamente, el jugador seguía vivo.
Pensamos en poner zonas de muerte, triggers y alguna solución más elaborada.
Al final bastó con una regla:
Si el jugador baja de cierta altura, pierde.
Es un número y una condición.
El juego se congela, aparece la pantalla para reiniciar y listo.
La cámara
Nuestro nivel ya era más ancho que la pantalla, así que necesitábamos que la cámara siguiera al jugador.
Primero hicimos lo más obvio: pegarla directamente al personaje.
El resultado fue bastante incómodo.
Cada pequeño movimiento del jugador hacía que toda la pantalla se moviera con él.
Así que cambiamos la cámara para que lo siguiera con un pequeño retraso, acercándose poco a poco a la posición del personaje.
Y de repente el juego se sintió mucho más suave.
Es una de esas cosas que probablemente nadie nota cuando funciona bien, pero que se sienten inmediatamente cuando funcionan mal.
Los enemigos
Los enemigos son, por ahora, cuadros rojos que caminan de un lado a otro, llegan a una zona, se dan la vuelta y regresan.
Si te tocan, pierdes una vida.
Tenemos tres.
Y aquí también apareció una sorpresa.
Un solo choque nos quitaba las tres vidas de golpe.
El enemigo seguía tocando al jugador durante varios frames y cada uno de esos frames contaba como otro golpe.
La solución fue bastante sencilla y es algo que probablemente encontraremos muchas veces durante el desarrollo: después de recibir daño, el jugador parpadea y se vuelve invencible durante un segundo.
Para defenderse, el jugador lanza un golpe.
Por un instante aparece una caja delante de él y, si esa caja toca a un enemigo, el enemigo desaparece.
Y con eso, casi sin darnos cuenta, ya teníamos lo que nos habíamos propuesto:
Correr.
Saltar.
Atacar.
Vidas.
Enemigos que patrullan.
Un inicio.
Una meta.
Todo con cuadritos.
Si quieres intentarlo
Hasta aquí hemos contado la parte divertida del desarrollo.
Ahora viene la parte para quien quiera abrir Unity y probarlo por su cuenta.
Casi todo lo que vimos arriba se puede configurar desde el Inspector de Unity, sin escribir código.
- Que no atraviese el suelo: agrega un
Box Collider 2Dal suelo y otro al jugador. - Que caiga: agrega un
Rigidbody 2Dal jugador. - Que no ruede: en
Rigidbody 2D→ Constraints → marca Freeze Rotation Z. - Que el salto tenga más peso: en
Rigidbody 2D→ Gravity Scale puedes aumentar el valor. Nosotros usamos 3, mientras que el valor normal es 1. - Que no atraviese cosas a mucha velocidad: en
Rigidbody 2D→ Collision Detection selecciona Continuous. - Que no se atore en las orillas: en su
Box Collider 2D, haz el Size en X un poco más pequeño que el dibujo. Nosotros usamos 0.8.
El salto, la pequeña caja que usamos para comprobar si el jugador está en el suelo y la caída al vacío sí son código.
Están en PlayerController.cs y PlayerHealth.cs dentro del repositorio.
Los valores que fuimos ajustando, como moveSpeed, jumpForce y killY, también están expuestos en el Inspector para poder modificarlos rápidamente mientras probamos el juego.
Y eso es todo por ahora.
No parece gran cosa.
Pero hace unas horas teníamos una idea y unos cuantos cuadros.
Ahora tenemos un pequeño juego que podemos jugar.
Para el siguiente devlog vamos a contar algo que probablemente sea incluso más interesante: cómo estamos usando un agente de IA para ayudarnos a construir Raccoon y qué pasa cuando le damos acceso al proyecto.