I've created a cart minification & linting tool in python - Shrinko8:
https://github.com/thisismypassport/shrinko8
It can do aggressive minification to reduce the token count, the character count, and the compressed size of a cart, giving meaningfully better results than other known tools like p8tool or GEM.
(E.g. in one example, a 81,416 char cart went to 31,213 chars with shrinko8, 35,563 chars with p8tool (though p8tool didn't run on it without having to do some hacks), and 40,813 chars with GEM)
It can do linting, aka reporting of issues that may indicate bugs in your code, such as undefined, unused and duplicate local variables.
It supports all pico8 syntax and globals, including modern ones (as of the time of writing, but I do plan to update it when needed).
It also supports creating a p8.png file directly, and can actually compress carts a bit better than Pico-8 would.
Example use: (first creates p8, second creates p8.png)
python shrinko8.py path-to-input.p8 path-to-output.p8 --lint --count --minify python shrinko8.py path-to-input.p8 path-to-output.p8.png --lint --count --minify |
The github link above has details on how to use it. (A modern version of python is a requirement)
I've decided to share it since people were having trouble using p8tool on their modern carts.
Comments, issues, and contribution are welcome.
Thanks to pancelor for initial bug reports & the new name.


Hi @thissismypassword:
I could sure use something like this for some of the more complex programs like the dialog window I made recently. Yep I manually compressed that myself. Took some time.
From the link you listed is there a way to download everything listed there you have - perhaps as a ZIP file - without downloading each file manually ?


OK, first off, big props on the fine work you did here, @thisismypassword, now that I could download it, thanks ! Definite gold star work here. Interesting idea to use lowercase letters as variable names. I'll have to remember that.
Yet - I am a little disappointed.
I thought it would take large commands such as circfill and optionally turn them into _ci or something, as I did with my code. Is there a way to do this automatically in your PY process ?
_ci=circfill cls() _ci(64,64,32) |


@dw817 - thanks, doing this fully automatically is too much for now (especially as it also increases the token count, so it's a trade-off), but I did add a --no-preserve option which, together with --[[preserve]], allows you to do this semi-automatically.
(You have to decide on the globals you wish to rename and add the "renames" yourself, but you can then keep using the globals by their real names and the minifier will determine the best name for them as usual).
See the new "Renaming Pico-8 Built-in functions" section in the readme for exact instructions.


Update: I've added the ability to output p8.png files (previously I kept this ability disabled since my compression code used to be worse than Pico-8's, but now that I improved it to be a bit better than Pico-8's - I've enabled this)


Glad to have a newer tool to point people to! I haven't formally given up on p8tool but I have partial PXA support that isn't working and I got kind of demoralized to fix it, so it stalled and has fallen behind. Maybe I can crib off of yours and unblock it. 😅 Nicely done!


One more update - I've added the ability to specify a custom python script to run before/after the processing, which can be useful to merge in custom data to the cart, etc.
More details (and example of use) in the README in github.
EDIT: And one more - I've added automatic removal of most unneeded parentheses, which decreases token count as part of the minification as well. (This is useful because memorizing the entire operator precedence table is hard and removing all unneeded parentheses results in hard-to-understand code)


I've finally got RP-8 fully migrated over to shrinko8, and the results have been amazing. p8tool, when I was using it, took off about 2k bytes, which was fantastic and unblocked my forward progress at the time. shrinko8 manages to take off another 2k or so bytes on top of that, dropping RP-8's compressed size from ~16.6k to ~12.4k.
Of the additional 2k I got from shrinko8, about half was just from better minification, the other half was from taking advantage of shrinko8's extension options to minify global names and table keys across both Lua code and parsed string data / embedded scripts. (This allowed me to exempt many fewer names from minification.)
If you need to squeeze out every byte you can, and especially if you've already been aggressive about moving structured data into strings to reduce token count, you should definitely check this project out.
edit: The linter is also great. It even found a missing local
that was eating about 0.5% of the CPU budget!


It's been 4-months since I commented on this marvelous tool. If you are having difficulty in downloading and installing it, I've put some information HERE to help:


[11-14-22]
OK, suggestion for future Shrinko-8. Convert this:
if orange==25 then cats=17 dogs=34 end |
to THIS:
if(a==25)b=17c=34 |
Currently I am getting this:
if e==25then n=17i=34end |
The easiest way to determine this is to ensure there are no additional IF
statements found within the block of code that is to be Shrinko-ed and definitely no incomplete IF
that requires ELSE, ELSEIF, or END on an additional line outside.
I won't be creating a new post each time. If I have further suggestions for Shrinko8, I will post them in this message.
Thanks for your attention to this !


@thisismypassword Thanks for this great tool. Do you have an Itch or Patreon or some other way the community can support your hard work?
[Please log in to post a comment]