Notes on Pico-8

After reading and hearing quite a bit about Pico-8 in the last weeks1, I dipped my toes into these waters one weekend (2025-10-18/19) and made a few notes about it…

Introduction

Pico-8 is a “fantasy (video game) console”: A virtual machine and game engine for a system that never existed in reality.

It mimics the limited capabilities of earlier 8-bit systems (from the 1980s) and thus encourages/forces some creativity and ingenuity from the developer when implementing the ideas; simultaneously, it doesn’t overwhelm one with the many possibilities of modern tools and machines – I like that idea/approach, but: I haven’t really done much with it, beside the initial setup steps described below.

And for the moment, it also seems unlikely that I will spend more time with it. Not because I don’t like it, it’s just a matter of time, priorites and interests: I have other things (and for longer) on my “bucket list” that currently deserve more focus.

That being said, things can also change again in the future, so I’ll keep these notes around…

First Steps

Setup

Unzip the file pico-8<version>windows.zip and put the extraced files wherever you want them to be:
There is no real installation/setup step required (I moved them to C:\Program Files\Pico-8 on my PC).

The Zip should contain:

Start

Start Pico-8 by either via double-clicking pico8.exe or run that program from a terminal.

Store

The default location for all kinds of Pico-8 related files is C:\Users\<username>\AppData\Roaming\pico-8:
Note: The folder is created by the first start of Pico-8!
Powershell snippet for Windows: Get-ChildItem $ENV:APPDATA\pico-8


Configuration

Pico-8 saves its configuration in the file config.txt (it’s initially generated when PICO-8 is being closed for the first time!).

Its location varies between the operating systems:

Powershell snippet for Windows: Get-Content $ENV:APPDATA\pico-8\config.txt

Paths

One can also change the directories where Pico-8 will look or store certain things:

// Location of pico-8's root folder
root_path C:/<...Path...>/carts/

// Location of cartridge save data
cdata_path C:/<...Path...>/cdata/

Calling pico8.exe with parameters

Some common parameters for starting pico8.exe from the host operating systems’s CLI:

pico8 [switches] [filename.p8]

-windowed <0|1>         set windowed mode off (0) or on (1)
-width <n pixel>        set the window width
-height <n pixel>       set the window height
-run <path/to/file>     load and run a cartridge
-splore                 boot in splore mode
-home path              set the path to store config.txt and other user data files
-root_path path         set the path to store cartridge files

Common tasks from within Pico-8

Start Pico-8 and use its CLI for this:

LOAD <path/to/file> Load a cartridge (from the path relative to root_path)
RUN                 Run the currently loaded cartridge

SAVE [<filename>]   Saves the current cartridge to a file.
                    If no filename is provided, it will be saved as "untitled.p8"
                    
                    Without an extension, *.p8 will be added by default.
                    *.p8: Text file format: For development, cannot be uploaded to the BBS.
                    '.p8.png': Binary file format; usually used for uploads to the BBS.
                    '.p8.rom': raw 32KB binary file format (?).
                    
                    The destination folder is what is specified for root_path in config.txt
                    One can also use 'path/to/file', but 'path/to' must already exist!
                    More: https://pico-8.fandom.com/wiki/Save

ALT+ENTER:          Toggle Fullscreen
ALT+F4:             Fast Quit (Windows)
CTRL-R:             Reload / Run / Restart cartridge
CTRL-S:             Quick-Save working cartridge
ENTER / P:          Pause Menu (while running cart)

Developing with external tools

Developing for Pico-8 and developing in Pico-8 are… different things.
Especially since the code editor is an “acquired taste” (due to the screen resolution and font choice).

That’s why it’s also not uncommon to use external tools (from the host operating system) to write code and create art for the Pico-8 target.

Background Info

Beside the actual code, also art, audio, etc. can be done outside of Pico-8 (e.g. pixel art with “Aseprite”) and then imported by Pico-8.

One could edit .p8 files directly in an external editor, but that is not recommended, because the .p8 file contains more than just code!
This could create potential conflicts (and loss of changes!), when your external editor and Pico-8 are both editing the same files.

Example: You edit the code, but forget to save. You then work on some art in the same .p8 file (sprites, maps, music/sound) and save these again.
By that, the unsaved code in the .p8 file will be overwritten/forgotten!

Instead, modify separate .lua files and include them in the cartridge’s code using #INCLUDE YOURFILE.LUA when running it.

Note: This including mechanism only works on this first level – nesting is not allowed! That means one cannot include a Lua file that includes another Lua file that includes a Lua file and so one :-(

Preparation

Before one can create own source code files, one must tell Pico-8 the location of the local development folder.

That means: Telling Pico-8 which root path and cartridge data path it should use when running:

  1. Open the configuration file (see above)
  2. Update root_path and cdata_path with the path to your work folder (see above)

Inside these two specified folders one can now have sub-folders for organizing the projects.

Based on:


Simple Program

This describes how to create a “hull” for more code.

Start Pico-8 and save the cartridge via (subfolders must be created before, by hand, in Pico-8!):

> SAVE [<dir>/]<filename>

The three main function that any Pico-8 program needs are _init(), _update() and _draw():

function _init()
    cls()
    print("1 Hello World!")
    print("2 Hello World!", 10, 10)
    print("3 Hello World!", 20, 20, 8)
    print("4 Hello World!", 12)
end

function _update()
end

function _draw()
end

Random Tips

There is also printh(): Print a string to the host operating system’s console for debugging (or to a file on the host OS, or to the host OS clipboard

Get the token count when using the #include method

Type info into the pico8 command line.

Booting into a cartridge on start (from the host CLI)

> .\pico8.exe -run $Env:APPDATA\pico-8\carts\test\test.p8

Loading and running a cartridge from within Pico-8

> Load [<Dir>/]<Filename>
> Run

  1. A side effect of being sucked into the rabbit hole of retro handhelds on YouTube – no, I haven’t bought one (yet?)… ↩︎