
Hey All!
PICO-8 0.2.5 is now up on lexaloffle, Humble, itch.io, and for PocketCHIP and web (Education Edition).
Edit: 0.2.5b is now up for Linux users who had trouble connecting to the BBS: https://www.lexaloffle.com/bbs/?pid=116441#p
Built-in Help
PICO-8 0.2.5 has built-in documentation on API functions and other topics. Type "HELP" at the prompt to see a list of topics in blue, and then e.g. "HELP GFX" to get more information about that thing.
While in the code editor, you can also press CTRL-U to get help on whatever is under the cursor, including operators and Lua keywords.
> HELP FILLP |

String Indexing
Single characters can now be grabbed from strings using a familiar str[i] style syntax that means something similar to sub(str, i, i). The index is rounded down to the closest integer, and can be negative to index from the end of the string.
S="ABCDE" S[2.6] -- "B" S[-2] -- "D" S[99] -- "" |
Strings in Lua are immutable, so this can only be used in an expression (on the right hand side of an assignment). e.g. s[2] = "z" is not allowed.
rnd(str) is now also accepted and returns a random character from string str.
// update: this might not be true from 0.2.5c: https://www.lexaloffle.com/bbs/?pid=116415#p
I've reverted sub() to pre-0.2.4 behaviour, which means that sub("abcde",2,_) returns "bcde". 0.2.4 was returning single characters when the 3rd parameter is non-numeric, which is now much better handled by str[i] style indexing. (Apologies if you were already using this behaviour!)
Editor Features
gfx_grid_lines in config.txt now takes a colour if you'd like super-visible grid lines in the sprite editor:

Map selections are now on a separate floating layer:

Pressing cursor keys in the map when nothing is selected now moves the camera, as I noticed some new users struggling to find/understand the pan tool and instead instinctively reaching for the cursor keys.
PICO1K Tools

Some changes intended to be useful for PICO1K Jam starting in September:
ctrl-click on the compressed code capacity to get a realtime compressed size counter in bytes. This is the same size given with the INFO command, and when storing the cartridge as a tiny (code-only) binary rom with "EXPORT -T FOO.P8.ROM"
"EXPORT -T @CLIP" can be used to get a hexdump of that same data written to clipboard. This is not very useful -- just a way to visualise exactly how much data is stored.
- SAVE @URL saves 3 characters when there is no sprite data included by omitting the redundant "&g=".
Web-Exportable Audio
extcmd("audio_rec"), extcmd("audio_end") can be used in web exports. The output file shows up as a downloadable .wav file. I'm hoping this will open the door for some cute sound generation tools.
Variable Width P8SCII Fonts
PICO-8 0.2.5 custom fonts can now specify how wide each character is when printed. This previously handled by doing things like injecting extra P8SCII commands into the output string, but this was cumbersome and meant that such fonts could not be shared as plain data. There were already pixel-wise cursor positioning commands in P8SCII, so I felt it makes sense to make this simpler. Also, I needed it for Picotron 8)
To specify a 3-bit width adjustment and 1-bit y offset for character 16..255, the data at 0x5608..0x567f is used. These would otherwise be the bitmap data for characters 1..15 which are all control characters and thus never printed.
Each 4-bit nibble in 0x5608..0x567f (low nibbles first) encodes the adjustments for one character:
bits 0x7: adjust character width by 0,1,2,3,-4,-3,-2,-1 bit 0x8: when set, draw the character one pixel higher (useful for latin accents) |
An addition bit must be set at 0x5605 to enable size adjustments: poke(0x5605, 1). Otherwise the data at 0x5608..0x567f is ignored.
To test this out, try loading the font snippet generation tool:
> LOAD #FONT_SNIPPET |
And then paste the following after the comment starting with "font attributes"
POKE(0x5605,1) -- turn on adjustments POKE(0x5634,0x70) -- set nibble for i to 0x7 |
You can now observe that the big "i" in "quick" near the top of the screen only has 1px of space to the right instead of 2px.
Here's a helper function for setting the 4-bit nibble (val) for a given character (c):
FUNCTION ADJUST_CHAR(C, VAL) LOCAL ADDR = 0X5600 + ORD(C)\2 LOCAL SHFT = (ORD(C) & 1) * 4 LOCAL MASK = 0XF << SHFT POKE(ADDR, (PEEK(ADDR) & ~MASK) | (VAL << SHFT)) END |
File Listings (for Dev Tool Carts)
Locally running programs can now use ls(path) to get a listing of any local directory. Entries that end with a "/" are directories. Use stat(124) to get the current path.
PATH = STAT(124) -- E.G. /FOO/ FILES = LS(PATH) FOR F IN ALL(FILES) DO COLOR(F[-1] == "/" AND 14 OR 6) PRINT(F) END |
BBS cartridges are not able to access local file listings -- this is intended for developing tools to use locally. For example: a utility that makes it easier to browser cartridge data and copy between cartridges using reload() / cstore() which are able to read and write any local cartridge file using the 4th parameter.
Keyboard Scancode Remapper
If you're having trouble getting PICO-8 to detect some keys (especially numeric keypad keys / unusual laptop layouts), there is now a built-in tool for mapping those keypresses to something SDL2 understand. Run PICO-8 from commandline with -scancodes:
pico8 -scancodes
Or use some other tool to find out which scancodes the keys in question are producing, and then map them to something else in config.txt (look for map_scancodes)
Dynamic Libcurl Support (Linux)
The 32-bit and 64-bit linux builds now try to dynamically load libcurl by default in order to make bbs requests (e.g. download carts from splore). This will hopefully make installing on some platforms easier, including Steam Decks. When libcurl.so is not available, it drops down to the old wget behaviour (requires wget to be installed). If this works well, I'll also see about moving to the same scheme for raspi and mac builds.
More Doodlemud
Doodlemud is a toy multiplayer game designed to test the backend services that PICO-8's high score table (and future projects) will be based on. Try it here: https://www.doodlemud.com/#skatepark
This version is running on a completely new backend, custom written from scratch as a self-contained program using libwebsockets. My first attempt was built out of opensource components (nchan, redis, openresty, nginx), but because of PICO-8's unusual requirements, this was making customisation, debugging and devops more complex that it needed to be. Sometimes just reinventing the wheel with a bespoke C program is still the right approach even in the world of web services. There are currently 5 nodes running which are selected based on the user's location when making a new room:

Next Steps
It looks like PICO-8's 0.2.5 API is unlikely to change now (really, this time!), and the next task is to port the new additions to Voxatron for Voxatron 0.3.7. After that I'll continue working on the BBS functionality needed to log in from PICO-8 and submit high scores. If you're curious, you can see the current plan for the SCORESUB() function by typing HELP SCORESUB.
That's all for now -- I hope you enjoy the update and as usual let me know here or in bugs/ if you find anything spooky going on.
Full Changelog: