Log In  
[back to top]


This cart is a barebones Forth implementation in 279 tokens. It could be smaller, it could be more usable, but I haven't really touched it in weeks, so here you go. Probably full of bugs.

Features

  • eval() function
  • Interpret and compile modes - extend syntax in Forth!
  • if/then (implemented in Forth)
  • A few useful comments, including some commented-out utility functions and basic smoke test.

Non-features / shortcomings

  • else (you can add this in Forth)
  • Arithmetic (you can add this for 11 tokens per binop, or 9 tokens if you're willing to use valid Lua identifiers as operator names)
  • Looping (you can probably add this for the cost of a few arithmetic/comparison operators, then add the syntax in Forth for no token cost)
  • Passing args or returning values when calling Lua functions from Forth (depending on how fancy you want to get, probably takes 20-50 tokens for a reasonable wrapper)
  • [ and ] are spelled _lb and _rb for some reason.

[ Continue Reading.. ]

5
0 comments



Cart #raccoon_ball-1 | 2023-06-04 | Code ▽ | Embed ▽ | No License
30

Does what it says on the box.

(updated to fix a major oversight: now it bounces)

Photo by Toan Chu

30
18 comments



Copy/paste is super cumbersome when using web exports on Mac. It appears that to reliably copy, I have to press ctrl-C and then cmd-C after text is written to the clipboard, and to get pastes to work I have to press cmd-V and then ctrl-V for PICO-8 to pick up the paste.

Is there a better way to do this? If not, can Mac exports be updated to only need cmd-C and cmd-V? I'd love to cut down the instructions on Tiny Drops...

It looks like this also may be affecting folks using the EDU edition: https://www.lexaloffle.com/bbs/?tid=51921

4
2 comments



Bounce tiny drops that fall from the sky to make music! This began as a 500-character cart for TweetTweetJam 8. Or check this cart out on Itch!

Cart #tiny_drops-3 | 2023-05-22 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
15

The latest version adds many more editing features, as well as save/load and audio export.

Controls

  • Click and drag the mouse to draw lines, or to move line endpoints.
  • Z/X deletes a line. If your mouse is over a line endpoint, it'll delete that line, otherwise it'll delete the newest line.
  • Left/right changes line sounds. If your mouse is over a line endpoint, it'll change that line's sound, otherwise it'll change the sound for new lines.

[ Continue Reading.. ]

15
0 comments



Cart #boundary_peaks_tweetcart-0 | 2023-05-10 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
9

Just a small tweetcart.

9
0 comments



The following code block prints only the number 4, though I would expect it to print 2, 3, and 4.

do
 if (false) if (true) print(1)
 print(2)
 print(3)
end
print(4)

Only the outer if has this property, the inner if's scoping is fine. Similar behavior happens without the do block, I just included it to demonstrate the interaction of this behavior with "normal" Lua scopes.

3
2 comments



Here's yet another piece of simple data compression code:

Cart #simple_lz-0 | 2023-04-09 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

I wrote this for a (hopefully) upcoming player cart for RP-8 songs, in order to be able to pack as much RP-8 song data as possible into the spritesheet/map/sfx/music area of the cart. The compression technique is basically LZSS, with a couple of small changes / enhancements:

  • The code supports strings longer than 32kB - it will break them into 32kB blocks for compression and reassemble those blocks after decompression.
  • Literals are move-to-front encoded.
  • Match offsets, match lengths, and MTF literals are encoded using Elias gamma coding. The lowest N bits (N is a separately tunable parameter for offsets and literals, N is fixed to 0 for lengths) are encoded as usual, the remaining high-order bits are Elias gamma encoded.

[ Continue Reading.. ]

4
1 comment



This code uses 11% CPU according to Pico-8, but if I delete the v[0]=1 lines in the if false block it uses 7% CPU:

v={}
::_::
if false then
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
 v[0]=1
end
for i=0,1023 do
 v[0]=5
 v[0]=5
 v[0]=5
 v[0]=5
end
flip()
goto _

Other observations:

  • If I put the v[0]=1 lines in a for loop with a huge iteration count this code uses 7% CPU. (No bug.)
  • If I put this code into _update() or _draw() it uses 7% CPU. (No bug.)
  • Adding / removing v[0]=5 lines bumps CPU by roughly 3% per line.
  • Replacing v[0] with v[1] makes no difference.
  • Pico-8 does act on this CPU info, the contents of the if false block will affect whether Pico-8 visibly stutters if I add draw code and the non-executing lines push CPU over 100%.

[ Continue Reading.. ]

7
6 comments



I've already posted this on the Discord and a couple other places, but, well, why not post it here too? Randomly generated snowflakes for the season.

Cart #snowflake_generator_3d-0 | 2022-12-24 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
12

12
5 comments



This behavior feels possibly intentional, but I thought I'd check here just in case. If you run RP-8 with load #rp8, on loading carts, RP-8 gives the message unknown extcmd: set_title. If you ask it to open its folder with extcmd("folder"), it fails with a similar message. Both commands work fine if I save the cart to a .p8 and immediately re-load it. This is on 0.2.5c.

It'd be nice if folks could use load #rp8 to run RP-8 - even if this functionality doesn't end up enabled from Splore, perhaps it could work when loading carts by ID from the CLI? Also, is there some way to work around this and avoid showing the error message if the extcmd call isn't going to work?

At this point I'm wondering if I'll need to just point to Itch as the canonical download source for folks to get reliable results. That wouldn't be the end of the world, but offering a load #rp8 alternative would sure be nice!

3
0 comments



I've been working on a song in RP-8, and I've recently modified RP-8 to not just write song files to the clipboard, but also to timestamped save files on the desktop. After a long session of working on the song, I tried to save, and got a message about there being too many printh files.

I wouldn't have lost too much work - the whole reason I have this many files is that I've been checkpointing frequently - and I was able to get the data out of the clipboard, but it was still frustrating. This was a very long session, Pico-8 had probably been open for 12 hours or more while I'd been working off and on. Creating so many save files would certainly be a problem if Pico-8 had only been open for a few minutes, but over 12 hours I feel like it's not unreasonable?

I'd love for Pico-8 to reset its number of files / amount of data limits after some period of time, even an hour or two would be fine for my purposes.

I'd imagine this isn't super high prio, but it would be very nice. As I get closer to releasing RP-8 I'm starting to think more about awkward situations and edge cases I'll have to explain in the docs, and this would certainly be one of them. The really awkward thing about this one is that it undermines trust (since the user feels like they're losing work), and it's somewhat difficult to get around in a nice-feeling way...

[ Continue Reading.. ]

3
0 comments



As usual with PCM audio, be careful of your volume, and if this doesn't play back well in your browser, try it in desktop Pico-8. Earlier versions had filter instability problems that could result in loud sounds showing up out of nowhere - I think these are fixed now (I've let this play for over an hour with no problems) but I can't 100% promise it won't happen again.

Cart #acid_jam_512-3 | 2022-06-22 | Code ▽ | Embed ▽ | No License
20

An entry to the Pico-8 512-Char Jam. Kick, hat, acid.

Jam entry
Itch page

Update 1: Moved the delay time slightly off the beat. Also saved a few characters thanks to @SmellyFishstiks, which let me thicken the oscilloscope line.

[ Continue Reading.. ]

20
12 comments



Based on a request for help in the Pico-8 Discord, I ended up working on a rope/string/ribbon/chain/etc. simulation:

Cart #rope_sim_demo-0 | 2022-05-30 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

The behavior of the rope changes substantially depending on the gravity and drag settings.

This sim tries to model the object as inelastically as possible, although it's far from perfect in that regard. The rope here has 128 segments, which is very difficult to handle without (a) instability, (b) excess springiness in the rope, or (c) tons of damping. So i ended up having to write a slightly clever constraint solver (multigrid for n log n instead of n^2 performance), and I chose a step schedule that uses almost 100% CPU at 60fps. But if you use fewer segments and tune the solver differently, going down to 16 segments or so and using a less conservative step schedule, like one suggested in the cart comments, you can get the CPU usage closer to 5% at 60fps. That might be more suitable for inclusion in a game.

[ Continue Reading.. ]

6
0 comments



I was thinking about what's keeping Pico-8 from being a popular platform for scientific computing and high-end DSP ... and I realized: I can't think of a single FFT library for Pico-8! That must be the reason. So I wrote one:

Cart #pfft-2 | 2024-05-27 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
6

There are some comments at the top of the cart code on usage, if you want to copy/paste this into a project of your own for some reason. It's not too slow: you can do about 400 length-256 real FFTs per second, which is enough to get up to some audio shenanigans. (See next cart.) You can use the left/right arrow keys to switch modes between DFT, complex FFT, real FFT, and DCT in this demo, but be aware that if you happen to switch to DFT mode - it is sloooooooow and you may have to hold a button down for a while to get out of it. (DCT is also slow but ~3x faster than DFT.)

[ Continue Reading.. ]

6
9 comments



One of the things that's been driving me nuts while working on RP-8 has been how unstable the PCM audio output has felt. I can check (via logs or asserts) that, at 60fps, stat(108) is always above 256 and stat(1) never exceeds 0.9, and I'll still get occasional crackles or small time skips in the output. If I record the audio out with extcmd('audio_rec') these issues generally appear there as well - most often as small intervals of 0 samples. The one or two dropout cases I've been able to inspect in Audacity made it look like the dropout was in the low 10s of milliseconds range. I have not yet been able to track down a skip on the Audacity waveform display.

I've been trying to chase down the bugs in my code, but today I instead tried RP-8 - specifically the current BBS version, #rp8-2 - on two machines that aren't my normal development machine. It was rock solid. Flawless. (Or, well, nearly flawless, just heard a dropout on the Intel Mac after leaving it running for 15 minutes, but the ARM Mac shows problems much earlier and more frequently than that.) My main development machine is an ARM Mac, and the two other machines I tried today were a Windows box and an Intel Mac. The only conclusion I can draw right now is that there's something wonky about Pico-8's PCM audio out on ARM Macs that causes it to skip and/or drop frames.

[ Continue Reading.. ]

0 comments



Hello! I thought I'd try to (slightly) clean up and post some utility functions I've found useful while working on RP-8. Maybe they'll be useful to others, maybe not. Let's see!

Cart #rp8utils-0 | 2022-04-16 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1

There are three possibly-useful functions here, plus their support code. Note that in the name of token conservation, all of these functions have essentially no error checking and can blow up in various exciting ways if you feed them bad data (or if they have bugs). The code also isn't the cleanest - maybe I'll tidy it up eventually, but I don't think it's completely unreadable right now. Anyway, we've got:

  • stringify(), 114 tokens. This serializes structured data into a string - RP-8 uses this to save songs. Escapes binary. Both the string format and the binary escaping are completely nonstandard, but the string format at least looks vaguely similar to Lua literals.
  • parse(), 286 tokens (can be cut to 246 if you don't want eval). This takes a string and transforms it into structured data. RP-8 uses this to load songs, as well as to set up some of its internal data. Uses the same weird format and binary escaping as stringify(), although it also supports some variations and syntactical sugar. You can probably cut more tokens if you don't need to support large input strings or binary unescaping.
  • eval(), two versions - 428 tokens for interpreted, and 556 for "compiled", plus you need parse(). (Very loose use of the word "compile" here...) This evaluates a script in a vaguely LISP-formatted mini-language with Lua-ish behavior, and returns the result. RP-8 uses this to save tokens by encoding bulky logic that doesn't need to run fast, like UI init. This can help save tokens. Note that the token costs here are pretty squishy, since they depend on what builtins you want to define.

While this eval may help you save tokens, if you're really serious you should probably consider external build tools and bytecode. (For more on this, check out what @carlc27843 did with

[ Continue Reading.. ]

1
0 comments



v1.1.2 update: added loop jump hotkeys (v1.1.1) and fixed a crash bug.

RP-8 is a synthesizer and groovebox inspired by Propellerhead Software's classic soft synth, ReBirth RB-338. It has everything you need to make entire tracks: two paraphonic synthesizers, a drum machine, a pile of effects to process your sound, and an integrated song mode sequencer to pull everything together. The audio is lo-fi, 8 bits at 5.5kHz, giving the output a distinctively crunchy sound.

If you're nostalgic for the early era of soft synths, a fan of minimalist computing, an acid squelch connoisseur, or just someone who likes to discover new sounds: I made RP-8 for you.

You can find this cart, including native builds, at https://luchak.itch.io/rp8, or try it out below. Note that this cart works much better natively than on the web - see the Web section under Compatibility Notes below for more info.

Cart #rp8-23 | 2023-11-04 | Code ▽ | Embed ▽ | No License
72

[ Continue Reading.. ]

72
38 comments



(spoiler: turns out I was scribbling over memory I shouldn't have been ... including the RNG state)

I think I've discovered a strange issue with rnd() and mouse position:

Here, I'm just playing a snare hit over and over again. The snare is created by mixing a sine wave with noise, where the noise is generated by rnd(). (With separate envelopes applied to each component.) Notice that every time the mouse exits the top of the screen, the character of the sound changes, becoming more tonal.

I am virtually certain this is because rnd() is doing something strange. If I modify my audio chunk synthesis function (runs ~1x/frame, generating ~100 samples) to put srand(any_constant_value) at the beginning, I'll get the tonal effect every time. If I instead put this at the beginning:

seed=0
function audio_dochunk()
 srand(seed)
 seed+=1

... then I never get the tonal effect, which is the result I would expect. I have confirmed that this does not happen when the mouse exits the screen in any other direction.

[ Continue Reading.. ]

3
3 comments



This follows the classic Stable Fluids paper by Jos Stam. Use your mouse.

Cart #simple_smoke-13 | 2024-03-08 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
24

A few things that would make this better:

  • More optimization
  • Higher resolution (if possible)
  • monotonic cubic interpolation for advection (likely too expensive)
  • MAC grid (NOPE - saves a lot of time to backtrace all quantities from cell centers instead. A MAC grid would mitigate some of the boundary artifacts here, but it's just too slow.)
  • vorticity confinement (expensive, but probably the next most important thing)
  • better smoke vis - bilinear interpolation? (almost certainly too expensive)
  • higher resolution for smoke than for velocity?
  • other forces: gravity / heat / etc.

[ Continue Reading.. ]

24
15 comments



PB-0x

A demake of a software groovebox from decades past...

Pattern mode is nearly complete! There's a mixer section, pattern storage, and a few editing tools. Good thing, too, since I think I'm coming up at the limits of what the Pico-8 CPU can reliably handle.

WARNING: Be careful if you play this cart on the web! Audio playback performs poorly on some OS/browser combinations and you may get loud crackling or popping noises. Turn your volume down before playing for the first time. If you have browser trouble, try it in native Pico-8. Or in a forthcoming native app export that I'll probably put up somewhere!

Cart #pb0x-4 | 2022-01-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
18

Instructions

  • Arrow keys select buttons/knobs/etc.
  • Z/X change control values. (Z is down, X is up)

[ Continue Reading.. ]

18
11 comments





Top    Load More Posts ->