A couple weeks ago I bought pico-8 to try and learn lua, but now I am stuck with the old version because it's not showing in my purchased products page. Any ideas? (I didn't use the weird 3rd party purchase save thing)
I'm working on a platformer game. I'm having an issue with enemy AI.
I want that the enemy will turn the opposite way once it reaches a cliff, much like a collision with a wall.
I want to make a collision check that will check if the floor of the tile after the enemy doesn't have any flags.
How do I do that if 0 means the first flag?
Very simple sprite-hack of Celeste made for my sister Payton for Christmas. Madeline has been changed a bit to look more like her and some text has been changed to mention Christmas.
All credit due go to Thorson and Berry for the original game.
From slimey, jump!
You can use arrow keys to move, button [O] (key [C]) to explode it.
Here are ↓
function dtb(num)
local bin=""
for i=1,8do
bin..=flr(num/2^(8-i))%2
end
return bin
end
Hallo zusammen, ich bin neu hier und hoffe, viele interessante Dinge zu lernen. Es wird besonders interessant sein, zu versuchen, Ihr eigenes Spiel zu erstellen.
Would anyone help me make a game cause I tryed so many times and its not working.
hey there PICO-8 and Voxatron users!
have you ever wanted to know spooky, interesting, and fun facts about the lexaloffle website?
well, I am here to show you some!
BEFORE WE START, SOME OF THESE POSTS HAVENT BEEN TOUCHED AFTER 2010, SO PLEASE DO NOT POST IN THEM TO KEEP THEM NOSTALGIC
first off: fun username numbers!
¨wait, what are username numbers???!!1/!11¨
username numbers are the number in the URL showing what number user you are!
(Zep is no.1: https://www.lexaloffle.com/bbs/?uid=1 )
user 666: https://www.lexaloffle.com/bbs/?uid=666 @LOR
user 999: https://www.lexaloffle.com/bbs/?uid=999 @PetRawk
user 10: https://www.lexaloffle.com/bbs/?uid=10 @Gray
(notes on @Gray: Gray has NO profile picture, and seems mysterious... EDIT: image fixed!) notes on grey: grey made posts in a game by lexaloffle, chocolate castle. https://www.lexaloffle.com/bbs/?tid=24 and https://www.lexaloffle.com/bbs/?tid=23
user 99: https://www.lexaloffle.com/bbs/?uid=99 (username is not working :( )
user 100: https://www.lexaloffle.com/bbs/?uid=100 @Jumps
OK! here this is the ONLY user so far that has games, and things posted!
user 7: https://www.lexaloffle.com/bbs/?uid=7 @Turtleheart
user 2: https://www.lexaloffle.com/bbs/?uid=2 @admin
user 6: https://www.lexaloffle.com/bbs/?uid=6 @matt (thank you @dw817)
user 55555: https://www.lexaloffle.com/bbs/?uid=55555 @Deerobotr (five fives :)) haha)
FUN POSTS!
this will be the same as username #... sorry.
post 666: https://www.lexaloffle.com/bbs/?tid=666 [WIP] the forest... by @Ruzzle
post 999: https://www.lexaloffle.com/bbs/?tid=999 Blind Devil - ??? by @blinddevil
post 10: https://www.lexaloffle.com/bbs/?tid=10 by @admin (i am guessing it was a test post)
post 99: https://www.lexaloffle.com/bbs/?tid=99 soje023´s Gardens 4 by @soje023 for @zep´s zen puzzle garden
post 100: https://www.lexaloffle.com/bbs/?tid=100 Turtleheart´s new animation wiki by @Turtleheart (user 7)
post 7: https://www.lexaloffle.com/bbs/?tid=7 [thread not found]
post 1: https://www.lexaloffle.com/bbs/?tid=1 [thread not found]
post 200: https://www.lexaloffle.com/bbs/?tid=200 LEX500 by @zep (last comment 2010)
post 300: https://www.lexaloffle.com/bbs/?tid=300 Editor Suggestions (voxatron) by @kavika
post 88: https://www.lexaloffle.com/bbs/?tid=88 I don't know what this is lol by zep
starting point of PICO-8: https://www.lexaloffle.com/bbs/?pid=101089 by zep
if there are any you find that are interesting in number or what is in it, post it in the comments!
thanks, sandwichblamwich
I've published the cart here: https://www.lexaloffle.com/bbs/?tid=45757
I didn't know much about compression algorithms when I started looking into this stuff and, in truth, I still know very little. So this may all be old-hat to a lot of people but hopefully somebody finds it interesting.
What am I compressing and why do I want to compress it?
For the last month or so I've been playing around with Signed Distance Fields (SDFs) first by making some simple pictures with them and using them to handle collsiion detection and then using them as the basis of a procedural morphing animation.
I'm interested in SDFs for a few reasons: I'm not much of an artist but I do like math. If I can substitute math for art in certain situations, that potentially works to my benefit. Also, since SDFs can be used to handle collision detection and they can be updated on the fly with boolean-like operators—union, intersection and difference—they seem like they could be a good choice for modeling level geomoetry and, in particular, destructible level geometry. But mostly I just like playing with them.
In general, you create a function which returns the minimum distance from any point on screen to the surface of whatever object you're modeling and then use that distance to determine pixel colour, or detect collisions, or whatever. But calling functions, especially complex functions as SDFs tend to be, is really slow, especially if you're doing it for every single pixel on screen. To get the animations to actually animate at a reasonable speed I had to pre-calculate all the distances and store them in an array so distance checks became table look-ups. Much faster.
Creating those functions and generating those arrays required a fairly large number of tokens though. So I've been learning about compression algorithms to store those arrays directly and use a, hopefully, smaller number of tokens to decompress them.
To compress, or not to compress
Like most things, it's a trade-off: for a multi-cart system you can probably fit a decent amount of SDF data per cart; for single carts, it's almost certainly not worth it.
SDF data is big. Not as big as I had originally thought but still pretty big. Even though I was ultimately able to get quite good compression ratios we're still talking about thousands of characters worth of binary data per screen of data stored. With a fixed limit of 65535 characters, that adds up fast. In fact, as I'll discuss later, it actually adds up even faster than you'd think. Each compressed SDF only requires three tokens but saving all the tokens in the world doesn't do you any good if you don't have any characters left to use them.
Test data
I mostly used the SDFs from the animation linked above as my compression test data. Here's, sort of, what they look like as distance fields.
Left-to-right, top-to-bottom: Square, Repeated triangles, Repeated circles, Repeated squares, Star, Rotated Star, Line, and Palm tree.
It's worth noting, again, that I'm storing the actual distance data itself and not these images speciifically. The images just give a sense for how the distance fields change and how simple or complex they are. An advantage of working with distance fields in that you can use the same data in multiple ways. Here's a quick little cart which demonstates the idea:
Press 'x' to cycle through the different options. It's the same data in all cases, just being rendered differently.
How big is an SDF anyway?
At first I thought I might have to store fractional values so I'd need 32 bits per pixel. But no. In reality, at least how I'm using them so far, I'm working with integer distances on a single screen. The farthest away something can possibly be on a 128x128 display is about 180 or so along the diagonal: 8 bits is plenty.
Eight bits is definitely an improvement over 32 but still, that's one byte of data per pixel or 16384 bytes per screen of SDF data. At that size, a direct encoding of four SDFs would bust the PICO-8 character limit. The animation linked above uses eight SDFs.
So that number, 16384 bytes, is the base/uncompressed size for all my test data.
Compression algorithms
I tried a variety of algorithms both individually and in combination. These are the main ones.
Run length encoding (RLE)
RLE compresses by replacing a run of identical distances with a single instance of that distance and a number representing how many times it occurs before changing.
It was my assumption that RLE would be a bad choice for SDFs because, although some have long runs of repeated distances, most distances change with every pixel. If your run length is always one then instead of storing one integer per pixel, you're storing two.
Even so, I figured I'd test my assumptions by actually trying it and, sure enough, RLE on its own makes distance data larger, not smaller.
Huffman Coding
A Huffman coding encodes each unique distance with a different binary representation. Not all distances are represented with the same number of bits and the encoding is built in such a way that values which occur often use fewer bits than values which occur more rarely.
On its own, Huffman coding gave similar levels of compression as the LZW algorithm below.
Lempel-Ziv-Welch (LZW) compression
LZW is sort of, but not really, similar to RLE. It doesn't look for runs of identical distances but instead looks for sequences which it has seen before. When it finds one it inserts a reference to that sequence, essentially saying, "take that thing over there and put it over here as well."
Vector Distance Transform (VDT)
Once I thought to search for distance field specific compression algorithms, I found this paper describing VDT and it's the basis for the approach I decided to take so I'll describe it in a little more detail.
Rather than assigning a distance to each pixel, VDT assigns a vector to each pixel. The vector indicates which other (previously calculated) pixels, if any, can be used to calculate the distance for the current pixel. If we calculate pixels left-to-right and top-to-bottom then there are four possible vectors: the pixels directly above the current pixel, the pixels directly to the left of the current pixel, the pixels diagonally up and to the left of the current pixel, and the null vector indicating that the current distance can't be calculated based on previous pixels.
Since there are four possible vectors, each vector can be represented by two bits and the entire array of vectors takes up a total of 4096 bytes. Each null vector indicates a distance that we can't calculate and have to store directly, adding an additional 8 bits each, while every non-null vector is a distance that can be entirely eliminated from our data for a net savings of 6 bits each.
VDT on its own can reduce the size of an SDF fairly dramatically. But a nice feature of VDT is that, once the distance prediction step is taken, the vector data and remaining distance data can be further compressed using other methods. For instance, although RLE doesn't do so well with raw SDF data, it does a great job on the resulting vector data.
I tried two approaches and they gave very comparable results. Both start by doing the vector distance transformation.
The first approach then applied the RLE algorithm to the vector data and a Huffman coding to the distance data, finally combining the result into a single binary string.
The second approach starts by combining the vector and distance data into a single binary string and then running the LZW algorithm on that string to compress it further.
Below is a summary of the results I got via various methods. The VDT+LZW columns could just as well be VDT+RLE+Huffman since the results were very similar.
Lossless vs Lossy
I suspect that the palm tree SDF compresses so poorly because it contains a bunch of non-linear transformations: sines, cosines, exponentials, etc. which means the distance field isn't "well behaved" and, therefore, difficult to predict.
The VDT algorithm is lossless by default—it only removes a distance which can be predicted exactly—but is easily modified to be lossy. I wanted to see if I could get the palm tree SDF down to a more reasonable size without degrading the quality too badly. Spoiler alert: not really. It's easier to see when rendered as an image:
The first image is the lossless version as listed in the table above. The distortions in the second could be acceptable in some situations but still only gives a 74% compression ratio with a maximum squared error of 5. The last image, which looks like Thanos had a personal vendetta against trees, has a max squared error of 10 and still only compresses down to about 60% or a little under 10000 characters!
Compressing less to compress more
One particularly interesting discovery I made was that—even though the VDT+LZW combination gives the best compression on average—the best way to fit more SDFs per cart was to use VDT only. Why should that be the case? VDT by itself gives the worst compression of those listed. How is that better?
I figured this one out by accident when I copied the binary strings, except for the palm tree, into a cart, ran INFO and saw this:
The raw character count and the compressed character count are nearly the same. Which actually makes sense: I've compressed the data significantly so whatever algorithm PICO-8 is using to compress code isn't able to squeeze much more out of it. That particular screen shot is when using VDT+LZW but the same thing happens when using LZW only, Huffman coding only, and VDT+RLE+Huffman coding.
That got me thinking: PICO-8's compression is probably better than mine. So what if I only used VDT and let PICO-8 compress it the rest of the way for me? Here are the same seven SDFs with only VDT encoding.
It uses up a lot more of the raw character count but the compressed character count is much lower and there's still room to spare!
Edit: I forgot to actually post the compression/decompression code anywhere so here's a cart demonstrating it. The code is also on github
Hi everyone!
I got pico-8 yesterday and I am trying to learn lua.
for my first project I am trying to mod the raycasting demo to be a 3d platformer.
I got the running and jumping set to what I like, but I don't know how to set the map
so that it doesn't crash once it looks off the first screen in the editor. Any ideas?
I added a gif to show what it looks like. after the gif stops it means that my program crashes or
does not let me move, look, or jump in the game.
HI guys! this is a characters for Jujutsu Kaisen!
:)
hi! this is gojo satoru from
Jujutsu Kaisen!
this anime is popular right?
:)



  1 comment