Mine 2020 en Pico-8

Gracias a Press Over News, y a su espectacular sección indispensables, descubrí Pico-8. https://pressover.news/indies-pensables/ufo-swamp-odyssey-mini-metroidvania/

Pico-8

Pico-8 es una consola virtual y al mismo tiempo un game engine. Está diseñada para imitar una consola de fantasía, emulando las limitaciones de hardware de los dispositivos de los años 80.

Por ejemplo, la resolución de pantalla es de 128 píxeles por 128 píxeles, bastante alejado del estándar 4k de las PlayStations de hoy. La cantidad de colores es 16, con una paleta fija.

La paleta fija de 16 colores de Pico-8

La cantidad de sprites, y los sonidos tienen limitaciones similares. Y son todas estas limitaciones, entre otras cosas, las que logran que programar juegos en esta consola de fantasía sea verdaderamente placentero.

Pico-8 cuesta 15 dólares, pero vino incluido en el bundle anti racismo de más de 700 juegos de Itchio, que por suerte mis hijos me obligaron a comprar: https://itch.io/b/520/bundle-for-racial-justice-and-equality

Programando Mine 2020

Y es así que luego de leer la nota de Press Over sobre el Ufo Swamp, que está hecho en Pico-8, y jugarlo, decidí aprender Pico-8 haciendo algo relativamente sencillo como un Minesweeper de los años 90.

El desarrollo fue relativamente sencillo, y sirvió para los propósitos de aprender a usar este espectacular game engine/consola virtual.

Entre las cosas más complejas (pero no tanto…) a las que me enfrenté desde el punto de vista de la programación y este entorno en particular fueron dos cosas:

La primera: quería imitar la funcionalidad del Minesweeper de Windows 3.1, en donde el jugador nunca pierde en el primer clic, de modo que la estructura de las bombas se arma luego del primer clic, y por supuesto invalida ese casillero para colocar bomba.

El algoritmo es bastante sencillo:

Agarra los todos los tiles, menos el que hizo clic el usuario, los mezcla con un loop de 1000, y finalmente le pone bomba a los tiles ya mezclados de forma secuencial. De esta forma se resuelve el asunto del clic inicial, y además evita que más de una bomba caiga en el mismo tile.

        assign_bombs=function(self,exclude_x,exclude_y)
            -- create array of amount of tiles
            exclude=self:get_index(exclude_x,exclude_y)
            local a={}
            for i=1,#self.tiles do
                if i != exclude then
                    add(a,i)
                end
            end

            -- shuffle the array
            for i=1,1000 do
                rand_pos1 = flr(rnd(count(a)-1)) + 1
                rand_pos2 = flr(rnd(count(a)-1)) + 1
                aux=a[rand_pos1]
                a[rand_pos1]=a[rand_pos2]
                a[rand_pos2]=aux
            end

            -- pick the first (bomb amount elements)
            for i=1,self.total_bombs do
                self:set_bomb(a[i])
            end
        end,

La segunda que también quise imitar, fue el hecho de que los casilleros libres contiguos se abren automáticamente. Una buena oportunidad para aplicar recursividad, que por suerte salió espectacularmente bien. Cada casillero que se va abriendo, trata de abrir sus 8 casilleros contiguos, y así sucesivamente. Si encuentra que tiene una bomba contigua, para de abrir, si no tiene bombas contiguas, sigue abriendo.

function uncover_recursive(tile,board)
    tile.closed=false
    if tile:get_bombs_near() > 0 then
        return
    end

    -- check top left
    if tile.x>0 and tile.y>0 then
        top_left_tile=board:get_tile(tile.x-1,tile.y-1)
        if top_left_tile:is_closed() then
            uncover_recursive(top_left_tile,board)
        end
    end

    -- check top
    if tile.y>0 then
        top_tile=board:get_tile(tile.x,tile.y-1)
        if top_tile:is_closed() then
            uncover_recursive(top_tile,board)
        end
    end

    -- check top right
    if tile.x<board.size-1 and tile.y>0 then
        top_right_tile=board:get_tile(tile.x+1,tile.y-1)
        if top_right_tile:is_closed() then
            uncover_recursive(top_right_tile,board)
        end
    end

    -- check right
    if tile.x<board.size-1 then
        right_tile=board:get_tile(tile.x+1,tile.y)
        if right_tile:is_closed() then
            uncover_recursive(right_tile,board)
        end
    end

    -- check bottom right
    if tile.x<board.size-1 and tile.y<board.size-1 then
        bottom_right_tile=board:get_tile(tile.x+1,tile.y+1)
        if bottom_right_tile:is_closed() then
            uncover_recursive(bottom_right_tile,board)
        end
    end

    -- check bottom
    if tile.y<board.size-1 then
        bottom_tile=board:get_tile(tile.x,tile.y+1)
        if bottom_tile:is_closed() then
            uncover_recursive(bottom_tile,board)
        end
    end

    -- check bottom left
    if tile.x>0 and tile.y<board.size-1 then
        bottom_left_tile=board:get_tile(tile.x-1,tile.y+1)
        if bottom_left_tile:is_closed() then
            uncover_recursive(bottom_left_tile,board)
        end
    end
end

La IDE

Para los que estamos acostumbrados a las IDEs de hoy, el editor de código del Pico-8 es altamente difícil de utilizar, no por lo complejo, sino por su limite de 32 caracteres de ancho. De modo que use Atom, con algunos plugins para Pico-8, que en realidad utiliza un lenguaje llamado Lua. Con el Atom de un lado, y el Pico-8 del otro se vuelve bastante sencillo de programar, y de ejecutar rápidamente lo que uno hace.

Programando Mine 2020 en Pico-8 con Atom

Los editores del Pico-8

Aparte del editor de código, Pico-8 trae un editor de sprites, y otro de sonidos. Estos editores son muy sencillos y prácticos de usar. Los sprites son de unos escasos 8×8 píxeles, y los sonidos que se generan tienen el aspecto sonoro chiptune de la era de los 8 bits, es genial!

Pico-8 - Editor de sprites
Pico-8 – Editor de sprites
Pico-8 - Editor de sonidos
Pico-8 – Editor de sonidos
Pico-8 - Editor de código
Pico-8 – Editor de código. Muy complicado de usar.

Jugar Mine 2020

Otra de las genialidades de Pico-8 es la capacidad de exportar el cartucho que uno programa en diferentes formatos. Con un par de comandos se puede armar al instante ejecutables para Windows, Mac, Linux y Raspberry Pi.

También es súper práctico el exportador HTML, que genera un archivo html y un archivo javascript para jugar en el browser directamente. Cosa que hice acá para poder jugar:

Mine 2020

https://mine2020.lucasdima.com/

Otras opciones para dar a conocer los juegos son tanto el sitio de Itchio, como el del desarrollador de Pico-8. Allí se pueden jugar a miles de cartuchos creados por toda la comunidad.

También armé un repositorio público en Github, con todo el código fuente. Muy práctico por si alguien quiere ver como está hecho todo esto y por qué no, también modificarlo:

https://github.com/lucdima/mine2020

Conclusión

Pico-8 te enamora. Te lleva a los comienzos, a tiempos más simples, en donde no había que preocuparse por diferentes resoluciones de pantalla, ni 3D, ni nada parecido.

Creo que es una herramienta muy práctica para aprender programar y para experimentar, por muchas razones, pero básicamente porque deja a la vista la esencia de las cosas.

Espero que en el futuro tenga tiempo de hacer más experimentos con este software increíble llamado Pico-8.