Chrome 71 (December 2018) implements the new autoplay audio policy for the Web Audio API, which affects the Pico-8 web player. The BBS is OK because it implements a "curtain" that the user clicks on to start the player, which does the Web Audio enable interaction. But this breaks the exported web player as of Pico-8 0.1.11g: If I export a game to its own page then load the page, Pico-8 starts immediately and is disallowed sound. No interaction enables sound after this point.
One fix is for the exported web player to implement a curtain similar to the BBS. I don't know if that meets everyone's needs but would resolve the issue for the exported page. I assume we can work around this by implementing our own player curtain.
Interesting side note: This appears to affect stat() calls regarding sound as well. I have a cart that paused on stat(24) != 0, to wait for music to finish playing. The web export with sound disabled never gets past this point. I added a timeout for the pause to get around this, though I still don't have sound in this case.
I notice that the YouTube field of the BBS profile only accepts alphanumeric characters, and whatever is entered becomes a link of the form www.youtube.com/<alphanumericfield>. I'm mostly ignorant of how this part of YouTube works, but my understanding is that not everyone can reserve a youtube.com/<alphanumericfield> URL. You need a certain number of followers, have qualifying channel art, etc. Everyone gets a www.youtube.com/channel/<randomlyassignedalphanumeric> channel URL, but I can't enter that into my BBS profile and get a working link.
There's some history with G+ URLs that I've forgotten the details of. It looks like anyone can reserve a www.youtube.com/c/<alphanumericfield> URL. At least I have one, not sure how. But I can't enter that in either.
I think the YouTube profile field needs to accept more values and/or provide hints in the profile form on how to link a profile to a channel.
It appears that I have to sign in to the BBS on a daily basis. This does not appear to be intentional, and it's certainly annoying. I believe in the previous version of the BBS we had a one month sign-in expiration.
My cookies seem to be in reasonable shape for expiration dates:
www.lexaloffle.com:
PHPSESSID: when browsing session ends
pass: one month
user: one month
lexaloffle.com without the www also sets a cookie, __cfduid, but this doesn't seem related. I have tried clearing and recreating all of these cookies, with no change of behavior.
Santa Panic! A gift wrapping arcade game for 1 or 2 players, by dddaaannn and TimSwast. This is game 9 of the PICO-8 Advent calendar 2018.
Get those presents wrapped and in the right spots, and get yourself back up the chimney, before you're found out!
- Directional pad to move.
- "O" button to pick up, then "O" again while not moving to drop, or while moving to throw.
- Wrap a present by walking it to a wrapping station.
- Pick up your sack and walk into the chimney to leave.
Two player co-op available! You could use the help, but make sure both of you get to the chimney in time!
ClockworkPi is having a "Black Friday" sale on GameShells, only $119 (40% off) today only!
This is the new version of the GameShell with more memory and microHDMI out. It runs Pico-8 and is my favorite Pico-8-capable handheld to date.
I am not affiliated with ClockworkPi, I'm just passing along the info. Enjoy!
This is Pico-8 running on the Clockwork Pi GameShell, a new hackable handheld game machine. GameShell has an ARM architecture, runs Linux, and works with the Raspberry Pi version of Pico-8.
Featuring a "modular" design, GameShell comes as a easy-to-assemble kit. You need side cutters or a hobby knife to separate the plastic pieces from their sprues and clean up the ends. Beyond that, the parts go together without tools. There are five modules: the main board, the screen, the battery, the keypad, and the speakers. Each module is enclosed in a plastic case with an easy-to-open lid. The modules are connected with little cables, and they all fit snugly in a Gameboy-sized case. There's a headphone jack and a microUSB port for charging, as well as on-board Wifi. The keypad includes D-pad, ABXY buttons, select, start, menu, and shift. You can also get a separate expansion module for shoulder buttons on the back.
This is Pico-8 on the GamePad Digital GPD-WIN palmtop gaming computer. I won't give this a detailed review because there are better sources of info on this machine, and it's no surprise that it can run Pico-8. But since I posted pics of RaspiBoy I thought it'd be fun to show it off in comparison.
GPD-WIN is a bit famous for being surprisingly good at what it does, but if you haven't seen it before: 5.5 inch touch screen, Intel Atom processor, teeny keyboard, built-in game controls (including shoulder buttons), and it runs Windows 10. Install the Windows version of Pico-8 and not only can you play games, but you can make games as well. The keyboard is implausibly small, but it compares favorably to a PocketChip. The whole thing folds up to the size of a 3DS.
I made a half-hearted attempt at setting up the game controls with Pico-8. You can choose between three controller modes using a hardware switch, including a mouse-and-keyboard emulation mode for regular Windowing. I ended up using this mode and Pico-8's keyconfig to get a reasonable result with the D-pad and buttons. I bet another mode and proper SDL controller set-up would also work. Mouse-and-key mode is also plausible for the editors: left stick to move the mouse, left shoulder button to left-click, etc. Touchscreen mousing is surprisingly good in general, but I personally would prefer the stick for drawing. There is one (and only one) USB-A port for external peripherals. It also supports Bluetooth.
The GPD-WIN sells for ~$400 USD, so a bit pricier than a RaspPi set-up (or any handheld game machine subsidized through licensing). It's also a plausible option (only option?) for playing Steam games in a handheld-like, which appears to be its chief purpose. I don't think I'd use it for apps unless I were desperate, or could use its mini-HDMI out and peripherals.
GPD-WIN has a subreddit of devoted fans, and the subreddit has a FAQ.
This is the RaspiBoy handheld console kit running Pico-8. Inside, it's a Raspberry Pi Zero connected to a TFT display, a LiPo rechargeable battery, a small speaker, a custom controller board, and a built-in full-size SNES-style controller including shoulder buttons on the back. The custom board provides two USB-A ports for data, a microUSB port strictly for charging, mini-HDMI video out, a headphone jack, a volume wheel for the speaker, and buttons for adjusting the display. RaspiBoy ships as a solderless kit that does not include the RaspPi Zero.
The two big ideas here are the full-size SNES-like controller grip and the injection molded case. Injection molding and silicone membrane pushbuttons do more to recreate the mass-market handhelds than any 3D-printed equivalent can. The controller size is comfortable and familiar. Overall, there are a lot of good ideas in the RaspiBoy that we haven't seen yet in this increasingly populated category of small-run manufacturing of Raspberry Pi-based handheld game consoles. The general design ticks a lot of boxes in my ideal version of this concept.
Unfortunately, there are some significant failures in the details. The large grip comes at the expense of a wide frame around the TFT screen. As shown in the picture, Pico-8 by default doesn't fill the frame, and the low resolution makes even Pico-8's chunky typeface difficult to read. (I have not yet experimented with options and config to fix this. The -width and -height command-line arguments may come in handy.) A flaw common to RaspPi-based handhelds is the need to formally shut down the operating system before turning it off, or risk corrupting the filesystem. (This could be fixed with custom software and a "soft" power button, but it'd be a project that I haven't seen anyone attempt yet.)
While the silicone membrane buttons have a familiar feel, they're a pain to assemble as part of the kit. Plastic buttons sit atop the membrane, and the membrane makes contact with simple copper pads on the circuit board. Getting these to line up while you push the two sides of the case together is difficult, and it took me multiple tries to get it to fit together correctly. Even when fully assembled, the buttons are too unreliable for gaming performance. I had far better luck sticking a prefab USB controller into one of the ports than I did with the built-in controller.
RaspiBoy doesn't use any custom software: it's just RetroPie in a common RaspPi configuration, and you install it yourself. So I'm not sure how to explain that Pico-8 misbehaves and crashes after a few minutes of play. I'm tentatively inclined to blame the RaspiBoy, the RaspPi Zero, or possibly the way the controller board connects to the Zero using pogo pins pressed up against the test pads. Needless to say, it's a deal breaker if I can't actually use it to play games reliably. I doubt I'll have the time or patience to troubleshoot this properly.
The basic RaspiBoy kit sells for 75 euros (~$90 USD) from http://www.8bcraft.com/.
Picotool is a library and toolset for manipulating Pico-8 cart data, useful for build workflows, as well as cart generation and transformation experiments. Many Pico-8 devs use it for its code minification feature (p8tool luamin), which can be handy when your game's code is near the uncompressed character limit.
A more recent feature is "p8tool build", a tool to assemble carts from multiple files. This tool takes a cart and replaces a type of its data from another file. For example, you can copy the spritesheet from another cart like so, such as to collaborate with an artist working in a separate cart file:
% p8tool build mygame.p8.png --gfx sprites.p8.png |
You can pull in Lua code from a .lua file with the --lua argument:
% p8tool build mygame.p8.png --lua mygame.lua |
When you use --lua, you get an especially powerful feature: build-time support for Lua's require() statement. The main .lua file can call require() to include code from additional .lua files, such as reusable libraries. It supports several features of the official Lua require() statement, such as only including a module once, and module return values.
You can get Picotool from its Github repo, as well as file bug reports, here:
Next Thing Co. now has an alpha test image of the next version of the PocketCHIP software (4.4 alpha) that includes Pico-8 1.9. If you don't mind installing an alpha version (which may have bugs that cause data loss), it's easy to give it a try. It's easy enough that you probably don't even need instructions but there's one bit that I found by guessing so I thought I'd write it up.
You'll need a computer running Chrome, a USB-to-micro-USB cable, and your PocketCHIP. Ideally, the computer would be plugged into power so it doesn't lose power in the middle of the update.
- In Chrome, go to http://flash.getchip.com/. If this is your first time using the CHIP flash utility in Chrome, it will prompt you to install the Chrome extension. Do so.
- Connect PocketCHIP to your computer via the USB cable.
- Turn on PocketCHIP. Allow PocketCHIP to boot up to the main menu.
- On PocketCHIP, press the "power" on-screen button. In the power menu, select "Flash Software."
As of 0.1.7 the GPIO feature is advertised as in development and involves the memory region 0x5f80-0x5fff (128 bytes). In the web player, this memory region can be accessed by external JavaScript by defining the window global pico8_gpio = new Array(128). Does the RaspPi build do anything with actual RaspPi GPIO pins yet? Does the bundled PocketCHIP version do anything with GPIO? (I get my PocketCHIP on Monday.)
I wrote a two-way memory mapper to watch this region and set values as I messed with stuff and didn't get very far. There are some necessary features, such as setting pin modes, that are either missing or encoded in an undocumented way in the memory region. I don't see any activity in either direction if I set pin modes outside of Pico-8 either. I verified my set-up with regular GPIO test code. I also took a quick guess based on the strings tool that Pico-8 was using a GPIO driver with C functions such as gpio_write(), and I tried setting debugger breakpoints and saw no hits, but I'm not confident I did that correctly so that's not conclusive. (Reverse engineering newb. :) )
Any official word? Has anyone had success reverse engineering in this area? Any reverse engineering tips or suggestions?
I just got a Pimoroni Picade, an arcade mini-cabinet for use with small board computers like the Raspberry Pi. It's a great match for PICO-8!
See also a short video I posted to Twitter.
The cabinet is $240 / £180, not including the Raspberry Pi and power supply. The cabinet goes together with a screwdriver (no soldering) and is fun and easy to build. (Be sure to refer to the assembly video in addition to the written instructions.) The result is solid and gorgeous.
I used a RaspPi 3 for my Picade. I strongly recommend the USB audio adapter that Adafruit sells, a major improvement in sound quality over connecting the Picade speakers directly to the RaspPi headphone jack. RaspPi 3 has built-in wireless Internet, but if you're using an older model you'll also want a RaspPi-compatible USB wifi dongle.
I'm happy to announce the relaunch of the Pico-8 wiki!
I've spent the last few weekends writing articles and reference material for Pico-8, including complete API and command references, a memory map (including format details), a summary of the Lua subset, and tutorials on several subjects. This is very much a rough draft and I still have a list of to-dos, missing articles, more thorough sample code with screenshots, and some stuff I want to reorganize.
But it's a wiki, so you can help! Corrections are welcome at this stage. If you want to discuss a change before making it, hit me up on Slack or use Wikia's messaging feature or just reply here. But don't be shy about changing things directly.
Let me know what you think!
--
Two possible points of controversy I'll mention up front:
-
I tweaked the theme colors so they're reasonably readable, matching the forum site. I'm still a bit concerned that the Pico-8 red is unsuitable for link and header text. One of my monitors apparently doesn't support sub-pixel rendering or something and blurs it all to hell, but I'm not sure how big a problem that is. I tried a bunch of options and all the others seemed to drop the Pico-8 feel of the site. Suggestions welcome.
- The cos, sin, and atan2 articles currently use a different convention to explain the y-inversion than the official docs do. A quick survey of the Slack group led me to try and explain it as inverting the angle direction and not the sign of sin(). This works until you get to atan2, which requires inverting the dy argument to fit that model. So the choices are counterclockwise with inverted sin() result, or clockwise with inverted atan2() dy argument. Inverting a result seems less problematic than inverting an argument, so I'll probably change it back. (I already have the diagram drawn.) Feedback welcome here as well.
Thanks!
-- Dan
Here's a simple ebook reader with the first three chapters of A Tale of Two Cities. Press X to advance (once per paragraph / page).
This is a tech demo of some tools I've been working on for developing text-based games. It'd be more impressive if it were an actual game, but this victory was hard won so I'm posting it. :)
Notes:
-
Text is stored in cart data, not as string literals in the code.
- The original source file does have the text as string literals in code. I use a post-processor to extract the string literals, pack them into text data stored in the cart, then replace them with string IDs. I use a custom syntax to flag which strings ought to be extracted so I can still use regular string literals elsewhere. The processing tool lets me adjust the location of the text in memory, so I can set aside space for sprites, sfx, etc. by limiting the size of the text data region.
I wrote a new tool that turns carts upside down.
% ./p8upsidedown jelpi.p8.png |
The tool is built with the picotool library (discussion). This version of the tool inverts the sprites, inverts the map, and translates the code to use inverted coordinates for drawing functions.
This is meant as a hack/demo and is known not to work with every cart. It works with many carts, and some of the failures are interesting. Notably:
-
The code translation increases the token count, so large carts (Celeste, Dusk Child) can't be turned upside down.
-
This version doesn't support spr/sspr calls that draw a rectangle of tiles. This wouldn't be too difficult to support: it'd need to flip the entire spritesheet not just individual sprites, translate the sprite IDs in the map, and extend the code to rewrite sprite ID args. But I have other things to do this weekend. :)
-
The print function will always print left to right, so we compromise and merely relocate the y coordinate for print / cursor calls. There's nothing the tool can do with carts that call multiple coordinate-less prints.
- I wrote this to exercise and demonstrate the picotool libraries for mutating Lua code via the AST. The lib doesn't know how to write out an arbitrary AST and preserve other comments/spaces, so p8upsidedown generates hideous code. Unfortunately the luafmt writer isn't entirely up to snuff either so it's not much help. This is mostly not an issue to Pico-8, though I did find a bug where Pico-8's special "t += val" syntax rejects a newline between the "+=" and the "val", which p8upsidedown might accidentally introduce.
Anyway, a fun weekend hack with picotool. Enjoy!
-- Dan
I'm pleased to announce picotool, a set of tools and Python libraries for manipulating Pico-8 game files. picotool can read .p8.png and .p8 files, and can write .p8 files.
To get picotool and learn how to use it, visit the picotool Github repo.
The p8tool command is a multi-tool with multiple functions. You can run it like this:
% p8tool stats helloworld.p8.png hello world (helloworld.p8.png) by zep version: 0 lines: 48 chars: 419 tokens: 134 |
picotool currently includes the following tools:
- build: builds a cart from pieces of other carts
- stats: a statistics reporting tool
- listlua: prints the Lua region of a cart
- writep8: converts a .p8.png cart to a .p8 cart
- luafmt: writes a new .p8 cart with Lua rewritten with regular formatting, to make it easier to read
I don't think anything ought to change, but I thought this was interesting. Pico-8 allows this:
x = 1 if (x == 1) do print('a') end if (x == 2) do print('b') end |
Notice that this is not "if-then-end" but "if-do-end". This appears to be supported accidentally due to the "if (...) ..." shortcut, described in the manual as:
IF THEN END statements on a single line can be expressed without the THEN & END IF (NOT B) I=1 J=2 -- is equivalent to: IF (NOT B) THEN I=1 J=2 END -- note that the condition must be surrounded by brackets. |
The intent is for "if (cond) exp..." to parse expressions to the end of the line. However, if the last expression is a do-end block, the block is allowed to span multiple lines. Of course, this requires that the condition be in parentheses.
I found 7 carts posted to the BBS that use "if-do-end" across multiple lines. Pico-8 does what's intended, so it's hard to call it a mistake.
Unrelated: "if (cond) block else block" is undocumented but supported. "if (cond) block elseif (code) block else block" is not supported. The else's block is optional (though pointless to omit): "if (cond) block else" I found 13 carts using the else form of short-if.
As of version 1.2, PICO-8 includes a command useful for debugging: printh("string") This command prints a string to the host operating system's console. You can put printh() calls in your code to examine events or state without cluttering the game screen with debugging information.
So how do you see the host operating system's console?
In Linux, you probably already run the "pico8" command from a terminal window. If you don't, locate where you put the "pico-8" directory, then run the pico8 command from a terminal window using its full path. For example:
~/pico-8/pico8 |
In Mac OS X, instead of double-clicking the PICO-8 icon, open Terminal, then start PICO-8 with the following command, adjusting the path to match where you put the app. For example:
/Applications/PICO-8.app/Contents/MacOS/pico8 |
In Windows, instead of double-clicking the PICO-8 icon, open Command Prompt, then start PICO-8 with the following command:
"\Program Files (x86)\PICO-8\pico8.exe" |