Hey Everyone! PICO-8 0.1.11d builds are now live on Lexaloffle and Humble! We are still working on CHIP / Pocket CHIP builds -- I'll update this thread when they are live. [Edit: they're live now with 0.1.11g]
Welcome to the Core
Despite the unassuming version number of 0.1.11, this update marks something of a milestone: The core of PICO-8 is now feature-complete, with API and specifications that are likely to remain fixed. Before it becomes entombed as a read-only blob of C code however, there is still some time before beta to address any issues that crop up. Let's see how 0.1.11 works out and what points of friction emerge.
One of the goals of PICO-8 is to create a stable, familiar medium in contrast to the shifting sands of modern software development. Instead of growing by changing the core of PICO-8 over time, I'm aiming to settle on a minimal, eternal component that can be built on top of (improved tools and bbs integration), extended sideways (extra ports / host platform support), built out from the inside (making useful snippets and carts!), and around (nicer BBS, cartverse, documentation, resources and community events).
v0.1.11 is also the point after which PICO-8 and Voxatron co-development start to part ways -- Voxatron's API and specification is a superset of PICO-8 v0.1.11's. The upcoming Voxatron update looks basically like a 3D PICO-8, with its own version of splore, png cart format, labels, and bbs integration. I messed up the Voxatron release plan partly because of committing to this -- but more on this later in a separate post. o(_ _)o
Many thanks to the numerous PICO-8 users who helped iron out bugs in the 0.1.11 release candidates. I snuck 0.1.11 out via twitter thinking it was pretty solid, but it took 3 more builds to get right. If you find any old carts that don't run or behave strangely, please ping me on twitter, or better still, post a bug report in the support forum. There will be another follow-up (0.1.12) to catch any left-over issues. After that it will be onwards to beta (0.2.0) \o/
Also special thanks to Gruber for help with the SFX editor, rez for helping shape fill patterns & cpu changes, and everyone who posted thoughts and suggestions on the BBS -- many of which I folded into this update. I haven't posted much this year due to going into blinkers-on just-make-the-thing mode, but I do read and appreciate every piece of feedback. I'll be re-visiting some older posts to update how things have turned out, and I'm also looking forward to joining the party and making some more carts too :D
New Features
Binary Exporters
PICO-8 can now generate stand-alone, distributable binary versions of carts and multicarts for Windows, MacOS and 64-bit Linux (dynamically linked with SDL2). Use the export command with a .BIN target, with the -I switch to choose an icon (or skip to use the cart label by default):
> EXPORT JELPI.BIN -I 48 JELPI.BIN JELPI.BIN/WINDOWS JELPI.BIN/LINUX JELPI.BIN/JELPI.APP |
Multicarts can be created the same way as exporting HTML -- just add up to 15 .p8 or .p8.png filenames at the end of the EXPORT command. Bundled carts behave just the same as local files -- they can be RELOAD()ed, CSTORE()ed to, and chain loaded with LOAD(), using the new breadcrumb and parameter features explained below.
SFX Instruments
Until 0.1.10, each of the 32 notes in a SFX were internally described with 15 bits: 6 for pitch, 3 each for instrument, volume and effect. 0.1.11 adds one extra bit to round out the 2 bytes: "SFX instrument mode" that can be set by toggling the button to the right of the instruments list.
When it is set, the instrument buttons turn into indexes 0..7, and when placing notes you'll see the instrument index appear green instead of pink. Instead of playing the built-in instrument, these notes will trigger the SFX of that index. In other words, SFX 0..7 are acting as instrument definitions. Each note will advance at the same speed as the definition, with the pitch shifted (relative to C-2), the volume multiplied, and the effects layered on top of each other. This can be used to reach a greater range of pitches, create per-note changes in texture and tone, and set up detailed volume envelopes.
Here's a rundown of other new SFX editing features, and a quick introduction to SFX instruments by Gruber (check out the other tutorials too!):
Fill Patterns
Along with SFX instruments, fill patterns are a late addition to the PICO-8 spec. In both cases I was planning to keep them as secret features, but they turned out to be too much fun and I couldn't wait! From the manual:
fillp p The PICO-8 fill pattern is a 4x4 2-colour tiled pattern observed by: circ() circfill() rect() rectfill() pset() line() p is a bitfield in reading order starting from the highest bit. To calculate the value of p for a desired pattern, add the bit values together: .-----------------------. |32768|16384| 8192| 4096| |-----|-----|-----|-----| | 2048| 1024| 512 | 256 | |-----|-----|-----|-----| | 128 | 64 | 32 | 16 | |-----|-----|-----|-----| | 8 | 4 | 2 | 1 | '-----------------------' For example, FILLP(4+8+64+128+ 256+512+4096+8192) would create a checkerboard pattern. This can be more neatly expressed in binary: FILLP(0b0011001111001100) The default fill pattern is 0, which means a single solid colour is drawn. To specify a second colour for the pattern, use the high bits of any colour parameter: FILLP(0b0011010101101000) CIRCFILL(64,64,20, 0x4E) -- brown and pink An additional bit 0b0.1 can be set to indicate that the second colour is not drawn. FILLP(0b0011010101101000.1) -- checkboard with transparent squares |
[tweet ]
Code Tabs
You can now organise your code into numbered tabs. They are not separate files, but rather the same block of code chopped up with special markers (internally: "-->8"). Hovering over a tab number displays the first line of code if is commented, which can be used as a makeshift method of naming tabs. To remove the right-most tab, just delete all of the text in the tab and then move off it.
Editing operations like undo, search and selections apply per-tab. It isn't currently possible to search across tabs -- this will be added later along with improved error messages that span multiple tabs.
Commandline Scripts
The new -x parameter to PICO-8 can be used to run carts as part of commandline tool chains. For example, if you have a long-winded process for copying data around and generating large multicarts, you could automate the process by creating a single cart that does the job:
-- BUILD.P8 CD("MYPROJ") LOAD("TITLE.P8") EXPORT("MYGAME.BIN -I 1 LEVEL1.P8 LEVEL2.P8 LEVEL3.P8") |
And then run PICO-8 from commandline:
$ pico8 -x build.p8 EXPORT /home/zep/pico8/carts/myproj/mygame.bin -i 1 level1.p8 level2.p8 level3.p8 |
This will execute each line of build.p8 as if it had been typed in from a fresh boot of PICO-8, but without ever opening a window. It isn't truely headless yet because it still requires SDL2 (along with the video/audio driver) -- e.g. you can still play sound from it. I'll look at improving this in the future for people who want to make twitter bots and whatnot.
HTML Templates / Plates
This is still a work in progress as I don't have any sample plates to offer yet! But the basic concept works: you can put html files in {app_data}/pico-8/plates, and use them as templates for the html exporter. The template should include a magic string ("##js_file##") in place of the accompany javascript file's name:
<script async type="text/javascript" src="##js_file##"></script> |
The template (in this example, one_button.html) can then be used when exporting like so:
>EXPORT FOO.HTML -P ONE_BUTTON |
The P is for 'Plate'. I use this more general term because they can act both as templates (custom control schemes like single-button, or to add technical javascript features) and also as faceplates (custom graphics around the PICO-8 screen e.g. based on the theme of the game). When doing the next round of website updates, I'll look at creating a way to submit plates as a community resource.
It is also possible in 0.1.11 to export the .js file separately (EXPORT FOO.JS) so that it is easier to work on the accompanying .html in the same folder as the exported cart.
Splore Menu
An extra per-cart menu can be accessed from splore by pressing the menu button (X and O still immediately launch the cart as before). This menu allows you to open the cart's BBS thread, remove it from favourites, and open a minimal options menu. The options menu includes SHUTDOWN which allows PICO-8 to be used from start to finish with only a controller (in -splore mode).
Extra splore tip that I forgot to mention in the docs: instead of typing SPLORE, you can use just S.
API Changes
- add() returns the value that was added
- assert() can take an optional error message parameter
- coresume() returns an error, making it useful to wrap with assert: assert(coresume(foo))
- getmetatable()
- sfx() takes a 4th parameter: number of notes to play
Time and Date
You can now grab the current local and GM time with stat():
80..85 UTC time: year, month, day, hour, minute, second 90..95 Local time |
Check out the ClockJam!
CPU Costs
There are many adjustments to the cost of calling api functions in 0.1.11. Some of them are due to fixing bugs including the ability to trick PICO-8 into giving back unlimited CPU cycles (!), some are to make costs feel more consistent with each other, to more accurately reflect the real world cost of the host machine (pffft -- like that matters), and finally to give a small bump to graphically intensive carts now that making 60fps carts is becoming more common.
I've tried to tread lightly on the heavy optimisation work done by cartridge authors. For example, kragzeg's technical articles on Dank Tomb rendering are still true. The general rule is that existing carts will run around the same speed as before, or a little faster depending on the operations they use. In a few rare cases they run slightly slower, and I am humbly offering low-cost pattern filling as compensation :P
- Horizontal scan fills are now super-fast (rectfill, circfill)
- sspr() is now the same speed as spr() per-pixel
- line() is faster -- but better to use rectfill() if axis-aligned
- bnot() and peek() cost 1 lua vm instruction more
- Fixed cost calculation of clipped gfx operations
Cartverse Preparation
The PICO-8 cartverse is a collection of interconnected webs of PICO-8 cartridges that can (optionally) exist independently of the BBS, and in the future the BBS will provide entry points to the cartverse rather than being a container for it. This update includes some of of the features needed to achieve this, and the are also useful separately:
BBS Cart Loading
Use LOAD("#45481")
to load a cartridge directly from the BBS. The number can (and normally should be) the containing post id, (not the id of the cart itself), in which case the most recent version of the cart is fetched. This can be called from a running cartridge, in which case the cartridge is immediately launched.
Breadcrumbs
Breadcrumbs allows the user to return to previous carts, much like the back button on a web browser. When LOAD()ing a cart, a second parameter can be used to request that the launched cart inserts an option in the pause menu to get back. The value of the parameter is the label of that button:
LOAD("#45481","BACK TO LAUNCHER")
Parameter Strings
The third parameter to LOAD() is an arbitrary string up to 1024 chars long that can be read by the receiving cart with STAT(6)
. When using a breadcrumb to get back to a cartridge, the parameter that cartridge was initially run with is restored.
The parameter string can also be set with RUN from the commandline: RUN BLAH DE BLAH
Custom BBS Functionality
This isn't a feature by itself but can implemented using these new features. Because the cartverse sits alongside the BBS, it will be (and maybe already is) a viable way to extend the functionality of the BBS. For example: when hosting a jam, instead of having customized web-based theme selection, cart listings and voting, we can do it all with carts. An invite cart could have a countdown clock + a link to a separate theme voting cart when it becomes available, and then afterwards a voting cart could link to all the entries and store results voting on itself. There isn't yet a tidy way to send data back to the jam host, but there will be later! I will try this out for P8JAM3
:D
Changelog:
Whoa. When you put it all in this one post, what an incredible update. I love the direction PICO-8 is headed. Thank you, zep! :)
Woah, that is a lot of changes! Thank you for all! I really enjoy code tabs! Also, I'm really happy, that pico-8 will go into beta soon!
Yay, a new "release post" :D
Normally I love seeing these, if only for the cute characters, but this release... is special. Thank you for all your hard work Zep, much appreciated! :o)
With regards to the "Cartverse"; I'm glad you already coined a name for this, coz I've been wondering what to call the ideas I've been having...
<Thoughts>
I've been thinking for a while now that, with this functionality, we can essentially create mini "PICO-8 Internet", where each cart can be the entry point to other cart "pico-sites", which link to other cart/pico-sites... etc. etc.
Some carts could be like mini websites (info about a topic/yourself/etc. perhaps with code examples/tutorials/etc. all linked together by Post/Cart ID's.
I'm picturing something like a cross-between the old Teletext/Ceefax system that used to be on TV's (pre-internet) and kinda like a good ol' dial-up BBS system. Where you have a few linked carts that represent your mini-site and other people's carts (in this whole Cartverse) can offer up links to yours.
</Thoughts>
Either way... this is all very, VERY interesting times! :D
whoaaa this cartverse concept is blowin my mind
what a great update! The API feels quite well-rounded now, with e.g. date/time access, the sfx length parameter, and that 1 remaining sfx bit used :D
I would trade my soul in for what Liquidream is describing.
Maybe it's even time to make a multicart OS, with browsers and all kinds of stuff!
kinda like a good ol' dial-up BBS system. |
Someone needs to make a Tradewars client.
(I guess you'd need to use the GPIO pins and some javascript to handle the networking? It could be done.)
I haven't had much time for PICO-8 stuff lately but this really makes me want to get back to it :)
Just a heads up, there are two more stray bugs in 0.1.11d that I'll patch in 0.1.11e soon:
- line numbers in error messages are broken for multiple tabs
- btn() with no parameters returns the same as btnp() // doesn't affect many carts, but is very confusing!
@Liquidream
A mini cart internet, yes! There is a lot to take from this analogy -- homepages, hyperlinks, webrings all transfer in cute ways. The parameter strings in this context act like everything after the '?' in web urls, which is why the they are restored when popping back up the stack of previously visited carts -- they are part of the locator.
Something that feels like door games (with or without the cartverse) is something I'm also indirectly aiming for. Expandable MUDs, board games, turned based strategy games. It would be great! The online scores scheme is designed to be abused in order to store small amounts of persistent world data so that we can make such things.
0.1.12 won't be a very big update -- likely sometime in December to scoop up leftover bugs, add some html templates and an in-game options menu.
Any chance of a transpose argument to sfx(), now that that's available for instrument purposes? It'd be nice to be able to give pitch-based feedback (for, e.g., a vehicle engine noise) without using up a bunch of sfx for the purpose.
Please take a peek at this...?
https://www.lexaloffle.com/bbs/?tid=30271
If you think it has any merit, it would be better to consider it sooner rather than later before the current implementation gets too ingrained...
btn() w/o parameters acting as btnp() is a problem in many of my carts. For example in tweetcarts I use
p=(1-band(btn(),3))%3-1+p%63 |
as a shorten syntax for setting player position when pressing left or right. Now it is suuuuper slow. :(
Same in other games where I just check if player press any arrow with
if band(btn(),15)>0 then |
which is kinda broken now.
EDIT: oh, just saw it'd be part of next version bugfixes, cool then!
also btnp() bit 6 is gone (menu button). it could be used with poke(0x5f30,1) to enable a custom pause menu.
well, it wasn't documented, but I was hoping for it to be at some point...
The cartverse in a way solves the mutli-cart problem for BBS carts. Can't partially load data from another cartridge but can break up your game into multiple carts and and have one load the next when you complete the first one.
Please make the editor full-screen on PocketCHIP.
Or at least make the CHIP version load to the console.
We all love Pico-8 for its restrictions. But using it on a PocketCHIP is restrictive enough without being forced to use 128x128.
oh, no...I use the undocumented btnp() bit 6 [start button] + poke(0x5f30,1) for my Zelda game to bring up the map and inventory.
Are we getting a leaderboard system anytime soon? Like just a way to upload high scores to the BBS and download the back to the cart? Or some sort of really low-level networking would be cool too.
This is super cool, started playing with it on my retropie rig.
Being able to exit without using a keyboard or forcing a reboot over putty is AWESOME!!! It fits perfectly into my retropie now!
Unfortunately I'm having a weird bug with the audio where it just cuts out every 10-15 seconds. I don't remember this happening on the last version I used, so it may be new.
Thanks for the hard work, this cartverse stuff is going to be AMAZING.
Oh, I have to use parentheses and commas when using CLS and SPR now! That was a surprise!
What do you mean, Tinglar? Could you give before/after examples?
Assorted bugs I've noticed in 0.1.11d:
- occasionally the editor will start interpreting the "X" key as a left-mouse click instead of a key press. When this happens, it's necessary to quit and restart the program. (Toggling the "keyboard cursor" option does nothing.)
- two of my favorite older carts—Postcards from the Fringe and Endless Sky, both by @electricgryphon—are broken in 0.1.11. Both feature similar visual artifacts and Postcards from the Fringe will occasionally crash on load.
(I'm on a 2017 MacBook Pro / OS X Sierra)
I've seen similar behaviour with the x key on PC. Line keeps jumping to where my mouse is when I'm trying to do any maths involving co-ordinates.
I mean that, before this update, I could write cls or spr x in my code and have them run. After this update, I have to use cls() and spr(x), instead.
How do I update? I Cant wait to make an OS. Something I wanted to do for so long!!
Oh, really? Lua wouldn't normally let you call a function without parentheses anyway. I suspect he fixed a bug. Bummer, though, it would have been nice to save the tokens.
It seems like the i386 version is actually x86-64. It would be nice to get a real i386 version. :-)
file pico-8/pico8
pico-8/pico8: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a589ada4e62f733db872d5a55494f1af37f66726, with debug_info, not stripped
yes, I got the same problem (the linux x86 is actually a 64bit binary). I want pico8 on my old atom based netbook and this is blocking me.
I really like the -x addition. I’ve used Pico-8 to draw some stuff and create maps for some c64 tests. It’s nice to be able to put the exporting into the build process.
I’ve only got my iPad here with me now. Does anyone know if -x and stat(6) work together? I.e. is it possible to give the cart parameters from the command line?
Oh, what a great idea. I have an old HP Mini-Note I should be using for Pico-8, silly me for not thinking of it.
But yeah, I'll need a true 32-bit build for it to run, since the thing runs on a Via Nano (atom-like x86) processor.
0.1.11g is now available at Lexaloffle and Humble.
More bug fixes, correct 32-bit Linux executeable this time, and I've included pico8_dyn in all 3 linux versions should you want to provide your own SDL.
Also, a NextThing build of 0.1.11g for PocketCHIP / CHIP is available! You can update by opening terminal and doing:
sudo apt update && sudo apt install chip-pico-8 |
(password is chip)
Alternatively, it's also included in the list of packages to update when upgrading:
sudo apt upgrade |
Because of improved adaptive framerate handling introduced earlier in 0.1.11, there is much less slowdown on heavier carts running on the PocketCHIP.
There are a couple of features (content filter, cartverse id support) that aren't live yet, but will become operational after the next BBS update.
If there are no serious issues, this will be the last time the file version is bumped for a while, so we can get some future compatibility going again. But you'll need to update to this version in order to play any carts made in 0.1.11g.
Other fixes:
v0.1.11g Added: CTRL-C to copy contents of commandline Added: stat(100..102) for current breadcrumb label, bbs cart id, and hostname (web) Added: content_filter in config.txt Added: Cartverse cart id support (not live server-side yet though) Fixed: Tab preview does not show on mouseover Fixed: Can't paste uppercase characters into commandline Fixed: Preprocessor can't handle glyphs in form: "♥.x += 1" Fixed: Unsaved changes sometimes reported when filename is not set Fixed: Pause menu doesn't open inside infinite loop inside _draw Fixed: load() crashes when "parameter string" parameter is not a string Fixed: cstore(),reload() crash when external cart filename is not a string Fixed: printh(str, "@clip") fails for glyph characters in str |
Wow, nice! Love, love, love the direction cartverse is headed. And the content filter? Awesome. That will be fantastic to have when working with kids. Thank you so, so much! :D
Hey zep, I have an issue. I think it's been around for quite a while, but since you're close to locking some stuff down, I think I should get it on your radar:
Background: if I run the app windowed, on Windows 7 x64 in my case, with my monitor set to a refresh rate of 60Hz, it holds vsync as steady as a rock. I can flip between red and green and get a uniform khaki color. No tearing, no dropping, just a little bit of blood from my eyes.
However, if I up the desktop refresh rate to 120Hz, which is becoming much more common among gamers, and which I would prefer to do all of the time, pico-8 starts tearing very badly and dropping frames all over the place. It's a real mess. My eyes have exploded so many times that I've had to ask our waste disposal company for an extra biomass container.
I'd expect it to handle an even multiple of 60 gracefully. I know 144Hz or 90Hz isn't going to work cleanly, but if the desktop is running at an even multiple of 60, it really ought to be able to work flawlessly.
If it helps, the FPS counter wibbles around the neighborhood of 110-115fps, but I've seen it go as low as 107 and as high as 120.
Also, this is irrespective of window size and scaling, and I'm running it on a very capable cpu with an extremely capable gpu.
Finally, this is the program I test with:
function _update60() end c=8 function _draw() rectfill(c-8,0,c+116,127,c) c=19-c end |
Also, this other bug persists in 0.1.11g:
Thanks for the update so I can use assert(coresume( feels cleaner than the workaround I had been using before to printout errors from within coroutines!
I'm very happy with this update.
Specially with the command line option -x.
This will open the way for tool making.
it still requires SDL2 (along with the video/audio driver) -- e.g. you can still play sound from it
I tried playing sounds with the -x option but it crashes :C.
I hope there will be a way to create a command line utility for playing music only carts.
Eg:
Plays Music 0 All Channels
pico8 -m 0 music.p8 |
Plays Music 0 Channel 1
pico8 -m 0 -c 1 music.p8 |
Plays Music 0 Channels 1 2
pico8 -m 0 -c 1,2 music.p8 |
Thanks for all your efforts zep :)
Was messing around with 0.1.11G in the music editor and I noticed some oddities in SFX editing. Putting a value in the volume column automatically makes a note appear there (usually C1); and then trying to backspace that value or note would result in the entire lineup of notes being bumped up a space, without any noticable way to "insert" a blank note in its' place. The backspacing issue happens on existing notes now, too; so it's not limited to just that. But there doesn't seem to be a way to eliminate accidental note placements in ways that doesn't screw up the rest of the SFX's structure.
Unless I'm missing some new hotkeys now, which I might be. Good thing I had saved before that!
@TonyTheTGR
I think the key you are looking for to insert a blank note is Enter.
To delete without moving other notes, you can highlight some part of the note's row of numbers (using Shift + left/right) and then push either Backspace or Delete.
When entering notes and making a mistake, though, I usually just push Up (to go to the previous note) and and then retype the note, because entering new things overwrites whatever is under the cursor.
As for entering a volume value and making a note appear, keep in mind that the determining factor that indicates if a note is played or not is the volume being greater than 0, so when you set the volume to anything other than 0, you are declaring that there is a note there now :) (and in cases of arpeggiation, the pitch is actually still used in the arpeggio, even if that note has 0 volume, which is why such notes now show up as visible if they are within an arpeggio group)
Ahhh, okay. I was trying "Insert" which wasn't doing anything; and expecting Enter to do the same as the spacebar, to play/pause the section. Thank you!
[Please log in to post a comment]