a week-long jam around the new creative coding library L5
L5 (https://l5lua.org/) is a new creative coding library for making art with code. It is based on Processing (and p5.js) and implemented in Lua. L5 is designed to be lightweight and to run on older computers and low-powered machines. It is a response to principles of permacomputing, which includes resisting planned obsolescence and wasteful practices of Big Tech.
My goal for this jam is to combine three of the suggested themes: slime molds, electroluminescent screens, and imaginary computing. The idea is to design a hh:mm watch face (maybe in the style of a 7-segment display) in which the numerals are lit up by the dynamics of slime mold growth. As the minutes change, we might discontinuously change the external forcing (aka external stimuli/food source) to get the mold to reconfigure itself into the shape of the next timestamp. I have no idea if this will work (that is: if there are parameters we can choose in a slime mold simulation that will actually yield somewhat recognizable watch-face-digits), but either way I'll learn a bit about lua, l5/processing, and slime molds.
We'll be following Jeff Jones' paper (there's a beautiful demonstration and exposition here).
Journal follows.
Decided to participate in the evening of the first day. I had incidentally started experimenting with Processing just earlier this week, so I figured it'd be a good continuation of that. The slime mold theme reminded me of Merlin Sheldrake's book on fungi, Entangled Life, which I read a few months ago (and remembered enough from to know that slime molds are not fungi!). I think that's where I first read about the maze-solving and path-optimizing capabilities of slime molds, as well as new unconventional approaches to computing through fungi.
Here's a gif of what the simulation looks like so far:
One problem I ran into is that rendering each particle individually via
calls to L5's point(x, y) seemed pretty slow, which makes sense. For
now I'm bypassing L5 a bit by using Love2d's
ImageData as a buffer, and
doing the rendering (via Image:replacePixels) in one pass, which seems
to be faster.
The simulation algorithm is described nicely in both the original paper and in Sage Jenson's schematic diagram here, so I won't go into details (I'll have the code up somewhere at some point). The implementation was actually surprisingly straightforward; I didn't have to do much debugging at all. To be clear: I have no idea if I've implemented Jones' algorithm correctly. The results look reasonable, though, so that's good enough for now. There were a few minor annoyances coming from being new to Lua, though:
continue statement, so I wrote the particle
sensing decisions as a slightly awkward (in my view, at least)
if-spaghettilocal keyword) has tripped me up a few times> listening to: Amusing Ourselves To Death - See How
Didn't have much time today, but managed to change the coordinate
system over to periodic boundary conditions (effectively a torus). The
nice thing about wrapping around like this is that you can delete all
the is_in_bounds checks and instead just work directly with
expressions like x % width. The modulus operator works as you would
want it to with negative numbers, which is convenient... though Lua's
one-indexing kinda gets in the way here again by making us have to
conjugate by a shift-by-one operation beforehand. The behavior of the
slime mold under periodic boundary conditions changes to roughly what
you would expect: there are no corner/edge artifacts, and the dynamics
are continuous across boundaries.
Currently I seem to be getting around 15fps when working with around 5000 particles on my m1 macbook air. Jones in his paper studies I probably can't expect crazy performance trying to run a particle simulation on the cpu, but I'd love to optimize this at least a bit.
I think the diffusion/decay step of the simulation is probably pretty
heavy. Currently this consists of looping through every pixel of and
diffusing the trail of stimulant left by the mold (the external stimuli
are not modified) by taking an average of the values in the 3x3-square
of tiles centered at the selected tile. Every step of the simulation,
then, the diffusion consists of roughly 9n^2 additions and n^2
divisions.
I did a quick search to see if there's any cleverer approaches to this mean-filtering. I found this paper, which thankfully seems pretty elementary. The idea is to reduce the number of additions and divisions whereever possible. I've never really done much performance-critical coding, so it feels kinda funny to me, but I'll probably try it out tomorrow.
Oh, I also started this devlog website. By the way, I took some color ideas from this vs code theme for the simulation [ed: and the original devlog website].
> listening to: MINIMIS - SSDD
Finished writing logs for the previous days and got this website up on squeak [ed: now here]. Now for the hard part... working on optimizing the diffusion algorithm.
After spending an embarrassing amount of time rewriting the diffusion algorithm to be slightly less naive, I'm able to stay at a solid 30fps up to ~8000 particles. For the 200x200 window I'm working with here, this is probably overkill -- Jones suggests experimenting with particle number between 3% and 15% of the total number of pixels, which comes out to between 1200 and 6000 particles in our case.
One interesting thing to note is that -- with the parameters we've chosen here -- the mold tends to form semi-stable 4-, 5-, or 6-gons. The video below is a typical example (with no external stimuli):
The optimization of the diffusion code is pretty straightforward. Instead of recomputing the sum of all the neighbors of a given pixel (including itself) in order to compute the mean, we pre-compute and store, at the start of every new row, the sum of the length-3 columns along that row. This cuts down the number of redundant additions significantly.
I got the idea from this paper I mentioned
above. In retrospect, the optimization is obvious, but I wouldn't have
thought this would make such a noticeable difference. I implemented a
few of the optimizations mentioned there, including the one which avoids
divisions entirely. The zero-division optimization should be the
fastest, according to their results, but I didn't see much of an
improvement over the version I implemented (add_red2):
mean(s) stdev(s)
baseline: 0.043 0.001
add_red1: 0.025 0
add_red2: 0.015 0
zero_div: 0.015 0
I've also added a bit of functionality to add blobs of external stimuli via mouse (they are visible in white, but pressing a key toggles display of external stimuli) to help me get a sense of how they might affect the overall shape of the mold. The goal would be to use external stimuli to shape the mold into visibly digit-like forms comprising a digital watch face. After playing with this for a while, though, I'm not so sure if this is possible without setting specific dead-zones...
> listening to: Find - Synaptyx
Busy, only wrote two little bits of code today:
I think the two of these, together with food (aka external stimuli sources) might allow for drawing little wobbly slimy digits. I don't think the solution will be pretty or elegant, unfortunately, but now that I actually have some visual intuition about the dynamics, I'm not sure I can expect the particles to form nice digits just using external stimuli. Anyway, I'll update with details and pictures tomorrow, it's getting late.
Busy, exhausted, no code today. Worried my original goal may have been too ambitious.
> listening to: Callisto - Sl8r
Instead of establishing dead zones (pixels into which movement is disallowed), we can achieve something similar by using negative external stimuli values. It's not quite the same, as we still see filaments extending through the perimeter depending on the initial conditions. Maybe we can experiment with setting up pre-arranged stimuli (both positive and negative) for each digit, and discontinuously iterate through them as the clock ticks.
I've manually implemented different little rectangles of negative stimuli for each digit 0-9. Et voila, two screenshots two minutes apart:

It's ugly as hell for now, but maybe I'll have time before the end of the jam to clean it up. It qualifies as a working proof of concept, I think. I don't think I want to do too much more, but here's a tentative to-do list for myself:
> listening to: data.matrix - Ryoji Ikeda
Added a mode-selector to switch between the full simulator and the clock. I haven't bothered tweaking things to make the clock look better... maybe when I find the energy later.
I think it's time to submit! This is my first ever submission to a jam of any variety so I'm feeling pretty proud!
The code can be found in the project page
here (download and unzip the .love
file).
> listening to: Live at Sydney Opera House - Underworld
Check out Lee's notes on the L5 cyber cafe he set up at community processing day nyc 2026! Loved the idea and loved the 'ole permacomputers! Don't forget to check out some of the other submissions!
Huge shoutout to the amazing people who organized and volunteered to make the event possible and to all the super cool workshops and super welcoming people!
last updated: 2026年10月14日