This update is focused on resolving runtime issues, with a couple of small but handy features thrown in for good measure:
To grab 32 random cartridges from the BBS, there is now a 'Lucky Draw' list in SPLORE. It is more likely to select cartridges that have more stars, but even unrated carts have a decent chance of appearing. Perhaps this will be a way to unearth some undiscovered gems, or just to find something new to play without scrolling back through several years of carts.
The list is cached, so it only changes every 2 minutes or so. But you can keep paging through the list to get new items forever.
Live Token / Character Count
Select some text in the code editor to view how many characters or tokens are contained within.
Shorthand Print Statements
The shorthand version of print (?"hello") used to require no preceding statement be on the same line, but you can now mix it with things like the shorthand IF statement, as long as it is the last thing on the line:
-- PLAY A SOUND EFFECT WHEN HIT IF (PGET(X,Y)>0) HIT=1 ?"\ADAF"
The PICO-8 Manual is still a work in progress, but it went through a large update last month, with new formatting, dark mode, linkable headers, and more printer-friendly. You can find it on the resources page:
The changelog has been separated into a text file here:
The pico-8.txt included in the distributables has changed to a short version that links to the online manual, but later on I'll bring back the full ascii version and keep it in sync with the html version.
This isn't a very useful feature unless you are manipulating PICO-8 cartridges with external tools, but it has always irked me that it is not possible to write 32k of PICO-8 cartridge to a file that is 32k!
> SAVE FOO32K.P8.ROM SAVED FOO32K.P8.ROM > LOAD FOO32K.P8.ROM LOADED FOO32K.P8.ROM (0 CHARS)
tostr() and tonum() now take format flags that make it easier to deal with large numbers.
PICO-8's numbers are all 16:16 fixed point, which basically means that every number is internally stored as a large 32-bit integer that is divided by 65536 to get the value in Lua. So for example, if you want to use that large integer for something like scores that need to go above the usual maximum of 32767, bit 0x2 can be used to display it in the raw integer form:
?TOSTR(3, 0x2) 196608 ?TONUM("196608", 0x2) 3
To add 10 points to a score stored in this way, you'd need to shift it right 16 bits:
SCORE += 10>>16
0.2.3 contains two changed to cpu costs which does not effect many cartridges:
In 0.2.2c, it was cheaper to write "local a=0+b" than "local a=b" and also "local a=0-b" than "local a=-b". This is because the Lua vm instruction for addition was cheaper than local assignment (OP_MOVE), and for unary minus (OP_UNM). The best solution I could find was simply to reduce the cost of those two instructions to 1 cycle instead of 2, resulting in a slight speed increase in some cases.
- peeking or poking multiple values in 0.2.2c did not cost any additional cpu, so doing something like: poke4(0,peek4(0x1000,0x1000)) was completely free! The same line in 0.2.3 now costs the same as doing an equivalent memcpy.
Next up for PICO-8 is a 64-bit Raspberry Pi Build, and also a preview of a web version that is also handy for running PICO-8 on Chromebooks. I'm also still working on online scores, which required developing some bespoke infrastructure that is optimised for PICO-8's usage patterns, and can handle traffic from exported carts without needing to start charging for PICONET subscriptions or anything like that. I'll test it next month with the release of https://www.doodlemud.com, which is a multiplayer drawing game designed to battletest PICO-8's backend before exposing it to precious cartridge data!
Added: Lucky draw list in splore -- gives a random selection of carts
Added: load/save carts in .p8.rom format (raw binary 32k block)
Added: tostr(), tonum() take format_flags parameter to convert to and from 32-bit signed ints
Added: ord(str, pos, num) returns num results starting from character at pos (similar to peek)
Added: FOLDER takes an optional parameter to open other host directories: BACKUPS | DESKTOP | CONFIG | BBS
Added: Live character / token count of selected text shown at bottom right of code editor
Changed: Removed collaboration list from splore (can still search for sub:collab)
Changed: 0x808 audio has a slight lpf filter on it by default // turn off by setting bit 0x20 at 0x5f36
Changed: tonum(boolean_value) returns 1 or 0 instead of nil
Changed: cursor CR x position set only by print(str,x,y) or cursor(), but not by print(str) (0x5f24)
Changed: character wrap is on by default when using print(str)
Changed: force-pause-menu hold duration is 500ms instead of 300ms to prevent accidentally triggering it
Changed: default gif length for new install is 16 seconds
Changed: ? shorthand can be used anywhere on a line e.g. if (true) ?"yes"
Changed: allow while/if shorthand with no statement, using colon separator: WHILE(BTN()==0);
Changed: added warning to fullscreen_method 2 in config.txt (gives erratic behaviour under some drivers)
Changed: cheaper OP_MOVE, OP_UNM lua vm instructions so that e.g. "local a=0-b" is not faster than "local a=-b"
Fixed: peek() / poke() do not charge extra cpu when reading or writing multiple values
Fixed: fget(n) returns junk when n is out of range (0..255); should return 0 in that case
Fixed: dropped .PNG files not detected as images when filename uses uppercase extension
Fixed: line()/tline() illegal writes caused by faulty clipping when (x1-x0) or (y1-y0) >= 0x8000
Fixed: -accept_future 1 only worked with .p8.png files; now also applies to .p8
Fixed: ?"\a7f" does not play f (happens only when f is the first note)
Fixed: abs(0x8000) return 0x0.0001 (should be 0x7fff.ffff)
Fixed: parameter string (stat(6)) is dropped when passed via RUN command
Fixed: preprocessing of form: "x += x<0 and -1 or 1" broken for operators <, >
Fixed: tab not accepted as whitespace for some preprocessor operations
Fixed: stat(1) wraps around when cpu is >= 2.0 (regression in 0.2.2)
Fixed: pressing SHIFT+ENTER on "local function foo()" or after "if (..) else" doesn't insert "end"
Fixed: pal() does not reset secondary palette to system default
Fixed: 0x808 audio does not respect pausing / volume / is not recorded with extcmd("audio_rec")
Fixed: 'h' pressed in sprite editor toggles hex mode in map editor
Fixed: After pressing shift-tab to toggle 128x128 map view, active draw area is still only 128x112
Fixed: Attempt to navigate to non-existant tab after running: function _update60() _update60=nil end
Fixed: stat(101) not returning cart id when running from BBS web player
Fixed: print() wrapping + scrolling; e.g. from commandline: while(true) print(chr(254+rnd(2)).."\0")
Fixed: integer divide assignment operator (\=) costs 2 tokens instead of 1
@StinkerB06 thanks (as if all my games did not use reload... :facepalm: )
.rom question - is the goal to have 32k data carts or only as a convenient way to generate carts (without the $ù@@## sfx/music format?)
correction: reload does work with p8.rom files
feature request: ability to reload the full 32k of a p8.rom files (now possible with 0x8000 region)
(should multicart games be limited by size rather than number of files?)
@freds72 .p8.rom is only supported by LOAD/SAVE.
I was imagining only using it for authoring single carts, but yes -- I suppose it should really be treated the same by CSTORE/RELOAD. I'll wishlist that for the next update. I'd like to keep the code vs. data section rules the same though (as oddball as they are), so it won't be a way to get the full 32k as readable data.
I have a problem with some code that worked up to the previous version:
if stat(30) then local k = ord(stat(31)) end
ord(stat(31)) always returns null but was returning the correct value before.
It works if changed to:
if stat(30) then local k = stat(31) k=ord(k) end
Hi @zep, thanks for the update!
Could you perhaps support .p8.rom via commandline "-export" like .p8.png?
I'm new to PICO-8 and I find SAVE vs EXPORT slightly confusing, eg. you use SAVE to write a .p8.png cartridge, but -export to do the same via commandline.
Just a suggestion! Useful for scripting and external tools.
Touk> it used to be clearer: we used 'save' (in the console) for the cart itself (P8 or P8PNG format), and 'export' for bits like the spritesheet or a music track.
HTML and native executables are also 'export'; in a way it makes sense that it’s not 'save' because this is compiling to a format that can be distributed but not edited, so 'save' is for pure carts and 'export' for derived things.
Now on the command line, there is no option for saving, so all operationes use '-export', even though it can be used to create pure carts in P8PNG or P8ROM format that can be loaded and edited again!
Hi to all.
I have an issue with this new version. the PRINT function works differently from previous version in handling '\n' character.
In previous version when PRINT encounter '\n' character the line start from the beginning of the previous, now allway starts from 0. I post this screenshot as example.
This works with 0.2.2c version but the same code give me this issue with 0.2.3.
Thanks to @zep for pico-8 that allways remain a great program :)
Yep, I found this version of Pico-8 does indeed NOT run some of my carts correctly as they ran before, @ViperSnake75.
Also if it's ideas people are after, I have several:
While a good number of these ideas have been read and implemented by @zep since my initial request of them 2-years ago, glad to be of service, there are still several I think are also good ideas still in the list not yet done.
Of course pinnacle to all of this would be the ability to compile your .P8 to native Android/cellphone format of APK or OPK as the case might be. Some of the competing Fantasy Consoles have this ability already so it is not an impossibility. Of course I would never leave Pico-8 and am always delighted to see each new version @zep produces.
[Please log in to post a comment]