Log In  
BBS > Lexaloffle Community Superblog
This is a combined feed of all Lexaloffle user blogs. For Lexaloffle-related news, see @zep's blog.

All | Following | PICO-8 | Voxatron | General

Just wanted to share my %95 complete Pong game in order to get some feedback. The main thing I'd like to change is make the ball run faster after every hit, and add some rudimentary AI for a single player mode.

P#77346 2020-05-29 01:49

Hi! It would be convenient to have an option in the cart submenu to save a file from BSS to local carts, for systems that are not always connected.

For the carts that only have numerical IDs or generated names, it would be great to have a new RENAME command in the console :)

P#77341 2020-05-28 23:25

Little experiment with different ways of painting a canvas moving pixels.

⬆️⬇️ more/less painters
⬅️➡️ next/prev mode
❎ change palette

Cart #pixelpainters-0 | 2020-05-28 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

P#77340 2020-05-28 23:07

Cart #the_state_of_things_0-0 | 2020-05-28 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

this thing really pushes the CPU, it's a bit laggy on web

P#77299 2020-05-28 18:55

So this is probably going to be a long, weird post, and is inspired by this post by @Mot a few weeks ago. I kind of dislike the way that Pico-8's cartridge RAM and Lua RAM exist in different worlds, and how everyone eventually uses huge strings to store data on the Lua side, when they run out of token space. It's fine to do that, and in fact I love that the option exists, but is it really a good default way for people to bypass the Pico-8 limitations? I have an idea I want to float to the community about this.

My proposal is to add two functions to the API, that convert between a Lua table and a cartridge bitstream. Using them to get your token count down would be a pre-publishing task, but it could be automated so that you only have to comment out the table to publish your game:

table = { true, x=15.5, [0]="yes", {"why?"}={"because","lua","supports","this","too"} }
len = luastore(0x0,table[,max_length]) --stores at 0x0 in cartridge RAM (not ROM), returns length of stored data
--cstore(0x0,0x0,len) --ROM is much slower and limits what these two functions can do, so keep it optional
table = luaextract(0x0[,len]) --use length if provided, otherwise it's at the start of the bitstream

In addition to giving people a standard way to store things without wasting a large number of tokens decoding the bitstream, this also does a lot to connect the Lua and cartridge worlds, and makes things like saving games trivial:

save_data_table = luaextract(0x5e00) --length is explicitly encoded at the start of the bitstream

But in addition to those advantages, it also gives people an opportunity to store data in a compressed bitstream that is standardized across cartridges, and gives a real use case for the 0x4300-0x5dff user data section of memory as temporary Lua storage! Writing your own encoders and decoders can be fun, but a fast, internal system that doesn't use your limited token space would open up this kind of development for a lot more newcomers. I think it caters to the idea of a cozy development environment, since it makes hitting that token limit barrier easily fixable for many creators, and less demoralizing.

Demo implementation

The rest of this post is a sample implementation of how Lua data could be serialized quickly, but with a decent amount of compression so that it works for the intended purpose. I did this more for fun than anything, and I'm sure there are people here that could do a better job of this, but hopefully this explains what I was thinking:

compressed bitstream storage format, for types: NUMBER, STRING, BOOLEAN, TABLE

All bitstreams start with an implicit 16-bit header, representing the total number of bytes stored. This is more a safety measure than anything else, and can be bypassed with a clever destination offset of 2.

All other LENGTHs are stored as packed ints: [2 bits: coded length in nibbles][4-16 bits: value]

STRINGs are stored as: [LENGTH][x bytes: one per character]

DATA is stored as: [4 bits: number flags][2 bits: type code, if non-number][type-specific data...]
Number flags prioritize compressing numerical data first, since it is assumed most common.

NUMBER DATA is stored as: [non-zero in 0xff00][non-zero in 0xff][non-zero in 0x.ff][non-zero in 0x.00ff][1-4 bytes: value]
0000 in number flags = non-number type follows

Two-bit type codes define less common types (6 total bits to declare these data types):
00 = FALSE DATA (end of entry)
01 = TRUE DATA (end of entry)
10 = STRING DATA (STRING storage follows)
11 = TABLE DATA (TABLE storage follows)

TABLEs are stored as: [2 bits: key flags][string keys+data][number keys+data][non-number/string keys+data]
Key flags optimize what follows in the table:
00 = empty table (end of entry)
10 = string keys only
01 = number keys only
11 = all keys, including BOOLEAN and TABLE keys (for full Lua support, more than for usefulness)

If STRING key flag is active, that section is stored as: [LENGTH of string keys][STRING][DATA][STRING][DATA]...

If NUMBER key flag is active, that section is stored as: [LENGTH of number keys][NUMBER][DATA][NUMBER][DATA]...
Since all keys in this section are numbers, [0000] in number flags is shorthand meaning "previous key + 1". If [0000] is the number flags of the first entry, it is assumed to be the first default key in a table, 1.

If both key flags are active, the final section is stored as: [[2 bits: type code][type DATA...][DATA]]...10
Since all keys in this section are not numbers, 4-bit number flags of DATA type are always omitted for keys.
Since type code 10 (STRING) is impossible in this section, those two bits signify the end of the table structure.
Therefore, in the false-positive case of only NUMBER and STRING keys, this section is only two bits: 10

demonstration encoding:
luastore(0x5e00,{1,[0]=0,str=5.25,[true]=false,{"what"}="why?"}) becomes this bitstream:
[0000|11|11]: [00|0001]:[00|0011][24 bits:"str"]=[0110|00000101|01000000];
              [11|01]:{[00|0001][0000]=[000010][00|0100][32 bits:"what"]}=
                      [000010][00|0100][32 bits:"why?"]
              [10] - end of typed key table, and end of table overall
[table w/all]:[1 str key]:[3 chars:"str"]=[num type:5.5];
              [2 num keys]:[default key]=[num:1],[num:0]=[num:0];
              [bool:true]=[bool type:false],
              [table w/num]:{[1 num key]:[default key]=[str type|4 chars:"what"]}=
                      [str type|4 chars:"why?"]
              ; = 27.75 bytes, store as 30 total bytes in 2-byte integer at bitstream start

I'm interested to hear if people like this idea, and if @zep thinks it would add something to the PICO-8 API. I know it just hit Beta and this is unlikely to be implemented, but I do think it would add a lot of value for many people in the community, myself included.

P#77321 2020-05-28 16:22 ( Edited 2020-05-28 18:28)

Not a bug but a feature request since Zep is still adding features on 0.2.0j. It would be great if the drawing tool would show a preview of the pixel you are about to draw as the cursor moves into the canvas. Here is a gif of what I mean:

This is the default setting in programs like Aseprite. It helps judging the scale and placement of pixels especially when the canvas is blank. I'm so used to it from Aseprite and I really miss this when I jump into Pico-8 to touch up things.

P#77323 2020-05-28 14:46

Cart #agario-0 | 2020-05-28 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

P#77316 2020-05-28 13:38

Cart #ninjarun158-0 | 2020-05-28 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

P#77311 2020-05-28 11:40 ( Edited 2020-05-28 11:41)

Cart #glider-3 | 2020-05-28 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

How far can you get? Press up to give your glider a wind boost but be careful because it will run out!

Made in Limerick, Ireland.

Inspired by a game named Glider that I think was the first game that I ever played, on the old Macintosh Plus.

Let me know how you get on! jamespoolegamescool.com

P#77309 2020-05-28 11:39 ( Edited 2020-05-28 12:26)

Hi, I will post here is the first time.

Yesterday, I tried to post a cartridge for the beta version of the game I made with pico-8 to BBS, but I could not do it because I was not aware that the compress text capacity was very oversized!

So I uploaded it to itch.io instead, you can play from the following URL.

I'm planning finaly to sell the completed full version, but now it's free and I want to improve it further.

I would be happy if you could play it and write a comment!


P#77307 2020-05-28 11:38 ( Edited 2020-05-28 12:00)

As an excercise to better understand the music tool I made a "cover" of the song "Surviving" by Namnambulu. I say "cover" with quotation marks because I suppose it's more... uuuh... "inspired by" =)


Edit: The sound quality in the web player in Chrome is really bad for me. Either try another browser, or click that little "sfx" link under the player to copy the song into pico8 itself.

P#77302 2020-05-28 07:18 ( Edited 2020-05-28 07:28)

Forgive me, I'm new here.

Cart #rinodirodi-0 | 2020-05-28 | Code ▽ | Embed ▽ | No License

P#77296 2020-05-28 02:38 ( Edited 2020-05-28 02:54)

Cart #gulliver-1 | 2020-02-05 | Code ▽ | Embed ▽ | No License

P#72745 2020-05-27 19:02

Cart #pico_skate_iv-0 | 2020-05-27 | Code ▽ | Embed ▽ | No License

Hello everybody,

after years of playing all your amazing Carts, and failing to build something more complex i proudly present you:

"pico Skate IV"

I built this in my free time over the course of two weeks, to get my self away from 3D art and back into programming. I had a lot of fun animating the board sprites by hand and having such huge sprites and tile sets. This also required me to use all of the available sprite and map space with only small unused spaces.

What to expect

In this quick retro game you can control your skateboard along four different levels, each with it's own look and play style. Tricks can be done by jumping on rails or pressing the arrow keys in the air. When you mastered these try to combine you tricks in to a combo by pressing the down button to manual.

P#77285 2020-05-27 18:30

On Firefox and Safari, the PICO-8 screen can go beyond the bottom boundary of the div that encloses it. When this happens, the bottom part of the PICO-8 screen can be masked/covered by elements below the player. On Chrome it always renders okay.

This screenshot shows what goes wrong:

This is the HTML template as exported by PICO-8 (0.2.0e). I only changed it to add some text below the player, and changed the background color of the "p8_frame_0" div to red.

The page is accessible here for anyone who wants to quickly try and reproduce it. Whether or not the problem occurs depends on the size of the view port. You may have to resize your browser window.

P#77253 2020-05-27 17:16

When attempting to load a .p8 cart that exceeds the 65535 character limit (one that may have been created by an external editor or tool), PICO-8 silently drops lines at the end of the cart and does not report errors. It then accepts to save the (now corrupted) cart when pressing Ctrl-S, overwriting the original file.

Here is a sample cartridge for testing purposes; notice that the last print() line disappears when loading it.

One more observation: sometimes, when the 65535 character threshold lies in the middle of a Lua statement, a loading error does appear. I have been unable to identify when exactly.

P#77260 2020-05-27 08:54

Cart #getugibono-0 | 2020-05-27 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

My entry for the RNDGAME Jam 2020 by Tom Hall

Alien brain parasites are invading earth! The disguised themselves as yummy food to sneak through the food distribution pipeline. You have to use your scanner to find the imposters and stop them with your beam cannon!

But don't waste any food!


  • UP & Down to move the scanner
  • LEFT & Right to move the Beam Cannon
  • X to fire your Beam

How to play

The food needs to reach the bottom of the screen. But if an imposter touches you or the bottom, the game is over.

You can find the Imposters with your scanner and use the Cannon to destroy them. The more you destroy, the faster you level up. On each level the game gets faster and harder.

Pssst... There are two secret gamemodes to unlock!

Thanks for playing and have fun!

P#77259 2020-05-27 08:32 ( Edited 2020-05-27 08:34)

Cart #maxbize_portaldeal-3 | 2020-05-27 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Chain portals together to collect all the gold!

How to Play

Hey, listen up! This game is tricky to get the hang of!

The objective of the game is to collect all the gold bars. You have a green collector that will grab them whenever it gets close. While you can't control it directly, you can place portals around the level to get it where you need.

The game is broken into two phases:

Setup Phase:

  • Left click on any wall with a white edge to add a portal
  • Add as many portals as you want. They chain together. For example, if you place three portals, portal one will lead to portal two which will lead to portal three which will loop back to portal one
  • The last portal you placed will be colored blue. The next portal you place will always connect to this one.
  • If you place your cursor near a portal, you will see which portals connect to it. Every portal has two connections - an input and an output portal
  • You can left click and drag an existing portal to move it somewhere else
  • You can right click to delete an existing portal
  • Once you're ready, press Z to end setup

Play Phase:

  • Sit back and watch the madness! You have no control over the movement of the collector
  • Press Z to return to setup


  • The physics is deterministic - every play with the same setup will have the exact same result
  • Use gravity to your advantage! The ball is always accelerating downwards
  • If you didn't beat the level, go back to setup, tweak things, and try again!
  • Every level has a bronze / silver / gold medal. Win medals by beating levels using fewer portals
  • Your progress is recorded. Come back at any time and pick up where you left off, or retry your favorite level!

This game was made in a week for #RNDGAME2020. Follow me for more gamedev! https://twitter.com/MaxBize

P#77256 2020-05-27 07:44 ( Edited 2020-05-27 07:57)

Hello again!

I had a peek into Celeste's code and i believe it is made using ECS or Entity Component systems. It gripped me immediately as i can sort-of understand the way it works, i think. I believe that each entity in a game contains its own update draw and init functions, and in the main update draw and init functions you just have a foreach loop that cycles through them and updates/draws them individually. My first question would be is this right? My second and main question is can anyone expand and put it into (preferably extremely simple) code. I would love to use this new architecture.


P#77255 2020-05-27 07:22

Cart #ufo-0 | 2020-05-27 | Code ▽ | Embed ▽ | No License

A short atmospheric platformer with metroidvania elements. Your UFO has been knocked out of the sky by scavengers and you're now trapped in their swampy junk yard. With the help of some friendly aliens, find a way to disable the electromagnetic pulse cannon that's keeping you from escaping.

This was my entry for RNDGAME Jam 2020.

Left/Right - Move
Z - Jump
X - Use Zapper (once you have received it)
Up/Down - Cycle Zapper Modes (when you have more than 1)

P#77254 2020-05-27 07:11
View Older Posts
Follow Lexaloffle:        
Generated 2020-05-29 04:54 | 0.141s | 2097k | Q:163