Log In  

Hey All! PICO-8 0.2.2 is now up on lexaloffle, Humble, itch.io, and for PocketCHIP.

This release follows a pattern set by previous 0.2.* updates in that I set out to fix a bunch of bugs and resolve design details, but in doing so, went down some deep rabbit holes and came out the other end with brand new features. As a result, some of the new features are on the advanced side, and this post will be likewise be more technical than usual. But I hope everyone can find something fun to mess around with!

SFX Filters

At the bottom of the SFX editor, you can now find 5 switches that alter the characteristics of each instrument. You can get a much wider variety of sounds and textures now, but they're meant to feel like variations on the existing instruments rather than completely new ones. I settled on this scheme after working on Voxatron's sound system and found that I could boil the set of parameters I wanted down to just 7 bits of information -- which is fortunate because there were only 7 unused bits left in the SFX data!

The 5 switches are:

  • NOIZ: Generate pure white noise (applies only to instrument 6)
  • BUZZ: Various alterations to the waveform to make it sound more buzzy
  • DETUNE-1: Detunes a second voice to create a flange-like effect
  • DETUNE-2: Various second voice tunings, mostly up or down an octave
  • REVERB: Apply an echo with a delay of 2 or 4 ticks
  • DAMPEN: Low pass filter at 2 different levels

SFX instruments (the green ones) can also use these filters, so it is possible for example to have a detuned square wave in the same SFX as a dampened triangle. When both the parent SFX and the SFX instrument have the same switch set at 2 different levels, the greater of the two is used.

Here's @Gruber explaining filters, along with a newly added control over the length of each SFX (useful for implementing uneven time signatures):

And here's @tesselode putting them to good use:

The BBS SFX player (copy a range of patterns and paste them as text) works with the new filters, but is still janky on mobile:



In previous versions of PICO-8 there were some characters in the range (0..15) that were sitting around doing nothing useful when you printed them. That's clearly no good, so 0.2.2 has introduced a new control codes that allow control over things like text formatting, cursor position and even sound generation. Along with some kana improvements, 0.2.2 now has complete set of 256 characters -- or P8SCII (PICO-8 Standard Code for Information Interchange).

An example: the "command" character (6) can be written as "\^" followed by a command character and sometimes a parameter:


?"\^wwide \^ttall\n"

?"\feset colour\n"
?"\#5solid background\n"

Character 7 ("\a") can be used to play audio using a compact description

?"\a" -- beep
?"\asfc3ccbdcbae2ee" -- play a wee ditty

This might be useful for squeezing extra sound effects into a cart (or tweetcart), or for simple sound effects in type-in zine listings.

For more details on the P8SCII control characters, see the manual: https://www.lexaloffle.com/pico-8.php?page=manual

Custom Fonts

A custom font can be enabled using control character 14 (or by setting bits 0x81 at address 0x5f58). A fixed character width and height can be specified at 0x5600,0x5602, followed by 8 bytes per character (8x8 bitmap) starting from 0x5608 (character 1). It can be a little fiddly setting the correct data up, so to get started, here's a wee tool that grabs font characters from the spritesheet and generates a snippet:


The output snippet is 7 tokens, and can be pasted into your cartridge. Here are some example fonts and their snippets:

The one on the right is from @thattomhall's SPRITEFONT cartridge: https://www.lexaloffle.com/bbs/?pid=75073#p

Snippets: https://www.lexaloffle.com/dl/files/font_snippets.txt

(that reminds me, there needs to be a good way of posting long snippets like this on the bbs)

Sprite Fill Patterns

It is now possible to apply fill patterns to sprites, which includes spr(), sspr(), map() and tline(). A special bit (0b0.01) is set when calling fillp() to turn this feature on. Each sprite pixel is mapped to TWO colours using the (previously undocumented!) secondary palette, and these two colours are used to draw the pattern.

There are more technical details in the manual, but here's an example:

If you add the following fillp call to /demos/jelpi.p8 in init_level() (tab 5):


The result is:

There's a lot going on here!

  • I've added the call to fillp() after reset(), as it sets fill pattern state to default values.
  • ♥\1 is a fill pattern constant with \1 (integer divide) to remove the alpha bit (0.5)
  • 0b.01 (0.25) is the bit that turns on fill patterns for sprites
  • 0b.001 (0.125) is another bit that applies the secondary palette mapping to ALL drawing functions, including a rectangle that is drawn at the bottom of the mountains.
  • the default secondary palette is being used, which consists of the original colour + a slightly darker counterpart. For example, 12 (0xc) maps to 0xdc. This could be changed with pal(12,0x78,2).

I think there there will be some interesting unexpected ways to use this feature, but a nice immediate example by @johanp is to add dithering to textured polygons drawn with tline:

(as the truck turns around, you can see a few frames of checkerboard dithering without destroying the look of the texture)


POKE, POKE2 and POKE4 can be given up to 2048 values to poke into memory in sequence, similar to the DATA statement found in early BASIC variants. Try this to write 6 pixels to video memory:


This can be used with unpack() and split() to dump a bunch of values to ram.:


Values can be read out in a similar manner:

a,b,c=peek(0x7000,3)  --  8,9,0xac

There is a limit of 2048 values in both cases, which means you can copy up to 8k in one go using PEEK4/POKE4.

Locked Mouse Pointer

This is a feature in 'devkit' mode which is normally intended for making development tools and exported binaries, but of course you are welcome to use it for whatever you like :)
(but keep in mind that some players using the BBS don't have a mouse or keyboard)

POKE(0x5F2D, flags)  -- where flags are:

        0x1 Enable
        0x2 Mouse buttons trigger btn(4)..btn(6)
        0x4 Pointer lock (use stat 38..39 to read movements)

.. so you need to poke(0x5f2d,0x5) to enable mouse with lock. stat(38),stat(39) will then give the mouse movements in desktop pixels rather than PICO-8 ones, so that the window size is irrelevant; they can be thought of as abstract motion events with a comparitively high sensitivity. PICO-8 attempts to match mouse movement when entering and exiting locked mode, but this requires setting the mouse cursor at the operating system level, which is not supported in web. In any case, you might get more consistent results by setting mouse lock once at the start of your cartridge and leaving it there (other mouse events will still work as usual via stat 32,33,34).

You can see it in action in @freds72 and @paranoidcactus's POOM: https://freds72.itch.io/poom

Custom Menu Control

Menu item callbacks added with MENUITEM can now elect to keep the pause menu open by returning TRUE, and can also detect if the left and right buttons were pushed. The callback takes an integer parameter that is a bitfield of left and right button presses. Buttons 4..6 all map to each other (can't tell them apart).

For example:

function my_menu_item(b)
    if(b&1 > 0) menuitem(_,"left!")
    if(b&2 > 0) menuitem(_,"right!")
    if(b&32 > 0) menuitem(_,"selected!")
    return true -- stay open

menuitem(1, "select me", my_menu_item)
function _draw() 
    cls(5) print(t()) 

Another example:


Web Gamepad Improvements

The default PICO-8 0.2.2 HTML exporter (and the BBS web player) now includes @weeble's improvements that allow the DPAD mapping, and better hotplugging / controller indexing behaviour.

Thread: https://www.lexaloffle.com/bbs/?tid=41293

Optimisation / CPU Changes

PICO-8 0.2.2 underwent a fairly aggressive optimisation pass; heavier cartridges use around 20% or in extreme cases 30% less cpu / battery life. I did some further tweaks of CPU costs to keep the theoretical host cpu ceiling as low as possible, which helps a lot on devices like the Raspberry Pi 2 & 3. Let me know if you have a cart that's running too slow on 0.2.2 -- I don't think there are many affected, and I'd be happy to help optimise it by swapping in the new binary operators etc. See the changelog for other cpu cost changes.

The following are some notes for the curious -- this shouldn't affect performance considerations when making PICO-8 carts. There was/is a lot of potential to change cartridge behaviour in subtle ways however, so as always, please let me know if you see something weird that was working in previous versions, even if it seems like a small thing.

There were 5 areas that needed improvement:

  1. The garbage collector until now has been doing a full collect every frame. This isn't as bad as it sounds (PICO-8 carts generally generate a lot of garbage to collect), and the aim was to reduce worst frame times rather than average ones. 0.2.2 does a little better by spreading collection out over several frames, and if it can't keep up with accumulating garbage, defers to full collection every frame.

As a result of this change, stat(0) needs to perform a full collect to preserve the meaning previous versions. But don't worry about performance of the host machine in the odd situation where you want to use stat(0) in a released cart (not just for debugging) -- it's really fine! If you're curious to read the raw, non-garbage collected ram usage, I've added stat(99).

  1. There were some 64-bit operations that didn't need to be there. The web builds suffer quite severely from 64-bit ops, but didn't seems to benefit from the other optimisations listed here.

  2. Miscellaneous API function improvements; For example, sometimes memcpy can map directly onto host memcpy 1:1 and doesn't need to go through an abstracted layer. The kind of thing that makes code messier and harder to maintain, but worth it when it's the end of the project.

  3. API function look-ups in Lua. Every time a function like cos,print,spr is called, Lua was performing a table lookup of that function's name. In a cheap, glorious hack, I just made all of them local by default. This shouldn't affect behaviour except when accessing them via _G, and gives quite a decent speed improvement. Lua can handle around 200 locals per scope, and so I used 50 of them -- I don't think any PICO-8 cartridges come close to exhausting the remaining slots.

  4. LUA_TLCF (light c function) calls. Lua does quite a lot of call stack manipulation every time a C function is called. But PICO-8 built-in functions are generally quite simple: the heavily used ones take a number or two and return a single number. So I added a new function type to Lua's internals: a LUA_TSLCF ("super-light c function"). This type of function is only allowed to output a single number by clobbering the position in the stack it was called with. Not a very Lua way of doing things, but it works, and saved a lot of call overhead!

Map Export


.. to get a full-scale png of your map!



Added: SFX filters: noiz (white noise for inst 6), buzz, detune (flange/overtone), reverb, dampen (lpf)
Added: SFX length (leave the second loop value at 0 to use). Can be >= 32.
Added: P8SCII control characters when using print() -- can adjust colour and cursor position etc.
Added: User-defined font at 0x5600, accessible via control character \014
Added: poke(addr, val0, val1, val2 .. valn) -- same for poke2, poke4
Added: can peek multiple values: a,b,c = peek(addr, 3) -- same for peek2, peek4
Added: Locked mouse pointer // poke(0x5f2d, 0x5) and then stat(38),stat(39) to read
Added: right click in sfx pitch mode to grab the instrument of that note
Added: IMPORT command can specify target location in pixels: IMPORT FOO.PNG -X 16 -Y 32
Added: IMPORT -S to shrink the imported image (e.g. -S 3 means shrink from 384x384 -> 128x128)
Added: ctrl-c at empty command prompt to copy the most recent error message
Added: extcmd("screen",0,1) / extcmd("video",0,1) saves files in same path as cart / exported executable or app.
Added: set bit POKE(0x5F36, 0x8) to treat sprite 0 as opaque when drawn by map(), tline()
Added: shift-tab in gfx/map editor for full-fullscreen mode (with no red menu bars)
Added: extcmd("rec_frames") to record each gif frame only when flip() is called regardless of rendering speed
Added: extcmd("folder") to open the folder on the host operating system (where printf, extcmd saves files to)
Added: custom menu callbacks can optionally leave the pause menu open, and can read LEFT and RIGHT button presses
Added: ctrl-h hex mode in map / gfx views (displays current sprite in hex, and shows map tile values)
Added: export map as a single image with export foo.map.png
Added: @weeble's gamepad improvements to the default html shell (dpad layout detection, better mapping / hotplugging)
Added: stack trace on bad memory access e.g. poke(-1,0)
Added: fillp can now be applied to sprite drawing (spr / sspr / map / tline), using colours from the secondary palette
Improved: General optimisation pass; heavy carts use 20~30% less host cpu
Changed: Most api functions are local by default for performance. use "pico8 -global_api 1" if needed for debugging.
Changed: unpack() now has a non-zero cost but still fairly fast
Changed: .. operator has a small cost based on number of characters concatenated
Changed: LOADK vm instruction costs 1 cycles (was 2) // otherwise "c=0" costs more than "c=a+b"!
Changed: removed function cpu refunds; speed-critical calls to bitwise function should use operator counterparts instead.
Changed: Incremental garbage collection each frame for improved performance.
Changed: stat(0) performs garbage collection in order to obtain a meaningful result; use stat(99) for raw value
Changed: options menu always available from pause menu (used to only be available in web exports)
Changed: tostr() returns "" instead of nil
Changed: exporting gif/png from web version now creates a pop-up div that can be dismissed
Changed: print() from commandline automatically wraps long strings
Changed: print() returns the x position of the next character to be printed (can be used to calculate text width)
Changed: glyph constants set only when running cartridge, not when running a command from prompt
Changed: Using printh from exported carts outputs files in the same folder as the .exe / .app
Changed: type() returns nothing instead of causing a runtime error
Changed: fill pattern is cleared when program is suspended by default. Use poke(0x5f2e,0x20) to preserve.
Changed: reset() resets everything from 0x5f00..0x5f7f, same as when program is initialised (including new random seed)
Changed: font tweaks for hiragana, katagana, ampersand characters
Changed: (raspi) separate binaries that support gpio to remove wiringPi dependency and gpio poking-related crashes
Fixed: Diagonal lines in editor contain an incorrect step when snapping to -1:1, 1:-1
Fixed: rnd(tbl) is not random enough when table has 2 elements /bbs/?pid=81092#p
Fixed: add(tbl) causes runtime error. should have no effect and return nothing
Fixed: cursor position in code editor incorrect when changing lines contaning glyphs/tabs
Fixed: CONFIG TABWIDTH does not take effect until restarting PICO-8
Fixed: Selecting sprites from bottom right -> top left and then pasting only pastes a single sprite
Fixed: Moving map selection around with cursor keys beyond original selection leaves streaks
Fixed: stdout/stdin serial() streams should be binary, not text mode (causes \r chars under Windows)
Fixed: printh("hello.txt",fn,true,true) fails to save to desktop when fn has an extention
Fixed: IMPORT FOO.PNG using the current sprite location as target instead of 0,0
Fixed: tonum behaving differently to parser for string numbers out of range. e.g. tonum("-0x9000") should be 0x7000
Fixed: Exporting the same zip file multiple times creates duplicate file entries
Fixed: tline / line clipping // sometimes off by 1px, sometimes incorrectly discarded altogether
Fixed: poking values with bit 0x80 to 0x5f28,0x5f30,0x5f3c,0x5f3e clobbers following address
Fixed: deli(tbl,nil) behaves the same as deli(tbl) -- should have no effect
Fixed: stat(13),stat(15) reporting y coordinates of menu with 0 items
Fixed: memory leak when saving gifs (causes web export to crash after a few records)
Fixed: print() linefeeds clobber multi-line text printed at bottom of screen
Fixed: preprocessor can not handle form: "::
::a+=1" (regression in 0.2.1)
Fixed: When split() by group size (e.g. split("ab12",2,false)), last parameter ignored
Fixed: partial cstore (len < 0x4300) from splore/export clobbering data outside that range on subsequent reload
Fixed: joystick stops responding after unplug and plug back in twice (also happens when some devices sleep / wake up)
Fixed: mkdir(nil) crashes
Fixed: possible to edit an SFX without the cursor visible (confusing)
Fixed: menuitem() callbacks broken when there is no _draw() or _update() defined
Fixed: should only be able to call from commandline: cd mkdir install_games keyconfig info
Fixed: controller menu (pause->options->controls) does not show custom key settings
Fixed: -export failing to find files relative from current path
Fixed: -export failing to locate html template path
Fixed: binary export storing multicart cart names with path (should be named "dat1.p8", not "dat/dat1.p8")
Fixed: pause menu broken when cartridge is launched from splore and run() is called inside first frame
Fixed: text printing does not respect draw palette (was broken in 0.2) // ref: /bbs/?tid=41428
Fixed: for backwards compatibility, non-numbery colour parameters should be taken to mean zero
Fixed: preprocessor: self assignment with quoted function calls on RHS a+=1+cos"0"
Fixed: ctrl-r during pause menu only takes effect after closing menu
Fixed: (bug in RC1) pack(...).n is zero
Fixed: (bug in RC1) using filters noiz:1, dampen:2, lpf is not applied to melodic instruments (but should be)

P#87591 2021-02-15 21:30 ( Edited 2021-02-15 21:45)


This is all super cool! I've been experimenting with the new SFX filters and new text formatting, and the results have been awesome! An excellent update all round :D

P#87697 2021-02-15 21:40

SWEET! Such a great update. Woo hoo! Glad the font was helpful.

P#87699 2021-02-15 21:47

Congrats on the release @zep! This is a lot!

The upside to being so slammed at work that my gamedev time is down to zero is that I get to sit back and watch all the pros do amazing things with these new features and pick up some tips to use when life slows down again :).

P#87702 2021-02-15 22:10

Wow, this is amazing. I'm constantly marveling at how even though there are all these new features in each update, you still end up making it feel like polish on an already amazing product. Almost like filling in gaps and holes, rather than new protrusions out of the original product. Like, "Oh, huh... yeah, that felt like it was missing before."

Anyway, congratulations on this update. I can't wait to play with all the new features! :)

P#87704 2021-02-15 22:23

I had literally just been wishing an update adding some of the hidden music effects (namely the filter) and was elated to find there's even more options than I had originally hoped for.

PICO-8 has been such a fun tool for creating chiptune music and this has already taken brought new life to several tracks that were feeling stale/same-y.

One of my issues was that many of the voices can be very harsh so the filters are a great addition. Having more than one is even better!

I guess this might be a good opportunity to ask if there is any possibility of adding a global speed value in the future that you can sync tracks to? This would make it much easier to adjust multiple tracks at once rather than having to go to each individual one and adjust speed on each track.

The only other feature I can think of would be
a transpose feature to easily adjust song keys but that might be too much for what this is trying to achieve. Either way, this is a fantastic update so thank you very much!

P#87715 2021-02-16 00:54

> The only other feature I can think of would be a transpose feature to easily adjust song keys but that might be too much for what this is trying to achieve. Either way, this is a fantastic update so thank you very much!

There is a transpose feature for individual lines - select the lines you want to change within the SFX and type Shift+a note to transpose the interval from middle C to that note - so, like ... if you had a UI where you could select a line of SFX and edit them all at once ... idk, I could see either or both.

P#87721 2021-02-16 01:38 ( Edited 2021-02-16 01:39)

Will you add multi-channel music export in 0.2.2b or some version afterwards? Nonetheless, congrats for these new filter switches and congrats on this update in general!

P#87725 2021-02-16 04:33

hmmmm, does the custom font feature allow us to change the font in the built in editor?

P#87739 2021-02-16 06:16

I know with all the amazing new features here this one might get overlooked, but the chained peek4 and poke4 are so fantastic! It finally marries the Lua RAM and cartridge RAM in a very intuitive way, which means you can now move data between them seamlessly.

Among other things, loading new image data into the sprite space from strings just became a whole lot easier. Cartridge ROM data can also be peeked out to Lua for long-term storage in the massive 2MB, without using memcpy and clobbering some other part of the 8KB RAM. So much potential here, you could even process a screen effect entirely in Lua. Pico-8 just got shaders. XD

P#87749 2021-02-16 09:26 ( Edited 2021-02-16 09:28)

@StinkerB06 Like, exporting all the individual channels as separate .wav files?

P#87758 2021-02-16 15:18

Congrats Zep!! Really excited for this!

P#87759 2021-02-16 15:23

hi to all :)
and thanks to @zep for pico-8. It is great!
I hope for a mobile version (Android) :D

I have downloaded this version and i think i found a bug:

This new version give me a syntax error in this function.
With previous version it wrks and it works with previous version.
I have the same error also in the cart that i have uploaded before.

function scr_msnlist(dt)
 local mh=_mhl[ui_op]
 if ui_draw() then
     ui_print('dump cantina - job ('..ui_op..'/'..#ui_opl..')\n')
     local st='\n'..mh.tit..'\nlevel:'..mh.lv..'\n\nwe need to '
     if mh.trg then st..='steal a '
    else st..='recover a ' end
     st..=mh.it.nme..' from '
     --if mh.trg then st..=mh.trg.nme..'`s '
     --else st..='our abandoned '   end
     --if mh.lnm=='starship' then st..=' orbits around'
     --else st..=' located on' end
  st..=' a planet in this sector.\nyou will receive '..mh.cr..'cr   on success.\nexact location will be provided upon acceptance of the job.\n\nremember to buy medikits!'
     ui_print('⬆️previous      ⬇️next',0,116)
  ui_btnlbl('begin mission','leave cantina')
    end ui_read()
    if btnp(🅾️) then

returns this sintax error

syntax error line 181 (tab 2)
  else st..='recover a' end
')' expected near 'end'
attempt to call a string value

With some test I found that the problem is this two lines:

if mh.trg then st..='steal a '
else st..='recover a ' end

This syntax seems correct

P#87760 2021-02-16 17:26

Thanks @ViperSnake75 -- I found the problem and will include a fix in 0.2.2b soonish (waiting for a few more bugs to surface)

P#87764 2021-02-16 18:06

Thanks to you @zep 👍

P#87765 2021-02-16 19:01

I think there might be another problem: I tried using the left and right button menu callbacks in my game, and for some reason it seems that whenever i leave the menu, the first left or right press also "leaks" to the game itself?

I edited @weeble's joystick test app to demonstrate: https://www.lexaloffle.com/bbs/?pid=nupeziwozo

P#87791 2021-02-17 07:37 ( Edited 2021-02-17 07:47)

ok got it for 0.2.2b, thanks @rnd
(all buttons are supposed to be ignored after exiting the pause menu even if they are held down while exiting)

P#87794 2021-02-17 09:34

In my case, I specifically released buttons before exiting the menu, but either way a fix for that bug would be awesome!

I almost finished another update for my PICO-8 port of Donsol, which adds toki pona to the list of languages (and also makes it easier for others to implement their own languages!), and it uses the left and right keys in the menu to select the language. Right now, the moment one sets a language and exits the menu, it moves left or right one spot, which on the title screen might lead to picking the wrong difficulty.

P#87829 2021-02-18 05:56 ( Edited 2021-02-18 05:59)

I suspect the NOIZ filter for Instrument 6 will be quite good for horror games. It sounds quite similar to the static noise player after the minigames in FNAF 1/2. I'm excited as heck!

P#87845 2021-02-18 13:04

@zep Found a slight text-selection glitch when using glyphs. When selecting text with the mouse from left to right, the character after a glyph won't get selected until you select two characters past the glyph. If you select from right to left, it works fine. Here's a GIF:

P#87911 2021-02-20 01:37

Another question: I noticed that in PICO-8 itself, the black color is a full black (#000000), but in exported images, it's #020408, to the point that the black color on the FAQ's palette is also #020408. Is this a bug or a feature?

P#87967 2021-02-21 09:24

@zep there seems to be a bug in a certain case of line-drawing where the pixels wrap around to the other side of the screen:


P#88217 2021-02-26 19:32

Hello @zep, I think I found a bug where my game doesn't scale properly in the web player. It seems to draw my rectangles and lines in my pong game possibly at the display's screen size instead of pico 8 scaling the 128x128 display to fit the window. I was able to copy my code back into version 0.2.1B on a different computer to provide the second screenshot. The third picture is how I discovered it on my phone's web browser :o

P#88262 2021-02-27 18:16

@zep Request to make the "|" control character move the cursor by P0-8 pixels instead of P0-16 pixels.

Rasoning: The "-" control character moves the cursor P0-16 pixels but the cursor will also automatically advance to the right on the next character. So with "-" you have authority to wiggle a character left or right.

With the "|" control character the cursor won't move additionally. So P0-16 will only gives authority to wiggle a character upwards. But I'd like to wiggle it downwards as well! If only to wiggle it back down after doing somthing like this:

Adding an "\n" doesn't help since that resets the x position. The above spooky font is done using "\v" now since "|" literally can't do it. Applies to "+" as well.

Please Zep, all I want is a spooky skeleton font as a treat!

P#88353 2021-03-01 03:23

@zep How do you terminate the "\a" character. Let's say I want to print out a line character by character like in many JRPGs

This is the code I used. I just add to add "\^1" characters in front of every character in a string.

function slowify(s)
 local ret=""
 for se in all(split(s,"")) do
 return ret

But then if I also want each character to make a sound and add the "\a" character like this


I hear a single complex sfx and I see no text. And tweaking the delay seems to actually change the melody. So I think all of the string behind the "\a" character seems to be interpreted as melody data. If this is not just ab bug but intended, how is it possible to "escape" the "\a" character?

P#88397 2021-03-02 03:45

Ah it seems like a space does the trick!


ret..="\a \^1"..se
P#88436 2021-03-03 06:23

@zep I found an error in the documentation.

        A custom font can be defined at 0x5600, consisting of 8 bytes per character * 256 characters
        = 2048 bytes. Each character is an 8x8 bitfield (1 bit/pixel), where starting from the top,
        each row is a single byte starting with 0x1 on the left.

        The first five bytes (character 0 is never drawn) describes attributes of the font:

            0x5f60 character width in pixels (can be more than 8, but only 8 pixels are drawn)
            0x5f61 character width for character 128 and above
            0x5f62 character height in pixels
            0x5f63 draw offset x
            0x5f64 draw offset y

0x5f60 is the secondary screen palette. You probably meant 0x5600, 0x5601, 0x5602... etc here?

P#88560 2021-03-05 02:51

On a whim, I was playing some older games found using 'search' in SPLORE. A couple of games seem to have odd freezing behavior.

Pico Off Road freezes temporarily between tracks as it builds them. This is okay, I can hang with that, no biggie.

However, this problem can become softlock as it does in 'Picoh-Mummy'. Starting a game, everything locks, but music still plays. Controls do nothing, so it must be Alt+F4 (windows version) quit.

Picoh-Mummy is here for testing/confirming bug:

P#88956 2021-03-14 09:30

@zep I'm not sure this bug? has been reported, assuming it is one.

print("\asfc1") -- plays C1
print("\asfd1") -- plays D1
print("\asfe1") -- plays E1
print("\asff1") -- plays F2 !
print("\asfg1") -- plays G1

IOW, F1 plays as F2, i.e., same as calling print("\asff2").

P#89049 2021-03-16 13:42 ( Edited 2021-03-16 14:26)

Workaround to get a standalone F1 = print("\asfe#1")

P#89076 2021-03-17 02:24

I found myself wishing @zep's font tool would also support importing a font from a snippet... so I extended it! https://www.lexaloffle.com/bbs/?tid=42560

P#90880 2021-04-21 09:31

BUG: go into sprite editor. Hit H. Go into map editor and it will be in tile number view.

Also other weird behavior that isn't always replicatable:
Choose larger sprite size in sprite editor, should reflect i n map editor but sometimes doesn't.

P#93716 2021-06-19 02:08

About the new menuitem parameter:

I noticed that it really only returns 1 for Left press, 2 for Right press, and 16 + 32 + 64 = 112 for X, O or Pause press. Holding multiple buttons will only react to the last button pressed, and never sum bitmasks (except for X, O and Pause, but they are always summed together).

I thought the advantage of using a bitmask was to detect combo like Left+X? Is it intended?

It seems easier to just check equality with 1, 2 and 112 if bitmasks are not used. That would make me spare a few characters too...

Note: I'm trying to get as many details as possible while improving the fan wiki page (https://pico-8.fandom.com/wiki/Menuitem)

P#94360 2021-07-02 18:43

I think the behaviour is intended. We used to have only OX to activate the item, then we got left/right to select from options. Combos are not meant to be used there.

(I’m surprised to read about Pause; I expected it to close the menu, not activate the item callback)

P#94381 2021-07-03 00:11

[Please log in to post a comment]