Thanks to Press Over News, and their spectacular essential section, I discovered Pico-8. https://pressover.news/indies-pensables/ufo-swamp-odyssey-mini-metroidvania/

Pico-8

Pico-8 is a virtual console and at the same time a game engine. It’s designed to imitate a fantasy console, emulating the hardware limitations of 80s devices.

For example, the screen resolution is 128 pixels by 128 pixels, quite far from the 4K standard of today’s PlayStations. The number of colors is 16, with a fixed palette.

Pico-8 color palette

The fixed 16-color palette of Pico-8

The number of sprites and sounds have similar limitations. And it’s all these limitations, among other things, that make programming games on this fantasy console truly enjoyable.

Pico-8 costs 15 dollars, but it came included in the anti-racism bundle of more than 700 games from Itch.io, which luckily my kids forced me to buy: https://itch.io/b/520/bundle-for-racial-justice-and-equality

Programming Mine 2020

And so it was that after reading the Press Over article about Ufo Swamp, which is made in Pico-8, and playing it, I decided to learn Pico-8 by making something relatively simple like a 90s Minesweeper.

The development was relatively simple, and served the purpose of learning to use this spectacular game engine/virtual console.

Among the most complex things (but not that much…) that I faced from the programming perspective and this particular environment were two things:

The first: I wanted to imitate the functionality of Windows 3.1 Minesweeper, where the player never loses on the first click, so the bomb structure is built after the first click, and of course invalidates that square for placing a bomb.

The algorithm is quite simple:

It takes all the tiles, except the one the user clicked, shuffles them with a loop of 1000, and finally puts bombs on the already shuffled tiles sequentially. This way it solves the initial click issue, and also prevents more than one bomb from falling on the same 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,

The second thing I also wanted to imitate was the fact that adjacent free squares open automatically. A good opportunity to apply recursion, which luckily turned out spectacularly well. Each square that opens tries to open its 8 adjacent squares, and so on. If it finds that it has an adjacent bomb, it stops opening, if it has no adjacent bombs, it continues opening.

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

The IDE

For those of us accustomed to today’s IDEs, the Pico-8 code editor is highly difficult to use, not because of complexity, but because of its 32-character width limit. So I used Atom, with some plugins for Pico-8, which actually uses a language called Lua. With Atom on one side, and Pico-8 on the other, it becomes quite simple to program, and to quickly execute what you’re doing.

Programming Mine 2020 on Pico-8 with Atom

Programming Mine 2020 on Pico-8 with Atom

The Pico-8 Editors

Apart from the code editor, Pico-8 comes with a sprite editor and a sound editor. These editors are very simple and practical to use. The sprites are a mere 8x8 pixels, and the sounds that are generated have the chiptune sound aspect of the 8-bit era, it’s great!

Pico-8 Sprite Editor

Pico-8 - Sprite Editor

Pico-8 Sound Editor

Pico-8 - Sound Editor

Pico-8 Code Editor

Pico-8 - Code Editor. Very complicated to use.

Playing Mine 2020

Another of Pico-8’s genius features is the ability to export the cartridge you program in different formats. With a couple of commands you can instantly create executables for Windows, Mac, Linux and Raspberry Pi.

The HTML exporter is also super practical, generating an HTML file and a JavaScript file to play directly in the browser. You can play Mine 2020 by clicking on the image:

Mine 2020 - Game screenshot

Mine 2020 - Click to play in your browser

Other options for sharing games are both the Itch.io site and the Pico-8 developer’s site. There you can play thousands of cartridges created by the entire community.

I also created a public repository on Github, with all the source code. Very practical if someone wants to see how all this is made and why not, also modify it:

https://github.com/lucdima/mine2020

Conclusion

Pico-8 makes you fall in love. It takes you back to the beginning, to simpler times, where you didn’t have to worry about different screen resolutions, or 3D, or anything like that.

I think it’s a very practical tool for learning programming and for experimenting, for many reasons, but basically because it makes the essence of things visible.

I hope that in the future I’ll have time to do more experiments with this incredible software called Pico-8.