Decker. I'd for some reason assumed it was some npm and/or wasm monstrosity, but it turns out it's nice zero-dependency Javascript in a single html file that you can save and run offline! And that's in addition to the native version that uses SDL just like LÖVE. So in some ways Decker has a better cross-platform story than LÖVE, which is non-trivial to run on iOS. The downside: on a web browser on Android it's even less efficient to run than LÖVE's native app.
Rust. I spent some time playing around with a LÖVE-inspired game engine called ggez, and the much more basic wgpu crate. The promise here: Rust seems to be evolving some pretty nice cross-platform tooling, so in time we may end up with a world where it's easy to cross-compile to any platform. Of course, the compile step is not ideal, but it promises to yield much more efficient binaries that might run on lower-end devices like old phones. The eco-system is not quite there, and the npm-like dependency explosions are rough. But I want to try to look outside my comfort zone. It's possible the way forward isn't unique-snowflake minority platforms like LÖVE or Decker, but just to use a majority platform with better taste, taking the time to understand and curate the landscape of dependencies.
Anyways, here's a little program I made to try to stretch Decker to more of the sort of procedural graphics I tend to gravitate towards on LÖVE:
This is dancing letters, a fixed piece of text except we're constantly switching the case of each letter at random.
Here's the code, to give you a flavor for what Decker's quite elegant mix of Lua and APL looks like:
local s: "abcdef" # put in whatever text you want
on view do
if ! 5%sys.frame
me.clear[]
local y:each c in s random["%u","%l"] format c end
local margin:15
me.text[y margin,margin,me.size-margin*2]
end
end
And here's that code along with the surrounding card (you need a canvas widget to be present just so) in a less readable form that you can copy and paste into a deck of your own:
%%CRD0{"c":{"name":"home","script":"on view do\n \nend","widgets":{"canvas":{"type":"canvas","size":[300,200],"pos":[48,51],"animated":1,"volatile":1,"script":"local s: \"Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can.\"\n\non view do\n if ! 5%sys.frame\n me.clear[]\n local y:each c in s random[\"%u\",\"%l\"] format c end\n local margin:15\n me.text[y (margin,margin,me.size-margin*2)]\n end\nend","border":1,"scale":1}}},"d":{}}
i'm doing a 15-day self-directed "art residency" in which my main goal is to draw rough drafts of comics i've been wanting to flesh out for a while. one of the main rules of this residency is that i don't go on instagram. i started doing 10-day breaks from it during july last year (when i was conveniently on vacation elsewhere and therefore easier to follow through new behaviour) and this is my first attempt at doing a half-month break. what has worked: if i'm on the app, i'm on the app. i look, like, comment, react, whatever. i get updated. i socialize as far as socializing there entails, so when it's time to plug out, i very much welcome the break. i've done it a few times that i feel like i've found the sweet spot that works for me.
it still takes a while to acclimate to the silence of those social media breaks, but even that process is enjoyable because then i start to think of my projects and actually take a stab at them. i also take the time to listen to new music as i do it to help stimulate the flow of thought. right now i really love doechii and cindy lee and revisiting joanna newsom. one added plus is that without social media, there suddenly seems to be a bit more time to think.
On holiday season I have cloud apps on my mind. Most people seem to find them a boring subject, but they're important tools nowadays, for sharing files with each other and between devices (short version: use CryptPad, it's the best right now).
I also wrote a story between Xmas and New Year, kind of a very short fanfic. It's my first in over a year, and it sucks, but still better than nothing. Didn't expect I would show it to anyone, but my friends actually thought it was fun! Go figure.
January lived in bullet points:
Like every year in recent times, 2025 debuted with a week of unseasonably warm, sunny weather; I got to wear my nice winter clothes.
Been thinking how to make the site better again; for starters, cleaning old cruft and trying out new web apps.
Speaking of which: thanks to a generous friend, web hosting is secured until autumn.
Now to see what happens next. Looks to me like a perfect storm is coming for the world, and pretty soon at that.
It has become something of a yearly ritual to take the first few days of the
year to write a new implementation of the compiler
I use daily. It serves to see how my programming style and solutions to these
now familiar problems might have evolved, it also ensures that the language
itself doesn't grow beyond what I am capable of implementing in at most a
week's time.
The most discernible difference in this new implementation, is that it leans
heavily on object-oriented patterns, by
favoring methods acting on private values, over pointer arithmetic by function
application. The stack is principally used as the communication channel between
objects, for example, a text object's buffer is only ever modified through its
explicitly defined capabilities, not by a function taking a text pointer. It
turns out it limits bugs, it is faster and even often smaller!
Dev & I have spent the last month visiting family. Much of the temperature this month was below zero, but we were well-dressed and drank lots and lots of tea. I cooked a ton. I made pies, tourtières, cookies, pizzas, breads, lasagnas, etc. Cooking for others is usually a stressful affair for me, but I do not experience this with family. I really love sharing meals with my parents, when I leave I will miss this.
MOVIES. We watched Alien: Romulus the other day. I am a big fan of the first Alien film (only that one). Alien: Covenant was so terrible, so full of gratuitous violence, that I was a bit concerned, I was not eager to have to sit through something like that again, but I remembered Lizbeth mentioning that it was very good, so we gave it a watch. It was excellent. I really loved David Jonsson's portrayal of a synthetic. The horror was well balanced, and the use of analog effects was so worth it — loved the facehugger animatronics(YouTube). I did not love that they revived Ian Holm for this film, the effect was not well done. I also watched Vampire Humaniste Cherche Suicidaire Consentant, a vampire film produced in Quebec about a teenage vampire who refuses to kill to eat, and so searches for someone who consents to die. I loved this film. Another notable film that I watched this month was Nope by Jordan Peele. I really loved it, it's a good cautionary tale, and to me was reminiscent of the book Le Péril Bleu by Maurice Renard.
MUSIC. I was introduced to Carousel From Hell by Lust$ickPuppy, it is excellent.
QUOTESImagination is more important than knowledge, for knowledge is limited, whereas imagination embraces the entire world, stimulating progress, giving birth to evolution.A quote by Albert Einstein
CALL TO ACTION. After being wrongly incarcerated for 5 months, Paul Watson, an activist, was released from prison in Greenland!
All of the Shin Devil Children fan fiction I had planned for 2024 is finished, leaving only Raindare's chapters (Grocery Run and Through the Circle) as remaining works in progress. She's still tied up by other fiction projects that she can't talk about right now. We're both quite proud of how this little exercise turned out.
Wrapping up 2024, we've got one final retrospective following up where the mid-year retro left off. These will be the last of the behind the scenes website meta articles. I think our work speaks for itself.
A new year is arriving! Help, where is it coming from! Why does this keep happening!! I hope u have a very nice start to 2025 and get some nice new shoes!
I've been trying to take it easy, but it has been difficult. I haven't been
able to consistently save a rest day between social events like I hoped.
So, I savour each little quiet inbetween moment I can find, whenever in transit or
waiting for guests to arrive, stealing a bit of time to read and relax.
How dearly I wish I had time to write more, and if I hadn't left our
camera aboard, take some pictures.
After a conversation with Jack Rusher and others about Emacs Nature [1, 2] and playing with Seymour by Alessandro Warth, I'm getting interested in building..
An environment for visualizing programs
(Not to be confused with visual programs, or visualization more generally.)
Start with a tiling window manager for managing named graphical canvas "buffers", using Emacs operations like split and resize.
Each buffer exposes a coordinate space of its choosing, listens for messages and positions objects in the space in response to messages.
Buffers can send messages to other buffers.
Examples of coordinate spaces:
Graphical game engines use the obvious 2D/3D cartesian systems. You position stuff using (x, y) or (x, y, z). You could also imagine polar or other coordinate systems that are studied in geometry.
The HTML DOM is a space where positions can be specified using CSS selectors or XSLT.
You can imagine a text editor operating in a coordinate space as well. Emacs seems to use a 1D coordinate, just character count from start of buffer. My stuff so far uses 2D: (line index, UTF-8 codepoint index within line)
Some examples of messages, to show the sorts of use cases this framework might unlock:
In a text editor, the cursor tracks a position, and keyboard and mouse send messages to move the cursor or insert objects (characters or longer text) at the cursor.
You can imagine print statements as a message from the "code" coordinate space to a different, 0-D (append-only so there's no notion of coordinate) space.
Terminal buffers in Emacs take the mostly 0D space of a terminal and augment it with a cursor. When you scroll up to an earlier command and hit a hotkey, the buffer sends a message to itself with the text around the cursor. The message is received at the bottom of the buffer.
Emacs Slime and other IDEs support keyboard shortcuts to send text from the current buffer to a REPL in some other buffer.
Ronin and Sketch-n-Sketch support bidirectional messages between two spaces with very different coordinate systems.
Live programming systems often show the results of a statement to its right. Examples: alv by S-ol Bekic, Bret Victor (of course), Seymour as above. These too can be seen as a reflexive message from a space to itself. In addition, the message contains an implicit coordinate: the current line.
Glamorous Toolkit, Lisp Machines and other Smalltalk systems do a lot of stuff like this. I think all of this can be cast in terms of buffers, coordinate spaces and messages, though you can imagine them as a single, very complex coordinate space like the HTML DOM, or many simple spaces with different possible coordinate systems. For example, in any of them you can create a new "log" space that you can append graphical objects to. Maybe even self-contained interactive graphical widgets.
The major question for me now is: how do you configure a buffer? You need some concise way to specify the space (perhaps just by naming from a small menu of options), handlers that listen for messages (e.g. keypress or mousepress), handlers for sending messages (e.g. widgets on the space that perform tasks when you interact with them), and generic handlers for sending messages to other buffers (e.g. print; here I'm imagining it to send a message from some arbitrary process, through say a socket, back into the environment, with enough information to route it to the appropriate buffer accompanied by a reasonable coordinate)