Log In  

Hey there! I made a little twitterbot recently that generates 8x8 sprites for PICO-8:


It tweets both a GFX tag ready for copy-pasting into PICO-8 or the BBS and an image preview of the sprite. Currently it has 3 colour modes (1, 2, or 3 colours on a black background) and 3 layout modes (top-bottom symmetry, left-right symmetry, and 4-corners).

Here are some examples of sprites it's generated so far:


If you're interested in how it works, I made it with CheapBotsDoneQuick and the source is available here. It's actually a pretty simple idea, but generating both the GFX tag and the image preview made it a lot more complicated (and more interesting IMO) than doing either one separately.

twitter procgen sprites
P#32644 2016-11-20 04:07


Cart [#31061#] | Copy | Code | 2016-10-16 | Link

Inspired by @pippinbarr's tweet:

░ ░ ░ ░ GAME IDEA
░ ░ ░
░ ░
░ ░ ░

Made for The Pippin Barr 'GAME IDEA' Game Jam.

play on itch.io

P#31062 2016-10-16 16:00


Uh oh, a flock of ducklings has gone missing, and it's up to Duck Duck to save the day! Can you help them find all seven?

I mean... it's not really your responsibility. I'm sure they'll be fine on their own. Why don't you just take some time to wander around and enjoy yourself? And hey, if you happened to find some ducklings along the way, that's cool too.

play it on itch.io

note: the web version on the BBS won't work because the module's TOTAL_MEMORY is too low, but I've included the cart here so you can still download it if you want. If you want to play it online I recommend the itch.io version.

Cart [#29009#] | Copy | Code | 2016-09-22 | Link

Cart [#28944#] | Copy | Code | 2016-09-21 | Link

updates: fixed bottom-right corner crash

P#28945 2016-09-21 12:10


This is a one button dueling game.

Hold to run, let go before passing to attack.

Whoever hits hardest wins.

If neither player let go before passing, it's a tie.
If one player let go before passing, that player wins.
If both players let go before passing, the winner is decided by speed. If speeds are the same, it's a tie.

Made for #OneButtonJam.

Cart [#26820#] | Copy | Code | 2016-08-12 | Link

Play it on itch.io!

One of the main things I wanted to try out with this game is an online multiplayer mode using the webplayer + GPIO stuff I experimented with in my PICO-8 twitter feed. You can try that out on the itch.io version of the game, which lets you connect to another player for peer-to-peer matches (using the Peerjs library and a heroku server to broker connections).

All in all it's a pretty simple game, but I hope it's interesting anyway!

multiplayer gpio
P#26821 2016-08-12 20:24


Hey there, this is a game made by Ian and I for the "A Game By It's Cover" jam.

Play it on itch.io

Cart [#27185#] | Copy | Code | 2016-08-21 | Link

2016-08-21: fixed PocketCHIP crash (with help from @MorningToast)
2016-08-15: updated menu navigation
2016-08-12: fixed random palette bugs

space exploration
P#25988 2016-07-27 20:49


Hey there! Over the past couple days I've been playing around with PICO-8's GPIO stuff and put together a simple Twitter client. There seemed to be a decent amount of interest in how I got this to work, so I thought I'd share a quick write-up to give others a potential starting point for using GPIO.

Check out P8T over on itch.io or grab the source on GitHub.

This is more of a proof-of-concept than an actual attempt at making a good Twitter client, but hopefully it's good enough for educational purposes!

I only discovered PICO-8's GPIO support yesterday. As near as I can tell, the GPIO is meant to represent pins on physical hardware so that PICO-8 apps could use accelerometers, LEDs, etc. on a Raspberry PI or PocketCHIP. I don't know how far along the development is on the hardware side, but in v0.1.7 JavaScript support was added to GPIO in the web player, which essentially gives us 128 bytes of browser/cart shared memory! Using this memory is super easy too:

// JavaScript
// initialize the pico8_gpio array before the cart loads (this is the only necessary step)
var pico8_gpio = new Array(128);
// alert the value of the first pin and set the fourth pin's value to 10
pico8_gpio[3] = 10;
// PICO-8
// print the value of the third pin and set the first pin's value to 2
poke(0x5f80, 2);

That's it!

128 bytes is a pretty big chunk of data for a PICO-8 app, so we could probably get by using GPIO as-is without issues in a simple app. However, I wanted Twitter integration: even if I only used one-way communication and stripped out all the metadata, 128 bytes isn't enough to fit a 140 character tweet! To get around this, I had to come up with a more formalized structure for communications. (I've never been much of a networking guy, so feel free to point out better or easier ways to handle this stuff.)

My communication structure uses a simple frame-packet analogy. We start with a frame: a single big block of data (e.g. a tweet) which we then convert into smaller, more manageable chunks of data (packets). Each packet is split into two sections: a header which describes the packet content (length, id, etc.) and a body which contains a portion of the original data.

On the browser's side, this means taking the result of a Twitter search, parsing it into a single string of text, splitting the string into an array of strings where each item has at most X characters, where X is the length of a packet body, and then sending this one-by-one through the GPIO.

On the cart's side, this means reading the header pins and using the values to help us parse and interpret the body pins. It also means concatenating data from multiple packets in order to form a full frame.

The trick to getting this working is to make sure that the browser and the cart are always in agreement on who's doing what. If both were just arbitrarily accessing the GPIO, we'd have no idea what was actually in the shared memory at any point. My solution for this was fairly simple:
-the first header pin always stores either a 1 or a 0
-if the browser sees a 1, it updates and sets the pin to 0
-if the browser sees a 0, it skips the update
-if the cart sees a 1, it skips the update
-if the cart sees a 0, it updates and sets the pin to 1

Initially, I had the browser updating on a setInterval with a fairly large delay, but after some experimentation I found that there wasn't really much benefit to this and put it on a requestAnimationFrame loop instead. Writing/reading to the GPIO doesn't seem to be a particularly expensive operation, so this allows for near real-time communication.

Once we've got a reliable order for our operations set up, concatenating the packet data into a frame is pretty easy too: we use one of the header pins to tell us how many packets are in the current data transfer, and another to tell us what the current packet's ID is. We create a new buffer for frame data when we receive the first packet, and append packet data until the packet ID matches the number of packets in the frame.

My focus was on sending data from the browser to PICO-8, but this system also supports limited two-way communication: after we've read the current packet data in PICO-8, we can replace it with a new packet, and the browser can similarly read it back before it sends the next one. In P8T, the state of the buttons are sent from PICO-8 to the browser in this way. If you've looked at the code for an exported PICO-8 app you'll probably notice that this is a bit redundant: the web player already has some separate variables you can use to query button state, but if you were to use GPIO to create a multiplayer game in PICO-8, you're probably going to need to send more than just button presses and the principle is the same regardless of the data.

Sending text
One of the hurdles in developing P8T was that I was originally sending text data to PICO-8 in ASCII, but PICO-8 has no built-in functionality for converting an ASCII character code into the character string. My workaround for this was to create a string with all the characters I needed and use sub() to grab individual characters based on their position:

// JavaScript
// converts characters to a format which the cart can read
    // case is reversed, characters are offset, and newline is a special character
    charToPico: function (c){
        if(c == '\n'){
            return 0;
            // swap case
            c = (c == c.toLowerCase() ? c.toUpperCase() : c.toLowerCase());
            // convert to ASCII
            c = c.charCodeAt();
            // offset
            c -= this.char_offset;
            return c;
// PICO-8
//ignores control characters except \n
//includes symbols (128-153)

function char(k)
 return sub(chars,k+1,k+1)

What could've been done better
-Currently, only one frame can be sent from the browser at a time. A fairly simple extension would be to place "send" commands in a queue for a more asynchronous experience.
-The browser can send an arbitrary amount of data, but the cart implementation is limited to a single packet. It wouldn't be too hard to recycle the frame/packet structure used on the browser's end to allow for unlimited communication in both directions, but the order of operations would get a bit more complicated (do you send packets in both directions at the same time knowing the frames won't be in sync, or do you wait for full frames knowing that they take multiple frames to send?)
-The twitter integration in general is pretty sloppy since I focused on just getting simple functionality working. Tweets are pulled one at a time and only on user-request; it would make a lot more sense to grab a dozen or so all at once, and then pull in new batches as the user browses through the ones you've stored locally. With a bit more work, you could even add a login and let the user interact with the tweets!

P#25751 2016-07-22 20:33


PICO-8 Styler

Current feature list:
-Page colours can be customized (background, button background/hover, text)
-Canvas scale can be customized, has no border, and defaults to 512x512
-Canvas is centered horizontally and vertically
-Canvas and buttons use image-rendering CSS for sharper fullscreen viewing
-First script tag includes "var require = null;" in order to address a node.js issue which prevents PICO-8 games from running in things like NW.js
-Buttons are "text-align:center" instead of "float:left"
-Buttons are slightly smaller to better fit default canvas size
-Button text can't be selected
-Buttons can be excluded
-Link button label/target can be customized
-Page can be autofocused for more accessible iframe embeds (without this, sometimes PICO-8 games won't receive input until you click on a button)
-HTML5 Gamepad API support can be included for singleplayer or multiplayer

If you have ideas for more useful features, feel free to contribute on GitHub or send me suggestions!

P#25348 2016-07-15 13:53


Cart [#23122#] | Copy | Code | 2016-06-18 | Link

try to fight it

-Arrows to move
-Z to attack
-X to sneak

itch.io page

P#23123 2016-06-18 12:45


Cart [#22591#] | Copy | Code | 2016-06-10 | Link

Oh no! There's been a disaster, and your crew has gotten lost at sea. Luckily, you've got a supremely buoyant sailboat: it's up to you to pick them up and tow them back to safety!

-Arrows for movement
-Z to toggle UI
-X to swap palettes

I went with some extra self-imposed challenges on this one:
-1-bit colour
-No text
-No assets (i.e. sprites, tiles, sounds, or music)

Made for #simplejam.

P#22592 2016-06-10 05:10


The finished game:

Cart [#21359#] | Copy | Code | 2016-05-25 | Link

It turned out pretty good for a first attempt at making a game with PICO-8 in my opinion. The gameplay itself is a little uninspired, but I had a lot of fun playing with the visuals and learning about the system.

Older versions:

Cart [#21270#] | Copy | Code | 2016-05-24 | Link

-Fixed x-overflow/underflow bug
-Changed default palette
-Rough menus
-Generally more stylish

Cart [#21212#] | Copy | Code | 2016-05-23 | Link

Cart [#21188#] | Copy | Code | 2016-05-23 | Link

Still needs a lot of work, but it's turning out ok!

P#21189 2016-05-23 17:12

:: More
About | Contact | Updates | Terms of Use
Follow Lexaloffle:        
Generated 2017-06-23 12:01 | 0.441s | 1835k | Q:82