domingo, 8 de octubre de 2017

Last Crown Warriors #2: Selection screen

Yesterday Light Games published a new development of Last Crown Warriors, in which the character and scenario selection screen was shown.
In the video we can see how the movement of two backgrounds occurs simultaneously (the selection bar and the map at the top). And we can also see a non-linear movement, with accelerations and decelerations.

At logic level, achieving these features in a program should not be a big challenge. Although in the case of the Game Boy, given the limitations of the system, a little prior planning is necessary. So leaving aside the technicalities and focusing on the logical design I'll explain the key elements of this selection screen.

 

Sinusoidal movement

In order to achieve greater dynamism, it has been decided to apply a sinusoidal movement in the shifts of the bar, the top map, the arrows, and the selectable characters. Calculating the sine of a number would be an overly expensive task for a Game Boy, so a little part of the memory has been sacrificed and these shifts have been stored in data tables.

By going throught the values of a table like this, we can apply to the elements the proper movement in each iteration. This table represents the top map shift when leaving the screen.

 

Scene composition

The logic of this screen uses some of the properties of the Game Boy system, such as hardware scroll or sprites. In this image the components are differentiated by color.


In red: sprites; in blue: the main background; in purple: the secondary background or window.

As you can see, moving the top scenario is as simple as applying the Game Boy hardware scroll on the main background. Of course, you have to keep in mind that this map must be redrawn. In this case there is only one selectable scenario, but in the case of having more than one, it would be necessary to reprint the background with each selection change. In the following image we see the evolution of the main background during that change.


This is the Game Boy main background, the red box being the visible area of the screen during the scenario change. Through one limit of the visible area we first remove the current map and later we print the new one.

The window have a disadvantage. It is not possible to reduce its horizontal coordinate below zero, which would be the natural way to make it enter the left limit of the screen. So as you can see, we use an auxiliary sprite during the movement that joins the bar.

Graphical update

In addition to the shifts there are also times when we have to reload the graphics of the backgrounds. The most obvious (and costly) of these reloads is the update of the window once the selection shift ends and all the icons alter their order.

The solution is to have a strict control of the VBlank interruption, and to optimize the graphic reprint. This routine is the responsible for reloading the window, and already has the list of values to copy ready. The formula in this case is the same as the one used in the Last Crown Warriors scroll, which I explain in this entry.


Now it's time to develop the game system of Last Crown Warriors. Any functionality that deserves to be explained, will be the focus of the next blog entries.

Last Crown Warriors #2: Pantalla de selección

Ayer mismo publicaba Light Games un nuevo avance de Last Crown Warriors en el que se mostraba la pantalla de selección de personaje y escenario.
En el vídeo podemos ver cómo se produce el desplazamiento de dos fondos de manera simultánea (el de la barra de selección y el del mapa de la parte superior). Y también se puede apreciar un movimiento no lineal, con aceleraciones y deceleraciones.

A nivel lógico, conseguir plasmar estas características en un programa no debería suponer un gran reto. Aunque en el caso de la Game Boy, dadas las limitaciones del sistema, se hace necesaria una pequeña planificación previa. Así que dejando a un lado los tecnicismos y centrándome en el diseño lógico, paso a exlicaros las claves funcionales de esta pantalla de selección.

 

Movimiento sinusoidal

De cara a lograr un mayor dinamismo se ha optado por aplicar un movimiento sinusoidal en los desplazamientos de la barra, del escenario del fondo superior, de las flechas, y de los personajes seleccionables. Calcular el seno de un número sería una tarea excesivamente costosa para una Game Boy, por lo que se ha sacrificado un poco de memoria y se han almacenado estos desplazamientos en tablas de datos.

Así, recorriendo los valores de una tabla como esta, podemos aplicar al elemento el desplazamiento indicado en cada iteración. Esta tabla representa el desplazamiento del mapa superior al abandonar la pantalla.

 

Composición de la escena 

La lógica de esta pantalla se sirve de alguna de las propiedades del sistema de la Game Boy, como es el scroll por hardware o los sprites. En esta imagen están diferenciados por color los distintpos componentes en acción.


En rojo: sprites; en azul: el fondo principal; en morado: el fondo secundario o ventana.

Como veis, desplazar el escenario de la parte superior es tan sencillo como aplicar el scroll por hardware de Game Boy en el fondo principal. Eso sí, hay que tener en cuenta que dicho mapa debe ser redibujado. Ya que en este caso sólo hay un escenario seleccionable, pero en el caso de haber más sería necesario reimprimir el fondo con cada cambio de selección. En la siguiente imagen vemos la evolución del fondo principal durante dicho cambio.


Este es fondo principal de Game Boy, siendo el recuadro rojo la zona visible de la pantalla durante el cambio de escenario. Por un lateral de la zona visible eliminamos primero el mapa actual para más tarde imprimir el nuevo.

Y en cuanto a la ventana tenemos una desventaja. No es posible reducir su posición horizontal por debajo de cero, que sería la forma natural de introducirla por el límite izquierdo de la pantalla. Así que como se puede observar, nos servimos de un sprite auxiliar durante el desplazamiento que parece mimetizarse con la barra.

Actualización gráfica

Además de los desplazamientos también hay momentos en los que se deben recargar los gráficos de los fondos. La más evidente (y costosa) de estas recargas es la relativa a la actualización de la ventana una vez el cambio de selección termina, donde todos los iconos que la componen ven alterado su orden.

La solución pasa por tener un control estricto de la interrupción de VBlank, y en optimizar al máximo la reimpresión gráfica. Esta rutina es la encargada de recargar la ventana, la cual ya cuenta con la lista de valores a copiar. La fórmula en este caso respecto a la actualización gráfica es la misma que la usada en el scroll de Last Crown Warriors, la cual explico en esta entrada.


A partir de ahora toca empezar a desarrollar y profundizar en el sistema de juego de Last Crown Warriors. Cualquier funcionalidad que merezca ser explicada, será protagonista de las próximas entradas.

viernes, 7 de julio de 2017

Sheep Kaboom (BitBitJam4)

Game Boy game made during a week by Light Games for #BitBitJam4

Hold A to charge the shoot. Release it to launch the sheep.
Aim to the target and avoid the spikes.


Design and programming: Imanolea
Graphics: Seiyouh
System: Game Boy

domingo, 9 de abril de 2017

Last Crown Warriors #1: Building the scroll system

In the April 1 screenshotsaturday I posted a short video in which the Last Crown Warriors scrolling and collision system could be seen in action.
In the video we can see Lilian moving at a speed of 7 pixels per frame along a stage of 512 by 512 pixels. In this post I will explain the logic behind the scroll system, which as you will see below, allows a scrolling of up to 8 pixels per frame.

The first thing to understand when it comes to setting up a scrolling system for Game Boy is that, in this console, any graphical update that is performed with the LCD switched on must occur during the VBlank interrupt (also during the HBlank interrupt, although is not considered for the scroll). And this interrupt marks the beginning of a period of time in which the system is not using the video ram, period in which therefore we have available that memory in order to modify it.

This interruption occurs 59.7 times per second (one for each frame of the game) in a Game Boy. This graph represents the duration of the interrupt (4,560 clock cycles) with respect to the total time of the frame (70,224 clock cycles).

Based on this graph we can conclude that the graphical update must be highly optimized.

And the second thing we need to understand is how the background scrolling works in this system. The scrolling of the background works at a hardware level, that is, changing the value of a register can alter the position of the background we have loaded into memory. But the size of this background is limited, 256 by 256 pixels, so for maps that exceed those dimensions it will need to be modified.

The base of the scroll system will then be the redrawing of the background. And taking into account that the graphic modification should be as optimum as possible, it only remains to decide which part of the background should be updated during the interruption. In Last Crown Warriors, we update the visible column and row of the part of the background to which we are going. For example, if you go up, left, or up and left, we will update the background bar highlighted in the next image. The blue box represents the visible background.


For the rest of directions we will update the corresponding bar following the same principle: update the row and column closest to being visible. This full modification of column and row allows us to scroll the background up to 8 pixels per iteration.

Once we are clear about what tiles need to be replaced, it remains to answer the question of how to do it. As we have seen, the time available to modify the video memory is very limited. So in Last Crown Warriors we prepare a data structure with the following information, in order to minimize the time it takes to replace the tiles of the background:
  • byte 0: low byte of the address of the tile to be replaced;
  • byte 1: high byte of the address of the tile to be replaced;
  • byte 2: new tile value.
This structure is repeated for each of the tiles that we have to update, 41 in total. Thus, during the interruption of VBlank we must only execute the following code, pointing to the beginning of the previously prepared data structure.


We use REPT so that the indicated code is repeated for each of the tiles. Discarding a possible loop, which would consume additional processing.

Also it is important that in case we use other Game Boy interrupts we execute "ei" (enable interrupts) at the start of them. So we make sure that the VBlank interrupt is called at the right time and that no part of it will ever run outside the VBlank period.

And this would be a conceptual explanation of how the scrolling system works in this game. In future posts I will try to cover other aspects of the development. For these posts it will not be necessary to have an advanced knowledge of the system in order to understand the exposed ideas.

Last Crown Warriors #1: Creando el sistema de scroll

En el screenshotsaturday del 1 de abril publiqué un vídeo corto en el que se podía obervar el sistema de scroll y colisiones de Last Crown Warriors en acción.
En el vídeo podemos ver a Lilian desplazándose a una velocidad de 7 píxeles por frame a lo largo de un escenario de 512 por 512 píxeles. En esta entrada me dedicaré a explicar la lógica que hay detrás del sistema de scroll, que como veréis a continuación, permite un desplazamiento por frame de hasta 8 píxeles.

Lo primero que hay que entender a la hora de plantear un sistema de scroll para Game Boy es que, en esta consola, toda actualización gráfica que se realice con el LCD encendido debe producirse durante la interrupción de VBlank (o durante la interrupción de HBlank, aunque no la tenemos en cuenta para el scroll). Y es que esta interrupción marca el inicio de un periodo de tiempo en el que el sistema no está haciendo uso de la memoria de vídeo, periodo en el que por lo tanto tenemos disponible dicha memoria para modificarla.

Esta interrupción se produce 59,7 veces por segundo (una por cada frame del juego) en una Game Boy. Esta gráfica representa la duración de la interrupción (4.560 ciclos de reloj) respecto al total de tiempo que dura el frame (70.224 ciclos de reloj).

En base a estos datos podemos concluir que la actualización gráfica debe estar altamente optimizada.

Y lo segundo que necesitamos entender es cómo funciona el scroll de fondos en este sistema. El desplazamiento del fondo funciona a nivel de hardware, es decir, con cambiar el valor de un registro podremos alterar la posición del fondo que tengamos cargado en memoria. Pero el tamaño de este fondo es limitado, de 256 por 256 píxeles, así que para mapas que superen dichas dimensiones será necesario modificarlo.

La base del sistema de scroll será entonces el redibujado del fondo. Y teniendo en cuenta que la modificación gráfica debe ser lo más óptima posible, queda decidir qué parte del fondo debe actualizarse durante la interrupción. En Last Crown Warriors, actualizamos la columna y la fila visible de la parte del fondo a la que nos dirigimos. Por ejemplo, si nos dirigimos hacia arriba, hacia la izquierda, o hacia arriba y hacia la izquierda, actualizaremos la franja del fondo resaltada en la siguiente imagen. El recuadro azul respresenta en este caso el fondo visible.


Para el resto de direcciones actualizaremos la franja correspondiente siguiendo el mismo principio: actualizar la fila y columna más próxima a ser visible. Esta modificación íntegra de columna y fila nos permite un desplazamiento del fondo de hasta 8 píxeles por iteración.

Una vez tenemos claro qué tiles hay que sustituir, queda responder a la pregunta de cómo hacerlo. Como hemos visto, el tiempo disponible para modificar la memoria de vídeo es muy limitado. Por lo que en Last Crown Warriors se prepara una estructura de datos con la siguiente información, de cara a reducir al mínimo el tiempo que conlleva sustituir los tiles del fondo:
  • byte 0: parte baja de la dirección del tile a sustituir;
  • byte 1: parte alta de la dirección del tile a sustituir;
  • byte 2: nuevo valor del tile.
Esta estructura se repite por cada uno de los tiles que tenemos que actualizar, 41 en total. De esta forma, durante la interrupción de VBlank sólo debemos ejecutar el siguiente código, apuntando al inicio de la estructura de datos previamente preparada.


Usamos REPT para que el código señalado se repita por cada uno de los tiles. Desechando así un posible bucle, el cual consumiría procesamiento adicional.

Además es importante que en el caso de que usemos otras interrupciones de Game Boy ejecutemos "ei" (enable interrupts) al inicio de las mismas. De este modo nos aseguramos que la interrupción de VBlank se llama en el momento adecuado y que ninguna parte del código con el que actualizamos los gráficos se ejecuta fuera del periodo de VBlank.

Y esta sería una explicación conceptual de cómo funciona el sistema de scroll en este juego. En próximas entradas intentaré cubrir otros aspectos del desarrollo, de manera que no sea necesario tener unos conocimientos avanzados sobre el sistema para entender las ideas que se expongan.