Introducción
En los últimos días he ido reflexionando sobre todo lo que quiero añadirle a mi juego y acerca de la viabilidad de poder añadirlos o no.
Por si aún no os habéis enterado, me encuentro ahora mismo en fase de concepción de un juego que quiero sacar para Game Boy (con su cartucho y todo) y cada viernes quiero compartiros mis avances y reflexiones sobre el diseño y desarrollo del juego, así como lo efectivas o desastrosas que van siendo las metodologías que voy utilizando.
En lo que al juego se refiere, se trata de un RPG clásico, con tintes de Zelda (para la resolución de mazmorras), Breath of Fire II (como sistema de combates y la elaboración de una aldea propia) y Fire Emblem (con muerte permanente de personajes).
El sistema de combates
Un punto en el que estuve rumiando durante bastante tiempo era el sistema de combates, puesto que mi idea inicial era el de hacer un action-RPG con combates estilo beat’em up, pero las limitaciones de la consola sobre el máximo posible de cuadros que se pueden almacenar en la VRAM de la consola: 25 cuadros de 16x16 píxeles.
Básicamente en esos 25 cuadros debíamos de incluir las distintas animaciones de personajes y enemigos, algo técnicamente imposible si queremos tener una party de 4 personajes y ver al mismo tiempo varios enemigos en pantalla. Así que, con estos datos, la hipótesis de hacer un beat’em up resultó fue descartada de inmediato.
Algo estilo “River City Girls” habría resultado épico, pero no parece viable.
Después estuve reflexionando sobre la posibilidad de hacer un motor estilo “Breath of Fire II”, donde aparte del background (que sería el escenario del combate y que no estaría incluido en el límite de 25 cuadros) deberíamos de ver los enemigos (un máximo de 4 distintos), la party del héroe (un máximo de 4 personajes distintos) y sus distintas animaciones (recibir daño, atacar, estar malherido, lanzar magias…). Si además copiamos “tal cual” el motor del “Breath of Fire II”, hay que tener en cuenta que el personaje se puede transformar en dragón y los personajes deberían de verse con más detalle que en el mapamundi (fuera de los combates). Con estos números queda claro que hacer un motor similar a este juego resulta también inviable, me gustaría hacerlo, pero técnicamente es imposible.
Así que me puse a hacer una lista de todo lo que quería que tuviera el sistema de combates de mi juego:
- Poder ver a 4 enemigos en pantalla.
- Poder tener un grupo de hasta 4 personajes.
- Tener animaciones de ataque, magia y consumo de ítems.
- Poder transformar al personaje principal en dragón.
- Utilizar ítems.
Captura de pantalla del tráiler oficial del RPG Maker XP.
Está claro que, debido a las limitaciones de la consola, no podré hacer algo tan bonito como lo que se ve en la captura de arriba que os comparto (sacada del tailer oficial del RPG Maker XP) y que tendremos que hacer sacrificios en orden de poder mostrar lo mismo, pero de una forma de que se pueda ver toda la información necesaria en la reducidísima resolución de la consola (160x144 píxeles).
Por poneros unos ejemplos, pienso remplazar las miniaturas de los personajes por “portraits” (aka “retratos”) que enfoquen sólo la cara de los personajes. Esos “portraits” variarán en función de si el personaje espera (cuadro normal), ataca o hace magia (compartirán el mismo cuadro) o reciben daño. En caso de muerte, su “portrait” sería remplazado por una calavera. Con todo ello, estamos hablando de consumir 13 cuadros de 16x16 pixeles entre los 4 personajes del grupo del héroe.
Por otro lado, queremos mostrar 4 enemigos en pantalla y que tengan un tamaño decente, por lo que deberían de ocupar 16x32 pixeles. No obstante, duplicar el número de pixeles implica que cada personaje consuma el doble de cuadros y nos quedaban sólo 12 disponibles. Si disponemos de 12 cuadros de 16x16 pixeles y queremos hacer uso de enemigos de 16x32 pixeles, esto implica que contaremos únicamente con 6 cuadros de 16x32 a repartir entre los 4 enemigos… Vamos, que tendremos que hacer enemigos estáticos y reservar únicamente 4 de los 6 cuadros disponibles de 16x32.
Un truco que podemos hacer para simular una animación (y hacer como que atacan) es voltear el cuadro, es decir, aplicarles un modo “espejo”. Por ejemplo, podemos dibujar de forma estática a un enemigo con el garrote en la mano derecha y durante su fase de ataque mostrar brevemente un cuadro donde la imagen esté invertida en el eje X dando una falsa sensación de movimiento.
Con todo ello nos quedarían aún disponibles 4 cuadros de 16x16 píxeles, que podemos emplear para los efectos visuales, por ejemplo:
- Dibujar un “tajo” que se visualice cuando alguien ataque y que se posicione en el personaje que recibe el daño.
- Dibujar burbujitas que se visualicen cuando alguien recibe los efectos de una magia (por ejemplo, para magias curativas).
- Dibujar una llamarada para las magias de fuego, que además podríamos voltear sobre el eje Y para dar sensación de agua o nieve para las magias de tipo hielo.
- Y nos queda un cuadro aún libre por asignar.
Además, podemos jugar con distintos efectos de pantalla para dar la inmersión de las magias o de los ataques: Podemos, por ejemplo, realizar un efecto de “fade-in” a color blanco con su correspondiente “fade-out” cuando apliquemos animaciones de curación; Hacer el mismo efecto pero sobre color negro cuando apliquemos animaciones de ataque; O hacer temblar la cámara cuando apliquemos magia de tierra (por ejemplo, producir un terremoto); Si alguna vez habéis hecho uso de “DIV Games Studio” o de algún “RPG Maker”, seguramente ya conoceréis este tipo de trucos.
Aún así, con este esquema perdemos un punto que me habría gustado incluir y es que el personaje pueda transformarse en dragón. Sencillamente, no podemos tenerlo todo.
Y ahí es cuando he empezado a pensar en una segunda opción, pero que no me gusta y pasa por dibujar los enemigos dentro del “background”. Esto liberaría todos los cuadros de memoria reservados que podríamos emplear, por ejemplo, en las imágenes del “portrait” del dragón e intercambiarlas por las del jugador cuando éste se transforme. La pega de hacer esto es que reduciremos la aleatoriedad definiendo de antemano la lista de enemigos a los que nos enfrentaremos, puesto que tocaría pegarlos directamente en el “background”: Estamos hablando de imágenes estáticas sin ningún tipo de animación y que deberíamos de aplicar pequeños efectos de “tembleque de cámara” cada vez que un enemigo ataca o recibe daño. Encima, muy importante, cada vez que un enemigo muera no se podría quitar de la pantalla y tocaría ponerle una calaverita encima.
No obstante, esta práctica nos aportaría dos ventajas: Más cuadros libres (hablamos de liberar 8 cuadros de 16x16 pixeles) y enemigos de mayor tamaño. Por ejemplo, si reservamos la mitad de la pantalla para los enemigos y dividimos entre 4 el eje X, obtendríamos enemigos de 40x77 pixeles… Un tamaño enorme para un juego de Game Boy y que valdría la pena probar. Y muy importante, podemos hacer jefes finales de 160x77 píxeles.
Pero hay una cosa más a tener en cuenta, aunque la resolución de pantalla de la consola sea de 160x144 pixeles, realmente no hay una necesidad imperiosa de que el background tenga ese tamaño. Podríamos definir, por ejemplo, un background de 800x144 pixeles dividido en 5 regiones: La primera región sería la imagen con los 4 enemigos y las otras 4 regiones veríamos a uno de los enemigos atacar (por ejemplo, en la región 2 dibujamos al enemigo 1 atacando, en la región 3 al enemigo 2 atacando, etc.). Esto nos permitiría simular animaciones (bastaría con desplazar la cámara en el eje X sin efecto de scroll) e incluso podríamos hacer una animación de respiración, creando una nueva región donde modificaríamos levemente el primer cuadro (para ello nuestro background pasaría a tener 960x144 pixeles). Puede parecer un tamaño enorme, pero recordad que hablamos de PNG de apenas 4 colores y que cada escenario de este tipo debería de ocupar entre 4 y 30 KB de espacio. De hecho, he hecho la prueba de redimensionar la imagen de assets más pesada del proyecto de ejemplo de “GB Studio” a 960x144 pixeles y me ocupa 17 KB. Si queremos limitar el tamaño máximo de este tipo de fondos a 1 MB (para reservarnos por ejemplo otro mega para el resto de recursos) esto indica que podríamos tener unos 60 tipos de encuentros distintos, una lista que no está nada mal.
Por cierto, si os lo estáis preguntando, el tamaño máximo documentado para un cartucho de Game Boy es de 2MB. Yo poseo un cartucho de 4MB, por lo que tendré que hacer una prueba para ver si una Game Boy real puede leer roms de 4MB o si tendré que limitarme a esos 2 MB de tamaño máximo. En caso de poder utilizar esos 4MB, mi objetivo es simple: Utilizarlos en mejorar el juego en todo lo que pueda.
No obstante, cabe destacar que todo esto es teórico y que tendré que hacer una prueba de concepto (POC) para ver si es viable. Digo esto porque en la documentación de GB Studio explican que el framework divide los backgrounds en tilesets (subdivisiones de 8x8 pixeles) y se puede contar únicamente con 192 tipos únicos de tilesets. Si dividimos el tamaño de nuestros enemigos (40x77 píxeles) por el tamaño de nuestros tilesets (8x8), obtenemos que cada enemigo consta de unos 50 tilesets… y sin aplicar animaciones. Lógicamente los números no salen, puesto que la suma de los 4 enemigos hace 200 tilesets de los 192 posibles… Claro, si hablamos de enemigos únicos
En el caso de que tengamos un encuentro y los 4 enemigos sean idénticos, realmente estaríamos consumiendo 50 tilesets en la primera región, 50 tilesets más para las regiones donde un enemigo ataca y 50 tilesets para la falsa animación de “respirar”. Y con ello ocuparíamos ya 150 de los posibles 192 tiles.
En pocas palabras, podemos tener combates contra enemigos gigantes, pero tendrán que ser siempre de la misma raza: Podremos enfrentarnos con uno, dos, tres o cuatro dragones; con uno, dos, tres o cuatro góblins; con uno, dos, tres o cuatro slimes… Pero nunca podremos juntar en el mismo combate dragones con slimes o góblins. Se trataría de una limitación técnica con la que tendríamos que contar con el fin de conseguir buenos gráficos en nuestro juego.
El modo exploración
En lo que se refiere a la jugabilidad, me gustaría
contar con un estilo similar al “Link’s Awakening”: Vista aérea, movimiento en
8 ejes (con diagonales), personajes cucos, puzles en medio del mapeado (cortar
llevar, usar un ítem X para desbloquear un área, etc).
El caso es que me gustaría modelar los gráficos en Blender para tener algo que se parezca el “Dokey Kong Land”, pero tras realizar unas pruebas básicas he visto que era inviable. Por ejemplo, he pillado la Midna que he modelado en blender, le he hecho un render de perfil, la he reescalado a 16x32 pixeles y le he reducido el color a una paleta de 4 colores, siendo uno de ellos el color transparente… Y el resultado ha sido horrible: Era imposible distinguir nada. Lo que sí que parece quedar más o menos bien son los escenarios (no es lo mismo comprimir un fondo básico a 160x144 que un personaje a 16x16, lógicamente el escenario consta de más detalle)… Y los personajes creados con el Game Character Hub (una aplicación creada por los creadores de RPG Maker), los cuales también quedan razonablemente bien:
Ejemplo de personaje creado con el “Game Character Hub”, reducido a 6 cuadros de 16x32 (12 cuadros de 16x16) y degradado a 4 colores en tono verdoso y que sirve como animación de caminar.
Si os fijáis en el ejemplo, ese personaje queda realmente precioso para tratarse de un juego de Game Boy, pero ocupa 12 de los 25 cuadros de nuestra VRAM. No obstante, creo que vale la pena apostar por este tipo de personajes. Ahora bien, el coste visual tendría un coste funcional y es que para poder contar con la máxima cantidad posible de NPC en pantalla, estos no podrán moverse: Me reservaría 3 cuadros de 16x32 pixeles para cada uno (uno para mirar a la derecha que aplicaremos en espejo cuando mira a la izquierda; Otro para mirar arriba y otro para mirar abajo), que suponen 6 cuadros más de VRAM (de 16x16 pixeles)… y con esas cifras, los números no salen, podríamos contar únicamente con dos NPC en pantalla, una cifra floja para todo RPG. Además, siempre viene bien contar con un par de cuadros libres en memoria para poder aplicar algún efecto o animación extra.
Hombre, no está mal, pero gráficamente impresiona poco, así que tuve que tomar una difícil decisión: Optar por la solución de tener personajes de 16x32 píxeles, pero hacer que permanezcan estáticos (no se girarían par hablar con el protagonista). Es la única forma que veo posible de tener la máxima cantidad de NPC posible a 16x32 píxeles.
Entonces, resumiendo:
- Contaríamos con 12 cuadros de 16x16 para el personaje principal.
- Reservaría 2 cuadros de 16x16 por NCP. Podemos hacer por ejemplo que salgan únicamente 3 a la vez. (6 cuadros reservados únicamente para NPC). Ahora bien, cabe destacar que podemos tener realmente más NPC en pantalla (los que nos permita el framework), pero que simplemente,a nivel gráfico, podremos mostrar en la misma escena sólo 3 clases de NPC.
- El resto de cuadros (8 en total) irían destinados a destinados a dibujar cofres, ítems u objetos necesarios para completar puzles.
Para disimular el hecho que los personajes no se muevan o miren al personaje, podemos cargar una nueva escena donde se vea en primer plano un dibujo del NPC, como si se tratara de un “The Elder Scrolls” o de un “Fallout” (cuando en esos juegos hablas con un NPC, la cámara se desplaza para apuntar a su cara). De esta forma podemos incluso poner un sistema de diálogos puramente rolero, con las opciones típicas de “Hablar”, “Extorsionar”, “Ligar”, “Robar”, etc. Y al igual que en el sistema de combates, podemos incluso crear un sistema donde los 80x77 píxeles de la izquierda correspondan a una imagen detallada del héroe, a los 80x77 píxeles de la derecha correspondan a una imagen detallada del NPC y que los 160x77 píxeles de abajo correspondan al área de texto.
Aunque bueno, me decanto más por un dibujo del NPC a 160x77 píxeles en la parte alta de la pantalla, reservando la parte de abajo para diálogos y limitarnos a poner el retrato/portrait del personaje de la party que hable en alguna esquina (para indicar quién habla).
De hecho, ya que estamos en fase de diseño, podemos definir las acciones que nuestro personaje puede hacer sobre los NPC:
- Hablar.
- Observar.
- Robar.
- Ligar.
- Extorsionar.
- Asesinar.
- Trueque.
Cada una de estas acciones tendría un diálogo distinto y podría causar que cambie el estado de ánimo del NPC y por ende, su relación o comportamiento con nosotros. Ahora bien, recordemos una cosa, y es que nuestra pila de guardado se limita a 32 Kb de memoria y que el framework nos permite la friolera de 521 bytes. Esto quiere decir que se nos hace imposible hacer que cada NPC del juego pueda recordar si les hemos intentado robar, si hemos hecho click en observar para tener más detalles de él… salvo si guardamos la información a nivel del pueblo.
Me explico: Podemos, por ejemplo, reservar el número máximo de aldeanos por pueblo a 8 y cada bit del byte correspondería a un NPC del pueblo. Así que, por ejemplo, el valor inicial del byte “Robar_pueblo_1” tendría el valor 00000000x2, y si los NPC 1 y 3 nos pillan robando, pasarían a tener el valor 00000101x2 (que equivaldría al nº 5 en decimal). Y si más tarde nos pilla el NPC 2, pasaríamos a tener el valor 00000111x2 (que equivaldría al nº7 en decimal). Limitando el número máximo de NPC con los que interactuar y usando esta técnica, podríamos reservarnos un byte por pueblo para memorizar si un NPC nos ha pillado robando, otro byte por pueblo para recordar si hemos “analizado” a un NPC, otro byte por pueblo para memorizar si hemos conseguido “seducir” a un NPC, otro byte para memorizar si hemos asesinado a un NPC, etc.… y así, con unos 12 bytes tendríamos esas tres informaciones a nivel de 3 pueblos.
Pero un punto sensible son las acciones de robar y trueque, puesto que nos va a ser imposible guardar en la pila el inventario de cada NPC del juego y encima no podemos reemplazarlo por dinero (es decir, que el personaje pueda únicamente robar dinero), puesto que trabajamos a nivel de bytes y el valor máximo que nos permite es de 256. No podemos reservar un byte (o varios) por NPC, sencillamente no es viable. Así que cuando robemos, el jugador deberá de recibir una cuantía aleatoria de dinero (es la única forma viable que veo). Ahora bien, una vez hecho el robo (tanto como si el personaje acierta, como si es pillado), pondremos el bit ligado al robo a 1 y el sistema ya no nos dejará volver a robarle y encima el NPC nos mirará mal cuando volvamos a hablar con él. Y respecto al trueque, tendremos que limitarlo a determinados NPC que contengan algún ítem necesario para la aventura y lo único que podremos hacer es comprarles ese ítem. Ahora bien, ese ítem debería de conseguirse de otras formas: Bien asesinando al NPC, bien completando alguna “quest” que nos pida. Con ello, damos al jugador una sensación más alta de inmersión.
De hecho, me gustaría que todas esas habilidades (robar, asesinar, ligar…) no estén disponibles por defecto y que el jugador vaya desbloqueándolos de alguna forma (que aprenda a asesinar tras la rabia de ver a algún compañero muerto, que aprenda a hacer trueque tras recibir una formación de economía, etc…) e incluso podríamos usar la misma táctica de emplear un byte para almacenar de forma booleana todas las habilidades que puede hacer o no el personaje. Por ejemplo, el primer bit podría ser el de “Puedo robar”, el segundo bit el de “Puedo ligar”, el tercero el de “Puedo asesinar” y así hasta llenar 8 posibles habilidades. Si limitados el número posible de personas que pueden unirse a nuestro grupo a 7, estamos hablando de que podríamos tener 8 bytes de habilidades (1 para el prota y 7 para el resto del grupo) para listar todas estas capacidades.
Ahora bien, tengamos en cuenta otros elementos y es que en cada RPG todo miembro de la party tiene puntos de vida (HP), puntos de magia (MP), un nivel (que hace que cambie el valor máximo de los HP y MP), puntos de experiencia y posibles magias (que dependiendo del nivel del personaje podrán usarse o no). Casi toda esta información es dinámica (cambia en función de nuestros progresos) y debe de ser almacenada en la pila de guardado (que ya hemos dicho que está limitada a 512 bytes a nivel de framework).
Tomemos nota de lo que nos hace falta:
- Cantidad actual de HP (1 byte -> de 0 a 255).
- Cantidad máxima de HP (1 byte -> de 0 a 255).
- Cantidad actual de MP (1 byte -> de 0 a 255).
- Cantidad máxima de MP (1 byte -> de 0 a 255).
- El nivel del personaje (1 byte -> de 0 a 255).
- Puntos de ataque físico (1 byte -> de 0 a 255).
- Puntos de magia (1 byte -> de 0 a 255).
- Puntos de defensa (1 byte -> de 0 a 255).
- Los puntos de experiencia (1 byte -> de 0 a 255).
- Los puntos de experiencia necesarios para pasar al siguiente nivel (1 byte -> de 0 a 255).
- Árbol de magias aprendidas (1 byte en booleano: 8 magias máx.).
- Árbol de habilidades aprendidas (1 byte en booleano: 8 skills máx.).
Pues a lo tonto nos plantamos ya en 12 bytes por personaje, algo que parece muy inviable. Si usamos 8 personajes, estaremos consumiendo 96 bytes sólo en la party. Encima, ocho magias posibles parecen pocas… pero podemos solucionar ambas cosas aplicando un sistema de clases. Por ejemplo, podemos hacer curanderos que tengan sólo 8 posibles magias de curación; Podemos tener magos que hagan sólo magia de fuego; Magos que hagan sólo magia de tierra, etc… Este sistema de clases debería de ir definido en hardcode para reducir al máximo la cantidad posible de bytes a guardar en pila. Es decir, a nivel del código el juego ya sabe si los personajes 1, 2 o 3 son de una clase u otra. Rizando el rizo, podemos hacer que la cantidad máxima de HP, de MP, puntos de ataque, de defensa, de magia, puntos de experiencia necesarios para llegar al próximo nivel… dependan directamente de la clase y el nivel que tenga nuestro personaje (es decir, se tratarían de valores calculados o predefinidos “in game”). Y puestos a rizar el rizo, podemos hacer que el árbol de magias aprendidas dependa también directamente del nivel del personaje.
Con todo ello podríamos reducir la cantidad de bytes por personaje a:
- Cantidad actual de HP (1 byte -> de 0 a 255).
- Cantidad actual de MP (1 byte -> de 0 a 255).
- El nivel del personaje (1 byte -> de 0 a 255).
- Los puntos de experiencia (1 byte -> de 0 a 255).
- Árbol de habilidades aprendidas (1 byte en booleano: 8 skills máx.).
Pero no olvidemos una cosa y es que queríamos implementar un
sistema de “muerte definitiva”. Para esto nos hace fata sólo un bit, donde 0
sea vivo y 1 sea muerto. La fórmula que podríamos seguir para implementar esta
función sería robarle un bit a la variable del nivel del personaje. Para
poneros en contexto, si hacemos que el nivel pasara a tener 7 bits en vez de 8,
tendríamos como posibles valores del 0 al 127 y de hecho, si os habéis fijado,
en muchos juegos el nivel máximo suele ser el 99. En este caso, el primer bit del
byte “nivel” correspondería a si el personaje está vivo o muerto y los 7
siguientes serían reservados para el nivel del personaje:
- Cantidad actual de HP (1 byte -> de 0 a 255).
- Cantidad actual de MP (1 byte -> de 0 a 255).
- Vivo/muerto + nivel del personaje (1 bit de estado + 7 bits de nivel -> de 0 a 127).
- Los puntos de experiencia (1 byte -> de 0 a 255).
- Árbol de habilidades aprendidas (1 byte en booleano: 8 skills máx.).
Y con todo ello acabamos con 5 bytes con personaje, pudiendo hacer todo lo que habíamos definido (pero con el costo de fijarlo con valores precalculados). 5x8 = 40 bytes para toda la party, nada mal. De hecho, podríamos aprovechar para crear bytes para el equipo:
- 1 byte para definir las 8 posibles armaduras que tenga compradas el personaje (8 booleanos).
- 1 byte para definir cuál de esas prendas está usando.
Y lo mismo para las armas:
- 1 bye para definir las 8 posibles armas que tenga compradas el personaje (8 booleanos).
- 1 byte para definir cuál de esas armas tiene equipadas.
Estamos hablando de 9 bytes por personaje: 64 bytes para toda la party, que en mi opinión son muchas, pero oye, creo que hay que apostar por esta solución. Y si os lo estáis preguntando, la capacidad del protagonista en dragón constaría como una clase propia y las transformaciones serían magias.
Así que como veis, estamos ya hablando de reservar 3 bytes de información dinámica por pueblo y 64 bytes para la party. Por ahora no se nos va de madre el diseño y hemos planificado implementar un porrón de cosas.
Navegación en grandes urbes
Un punto que puede agilizar el desarrollo pero que afecta de mala forma a la inmersión, es seguir con el esquema de ciudades que se aprecia en juegos como el primer “Sword Art Online” de PSP que tuvo posteriormente una remasterización digital para PS4 y PS Vita (“Sword Art Online: Hollow Fragment”). Por cierto, un servidor considera de que a día de hoy se trata de uno de los mejores juegos de la saga.
En este juego Kirito tiene que ir desde la planta 75 a la 100 y cada planta tiene una ciudad distinta… Pero realmente sólo una de esas ciudades está modelada en 3D, el resto son “backgrounds” (imágenes de fondo) en los que podemos decidir qué hacer: Visitar tiendas, ir a la posada, etc.
Mi idea es la de pillar este concepto para las metrópolis, así podríamos dar una falsa sensación de ciudad gigante y continuar con la limitación de disponer sólo de 8 NPC por pueblo (la limitación de los 3 bytes): Entras en la metrópolis y ves un dibujo chulísimo de la ciudad y se te presenta un cuadro con varias opciones: Ver monumentos, ir a una posada, comprar objetos, buscar trabajos… Cada acción llevaría a un nuevo escenario en vista “tradicional”. Ahora bien, las aldeas sí que serían modeladas de forma “tradicional” (vista aérea) y este sistema de dibujo + opciones iría únicamente destinada para las grandes urbes.
Gestión del inventario
Un punto crítico en todo RPG es el sistema de gestión del inventario y aquí vamos a estar terriblemente limitados, ya que, a diferencia del modelo tradicional de programación de este tipo de juegos, no vamos a poder almacenar toda esta información de forma dinámica. Tendremos que crearnos un vector estático.
De hecho, propongo reservar 2 bytes para ítems importantes para la aventura, es decir, emplear 16 booleanos para memorizar si poseemos determinados ítems únicos necesarios para la progresión del juego. En juegos tipo “Zelda”, estos ítems serían por ejemplo las pulseras del poder, las botas para correr, o la pluma para saltar.
También me gustaría reservar 1 byte por mazmorra, ya que, siguiendo el modelo de Zelda, me gustaría disponer con distintas llaves para abrir puertas, la brújula que indica dónde está el jefe final y el mapa de la mazmorra (se trataría de contar con 8 booleanos). Pero realmente tendremos que contar con dos bytes: Uno para saber si disponemos de esos ítems y otro byte para saber si hemos abierto todas las puertas asociadas o si hemos matado al jefe final.
Si cada juego suele tener 8 mazmorras, parece totalmente viable poder reservar esos 16 bytes e incluso podemos plantearnos duplicar el número de mazmorras.
De la misma forma, podemos también definir varios bytes destinado a los cofres que irán repartidos por todo el juego. Si nos reservamos 10 bytes, podremos memorizar en booleanos si hay 80 cofres abiertos o cerrados.
Por cierto, cuando hagamos la documentación, toda esta información de cómo están definidas las variables y en qué las emplearemos, tendremos que definirla en una matriz (fichero Excel), porque podemos liarla parda muy fácilmente si empezamos a codificar sin planificar nada.
También me gustaría reservar 10 bytes para el inventario de consumibles de la party (pócimas, hierbas, objetos de farmeo, etc.). La pega con este tipo de objetos es que no se tratan de objetos únicos y que el jugador puede ir comprando y acumulando esos bienes, por lo que realmente tenemos que utilizar 1 byte por objeto.
Como diez posibles objetos distintos parecen muchos y disponer un máximo de 255 parecen una animalada (demasiados), propongo utilizar 4 bits por objeto. De esta forma podemos disponer de 20 clases de objetos (2 por byte), pero limitando el número máximo de cada uno a 15 unidades. De hecho, si queremos impresionar, duplicar el número de bytes (20 en total) y de esta forma contaríamos con la friolera de 40 tipos de objetos distintos (pero con la limitación de disponer como máximo de 15 unidades por cada uno de ellos).
Punto de atención: Estas variables servirán para definir su posesión en pila, pero su comportamiento, aspecto, descripción y efecto deberán de estar predefinidos en código.
Un punto que me gustaría tener en cuenta también, es que la party sepa para qué sirve cada objeto. Imaginemos por ejemplo que nuestro personaje coge una hierba curativa que no ha visto en la vida, la consume y ¡puf! ¡Resulta que era una hierba venenosa!
Para poder aplicar esto, me gustaría tener con un booleano por objeto que nos permita saber si la party conoce o no el efecto del ítem. 40 booleanos implica reservar 5 bytes de memoria y la idea es que esos booleanos pasen a 1 en función de:
- Las personas que formen nuestra party.
- Las conversaciones con los NPC.
- Los distintos libros que podamos consultar.
Es muy importante que esos 5 bytes sean a nivel de party, puesto que sería inviable reservarlos a nivel de personaje (5x8 = 40 bytes).
Gestión de las quests
Aquí quiero diferenciar la quest principal de las quests secundarias. De hecho, podemos definir una quest en varias etapas: Habla con el señor X, ve al lugar Y, vence al bicho Z, etc.
Lo que propongo es tratar el esquema de la aventura con un contador: Es decir, si pillamos un byte podremos contar con 255 etapas, siendo 0 la más simple (la quest no ha comenzado) y 255 la última (quest completada). Y cada vez que cumplimos un hito importante con efecto en la trama, ese contador suma 1. Al hablar con el señor X pasaríamos a tener el valor 1, al ir al lugar Y tendríamos el valor 2, al vencer al bicho Z pasaríamos a tener el valor 3… y así iríamos avanzando por las distintas etapas de nuestra aventura. El problema de este enfoque es que tendremos una historia bastante lineal, por lo que habrá que jugar con variables auxiliares para dar una falsa sensación de libertad.
Un punto a tener en cuenta es que pienso contar con varios finales, entonces mi idea es contar con 2 bytes:
- El byte que acabamos de definir con 256 etapas.
- Un byte que define la rama actual sobre la que nos encontramos (valor 0 -> historia por defecto; valor 1 -> trama favorable al régimen; valor 2-> Trama en contra del régimen; … valor 255 -> Trama a favor de la destrucción de la humanidad.
Jugando con esos dos bytes podemos ir variando la quest principal e ir evolucionándola y derivándola para que deje de ser lineal.
En lo que se refiere a las subquests (o quests secundarias), 255 etapas parecen demasiadas, por lo que he optado por reservar 4 bits por quest secundaria. Es decir, cada byte contaría con dos quests y cada quest tendría un máximo de 16 etapas (con valor 0 la no iniciada y 15 la quest finalizada). Si nos reservamos 30 bytes para quest secundarias, nuestro juego podría contar con hasta 60 quests secundarias, un número bastante loable.
Gestión de pantallas
Acabamos de diseñar bastantes elementos ligados a nuestro juego, pero una parte bastante importante tendrá que ver con la gestión de las pantallas y de los diferentes menús.
La pantalla inicial será el logo del desarrollador, que al cabo de X segundos o tras pulsar algún botón, navegará a la pantalla de “Intro”. En esta pantalla veríamos una escena animada estilo “Link’s Awakening” que nos daría el contexto de cómo el personaje ha llegado al planeta. Al pulsar cualquier botón o al finalizar la introducción, pasaríamos a la pantalla de “Pulsa Start”.
Link's Awakening, uno de los mejores juegos de la historia de GB.
La pantalla de “Pulsa Start” mostraría un dibujo a pantalla completa, mostraría el texto de “Press Start”. Si alguna vez nos hemos pasado el juego, el dibujo a mostrar cambiaría. Al pulsar start pasaremos al menú inicial.
El menú inicial contaría con las opciones de “Partida nueva”, “Cargar partida” y “Password”. El botón de “Cargar partida” quedaría deshabilitado si el juego detecta que la pila está vacía.
La elección de “Partida nueva” machacaría el “save” actual, es decir, formatearía la pila. Es por ello que una popup de alerta deberá de mostrarse en caso de existir ya un “save”, dando opción de volver a la pantalla inicial para evitar perder el “save”.
Hay dos cosas que me gustaría implementar en el menú inicial pero que voy a descartar:
- Poder cambiar de idioma, pero teniendo en cuenta las limitaciones de memoria y lo ambicioso que parece el juego, creo que me limitaré a escribir los textos en inglés.
- Poder exportar el “save” a un código QR (los 512 bytes), para poder jugar una eventual secuela o un remaster en otra plataforma.
Al empezar la partida veríamos la pantalla de juego normal (vista aérea, con el HUD/IHM y el personaje centrado). El HUD deberá de limitarse a:
- El portrait/retrato de cada jugador de la party (un máximo de 4).
- La barra de vida y de magia de cada miembro de la party (un máximo de 4).
Al pulsar “Start” pasaríamos al menú de inventario. En este inventario podríamos:
- Consumir ítems.
- Aplicar magias (p. ex. de curación).
- Consultar los estados.
- Seguir las quests en curso.
- Guardar la partida.
Al consultar un estado que no sea del héroe (vamos, el estado de un compañero), se nos abre la opción de poder hacer un diálogo con él. Este diálogo variará en función de la etapa de la quest principal o de determinadas quests secundarias y servirán para dar pistas.
Al entrar en un combate pasaríamos a la pantalla de combate y volveríamos al juego “normal” al acabarla.
De la misma forma, al iniciar un diálogo con un NPC pasaríamos a la pantalla de diálogo (estilo Fallout / The Elder Scrolls) y al finalizar éste volveríamos a la pantalla de “juego normal”.
Al morir el personaje inicial, se mostraría la pantalla de “Game Over” y tras la pantalla de Game Over volveríamos a la de “pulsa start”, dejando la opción al jugador de cargar el último “save” guardado.
Durante la partida, podremos visitar tiendas y posadas. En las tiendas puede darse el caso de que el jugador realice hurtos, mientras que, en las posadas, aparte de dormir el jugador podrá reorganizar los miembros de su party (definir los que nos acompañarán y su equipamiento) y permitir opciones como salir a tomar una caña por las noches para conseguir información local.
Me gusta el tema de poder organizar el equipo únicamente en las posadas, debido a que es un enfoque más realista de lo que estamos acostumbrados. Desde mi punto de vista, es poco real que el héroe deshaga su maleta en medio de una mazmorra para permitirse cambiar el equipo. Una cosa es recibir una espada nueva y equiparla (podemos dar la opción al jugador al abrir un cofre y al comprobar que la arma es mejor), pero otra totalmente distinta es pasearse con todas las armaduras adquiridas.
Sistema de día y noche y meteorología (descartado)
Un punto que me gustaría implementar es un sistema de día y noche. De noche los negocios estarían cerrados, apenas habría personas paseando; Podríamos hacer que las posadas rechacen hospedarnos si acudimos de buena mañana, etc. Pero me he visto obligado a rechazar esta idea debido a una limitación técnica importante: La Game Boy tiene tres colores, hacer que sea de noche resulta inviable, porque significaría hacer escenarios más oscuros y de 3 colores, mezclando entre ellos el negro y dificultaría la visibilidad de la pantalla. Tampoco puedo hacer el truco de cargar una capa oscura y transparente a pantalla completa. Vamos, que en este juego sólo se permitiría pasear de día.
También me habría gustado un sistema donde una vez por semana lloviera o donde de vez en cuando se asomara algún copo de nieve, pero su implementación me ha parecido complicada debido a las limitaciones del framework. Podremos definir fondos nevados y/o pantanosos, pero serán siempre nevados y/o pantanosos.
Combates de batallones
Otro punto que me gustaría implementar son los combates de batallones, donde se simularán combates entre muchos soldados, representados por las formas y movimientos de fichas de ajedrez.
Para poneros en contexto, a lo largo de la historia principal estallará una guerra civil y si se dan las condiciones (puede darse el caso que no se produzca) el jugador podrá dirigir batallones.
Estos combates no serán igualitarios, es decir, dependiendo de la situación la cantidad de piezas disponibles por cada bando variará, puede darse el caso de tener 3 peones y 4 torres vs 4 alfiles, 2 caballos y una reina, por poneros un ejemplo. El combate acabaría cuando las piezas de un bando desaparezcan (sean “comidas”) o cuando el rival huya del combate.
Además, el tablero cambiará según el combate, puesto que simulará ser un campo de batalla. Si dibujamos por ejemplo un río, un pequeño bosque o montañas…. Las piezas no podrán posicionarse encima de estas áreas, limitando por ende el área de movimiento de las piezas.
Ganar o perder una batalla de este tipo aportará consecuencias a la trama, creando posibles derivaciones o posibles finales. Debido a esto, el número de batallas de este tipo será bastante reducido.
Los comercios
Habrá tres tipos de comercios:
- Las armerías, que venderán equipo y armas.
- Las tiendas de ítems, que venderán consumibles.
- Las posadas, que además de ofrecer un lugar donde dormir, permitirán la venta de alcohol.
Las armerías y tiendas de ítems sólo permitirán la compra de objetos de su familia. Es decir, no podremos venderle hierbas medicinales a un armero y no podremos venderle espadas o armaduras a una droguería. Las posadas directamente no darán opción de venderles nada. Se podrá hacer uso de habilidades como extorsión o ligar para poder conseguir algún tipo de descuento, pero ojo, que un crítico al usar una de estas habilidades podría causar el resultado inverso.
También podemos crear modelos específicos de tiendas, enfocados por ejemplo a la venta de frutas o de libros. Estas tiendas seguirían el modelo de las tiendas de ítems pero estarían “capadas” para no permitir que el jugador les venda ítems.
Fin por hoy
Y poco más, esto va tomando forma y creo que por hoy
ya está bien. Os animo a volver el próximo viernes 30 de julio para compartiros
una vez más los avances con el diseño y desarrollo de este juego. Y si se os
ocurre una idea más, os animo a compartirla en los comentarios aprovechando que
aún estoy en fase de diseño.
No hay comentarios:
Publicar un comentario
Si te ha gustado la entrada o consideras que algún dato es erróneo o símplemente deseas dar algún consejo, no dudes en dejar un comentario. Todo feedback es bienvenido siempre que sea respetuoso. También puedes contactarme por estas redes sociales https://linktr.ee/hamster_ruso si lo consideras necesario.