March 2, 2023


Hello! Just in time for 7DRL, Roguelike Browser Boilerplate is now open source.

The boilerplate is a JavaScript based game template that takes care of all the annoying stuff like splash screen, start screen, credits screen, instructions screen, settings screen, menus, pixel styled UI, win/lose condition screens, sound effects, animations, etc. so you can get on with making the actual game.

It's ROT.js based and includes example implementations for monster, inventory, level gen, etc. It works on mobile and desktop.

The license is MIT so you can do what you want basically, including using it in a commercial game.


Feb. 10, 2023

I predict Python will be the most used programming language among developers world wide by 2032. This post contains my reasoning.

First take a look at this chart.

Chart of most used programming langauges 2022 from Statista

(Chart source. In the chart Javascript is #1 with 65%, HTML/CSS is #2 with 55%, SQL is #3 with 49%, Python is #4 with 48%.)

It looks this way because of the web. The world has chosen web tech over everything else because it is fast and easy to make software that runs on the web. It is fast and easy to let other people run your software on the web. You don't need anybody's permission. The only developer dependency you really need is a web browser, and the web browser is a feature rich runtime environment that can be programmed to do a huge variety of user-facing multi-media things.

The reason why Python is fourth on that list is because it is the easiest thing to use for just about everything else. From data science to web backends to ops glue code and micro-controller snippets. If Python ran in the browser it would probably be the easiest thing to use there too. There have been several attempts to bring Python into the browser. PyScript, based on Pyodide, is the latest and the best so far.

I took it for a spin the other day. It is quite large (900k) and it is quite a bit slower to load than native JS. It does this annoying thing of hard-coding a loading spinner instead of letting the developer take care of that. Clearly though, this iteration of Python in the browser is now good enough for a large number of front end use cases. Here is my minimal hello world PyScript HTML file to get you started:

<!doctype html>
<html lang="en-us">
    <title>PyScript test</title>
    <meta charset="utf-8">
    <script defer src=""></script> 
      body { max-width: 800px; width: 100%; margin: 1em auto; font-size: 2em; }
      #pyscript_loading_splash { display: none; }
      py-script { display: none; }
    <div id="app">Loading...</div>
    from js import alert
    Element("app").write('PyScript was here!')
    # alert("hi")

If you have a Python heavy dev team and you're building some internal web tool that doesn't have to load instantly, it's a no-brainer. Even if you're building a larger public facing app, it's probably good enough. Lots of front end apps today are this heavy and load about as slowly anyway. I have no doubt the size and speed will improve over time.

I think a lot of people will start using Python in front end browser code soon. They like Python already, and now they can use it in the web browser. It will only take a large-ish minority of projects using Python to bump it up above JavaScript, since it is already so popular in other domains. I expect that will happen in the not too distract future.

I don't think JavaScript will go away. It is the most popular programming language in the world and the syntax is not that much less accessible than Python. I think both languages will remain popular, and hopefully many other languages too, but I do think Python will become the most popular language.

Here are my own browser dev preferences in case you are interested. I no longer write as much Python or JavaScript code as I use full-stack ClojureScript. I like JavaScript and I am grateful that Eich was there at the right time and place to create this amazing LISP in C's clothing. The web would not be the same without the swiss army knife network language that is JS. I enjoy Python too. It is a very accessible language and that is an important reason why it is so popular.

Note, I have used the word "easy" here on purpose. Simple is not always easy, and simple is probably more important than easy, but the world sure does love easy.

Jan. 30, 2023

My first app of the year is out, hooray! \o/ It's a simple app to sync pocket operator devices. It outputs a sync signal from your phone which you can plug into your pocket operator's left input to drive it using a 2.5mm male-to-male stereo audio cable. It works well with the p0k3t0 Sync Splitter.

You can get it for Android and iPhone:

PO Sync connected to a phone

This was a fun app to build. I made it because somebody left this review on one of my other apps on Google Play:

Using this for the PO sync feature. I like that most; everything else is okay... I think a great idea would be to make an app with just the PO sync feature and a tempo slider or wheel, plus an on/off

So I knew there was at least one person who wanted this app. It was simple to implement and I got to use my favourite programming languge, ClojureScript. I love it when people need software that I know I can put together quickly. You can get the source code here:

2023 is going to be the year of pocket operator apps for Dopeloop and I. I hope to make at least 4 new music apps. I'll post back here when I release them (and also to newsletter + Dopeloop subscribers).

Jan. 17, 2023

2022 was a fun year for side projects. My indie apps made $2500 USD. I also hacked on a lot of open source code, doodled a fair few drawings, and started a new sci-fi lo-fi beats music project. \o/

Here's a spreadsheet of income from different software I made:

Spreadsheet of 2022 indie project revenue

All of the revenue came from projects that I barely worked on. The "Git days (2022)" column shows the number of days for each project on which I made a git commit. On average this works out to something like "part time days of work". As you can see the vast majority of the income came from work I did in previous years. That's the very definition of "passive income"!

The mobile music apps continued to grow from last year despite no work.

Roguelike Browser Boilerplate steadily made one sale per month. I didn't touch the code or do any marketing.

Hosted Gitea gained a surprising number of customers this year. This is likely due to the articles I wrote at the start of the year which helped a lot with SEO. I have been putting some dev time into Hosted Gitea again recently. I owe it to the current customers to turn it into a product I am proud of. In 2023 I expect it will make double what it made this year. I donated the 2022 profits to the Gitea open source project and I hope to donate again next year.

Jsfxr Pro was the for-profit project that I put the most work into. I only just turned it live. Signups have been gradual but I have had good feedback so far. The TODO list is long and I am going to take a break while I figure out priorities and see how it grows organically in the coming months.

The most interesting/useful numbers from the spreadsheet are RPM and RPTD.

RPM = "Revenue Per Mille". It measures the revenue per thousand visitors. It's basically a measure of marketing leverage. How much is it worth to point 1000 people's eyeballs at the product page for each app? A high RPM means I don't have to do as much marketing because a small amount of marketing gets a relatively larger amount of revenue. Low RPM means a lot of work on the marketing side to get enough eyeballs to make it worth doing.

So high RPM means more coding and less marketing, which is what I want.

RPTD = "Revenue Per Total Days". It measures how much revenue the thing made this year, divided by the total number of days on which a git commit was made ever. So it shows how much bang-for-buck in terms of my own dev time I get from that particular thing each year. If something has a high RPTD it means I got more revenue for less work. Note that for most of these projects I did no work this year so they have a yearly revenue-per-git-day of infinity!

Looking at these numbers helps me plan for 2023 and keep the motivation up. In the past couple of weeks I made a lot of updates to Hosted Gitea. I've got it to a good place for 2023. I'll do some more work on it in a couple of months time once I see how those changes go.

Right now I'm focusing on new pocket operator apps. First I am building a new free pocket operator app for Android and iOS. I got the idea from a review somebody left where they asked for an app that simply creates a sync signal for pocket operators. So I am working on that and it's almost done.


Once PocketSync is done I'm going to work on some kind of synth or chiptune app. A simple little app you can use with your pocket operator to add synth lines and melodic texture. That app will be paid and open source. I'm hoping to have both of these apps out by the end of January.

Two other things I am doing in 2023. First I am drawing one doodle per day to keep the drawing muscle fit. Second I am open sourcing any new projects I start. I am going back to my old open-source-by-default way of working.

I'm looking forward to another fun year hacking on this stuff!

Dec. 30, 2022

Mastodon is a real breeze to develop for. I was able to use nbb (Clojure scripting on Node.js) to post an image using the API in a few minutes. Here's how.

Step 1: Create a new Mastodon app.

Go to Preferences -> Development -> New Application, or visit /settings/applications/new on your Mastodon server.


Step 2: Store the access token

Once that is done copy the "Access token" and your server's URL. Put them in an env file:

export MASTO_SERVER=...

Get these into your current environment (or use direnv etc.):

. ./env

Step 3: Set up nbb & libraries

echo {} > package.json
npm i nbb masto

Step 4: Create the code

In a file called post-image.cljs put the following code:

(ns post-image
    [promesa.core :as p]
    [applied-science.js-interop :as j]
    ["fs" :refer [readFileSync]]
    ["process" :refer [env]]
    ["masto" :refer [login]]))

(p/let [masto (login #js {:url (j/get env :MASTO_SERVER) :accessToken (j/get env :MASTO_ACCESS_TOK)})
        attachment (j/call-in masto [:v2 :mediaAttachments :create] #js {:file (readFileSync (last argv))
                                                                         :description "Test image"})
        status (j/call-in masto [:v1 :statuses :create] #js {:status "Hello this is a test!"
                                                             :visibility "public"
                                                             :mediaIds #js [(j/get attachment :id)]})]
  (js/console.log status))

Step 5: Test it.

npx nbb post-image.cljs some-image.png

Congratulations, you now have an nbb script which can post images to Mastodon. Enjoy!