So I decided to build a bot in Mastodon that reports the damage you’re taking hourly. 
 
 This was a fun exercise and mostly an excuse to play with Rust. I’ll talk about the process a bit: the core, setting up the scripts to execute it, and then a Docker wrapper.
I’ve been thinking as of late about the things that desktop computer users get
that we’ve decided isn’t worth giving software engineers in their own
infrastructure. 
 I don’t think I’ve ever met anyone who works at a big tech company who is
 happy with the status quo. The closest we get is less sad. And a lot of the
pain points are fixable, but…
Related to my previous post , I needed to resolve the need to quickly take screenshots from Windows and put them in an org file in emacs. This proved a bit more difficult than I’d hoped; triggering a screenshot in Windows from emacs is non-obvious, and my attempts to use yank-media suggested that screenshots didn’t end up on the clipboard in a way emacs could see them. Other options I…
Lately, I’ve been using Etherpad on Sandstorm to track notes and clues in the game Blue Prince . While it started okay, I cannot recommend it at this time for this application. What follows is the specific issues that I’ve encountered. 
 Note that this may not mean it’s not fit for any purpose, or that these things cannot be fixed (I haven’t figured out how to fix…
In part 1 , we discussed setting up Grafana, Loki, and Alloy. Here, we’ll dive into Prometheus setup. 
 Prometheus differs from Loki in that Loki stores individual log entries. Prometheus is a time-series database: it stores individual events (each of which can be tagged with specific labels) and it is specialized for running analysis, bucketing, and summaries on events. 
 
…
Having gotten to three whole nodes in my home network, I’ve decided it’s about time to get some centralized monitoring going. To that end, I’ve gone with what I’m (vaguely) familiar with: the Grafana open source logs display and its accompanying pieces. Here, I’ll lay out approximately how I got working home monitoring set up after a couple missteps. 
 Part 1 will…

 In my quest to back slowly towards the exits from total reliance on Google’s infrastructure, I’ve managed to stand up an instance of Sandstorm on a small ZimaBoard. This has been successful; one thing I was very concerned about was storage reliability because I know if I’m rotating away from someone else’s Cloud, it’s up to me whether I lose data if these drives…
I’ve used multi-term for years in emacs as my primary terminal interface. It works great, but occasionally while ssh’ing to another machine and using the emacsclient -t interface (my common approach), the terminal gets stuck to a too-small size. This happens most commonly when my ssh session crashes and I have to start a new one. 
 It turns out the cause of this is that the…

 After not too much work, I was able to finish up the fireplace in our front room. This was a small hack involving a Raspberry Pi. I’ll summarize what worked and then share a few thoughts on what didn’t. 
 What worked 
 Here’s the quick summary: 
 
 Formatted a new Raspberry Pi 4B with a fresh OS install. 
 In the Raspberry Pi settings, set boot to…

 This is a followup to my previous post on building a shader based on Xflame. I won’t be covering much of the details of building it since they’ll be similar. 
 You can see the shader in action here . Feel free to pop it open and inspect the code as we go. 
 There are two primary pieces worth talking about in this one: the noise source and the Fractal Brownian Motion…
Over the holiday, we had the fun idea to put a TV in front of the fireplace we never turn on so we can run fireplace images on it. 
 
 Really ties the room together. 
 
 

 It’s been a joy, but it got me thinking about what it would take to put a fire visualizer on there instead of videos of fireplaces. To that end, I’ve dusted off my old knowledge of GLSL and…
It’s the New Years season again, and that means resolutions. Usually. This time around, I’m trying something a little new. Inspired by CGP Grey’s video on the topic , I’m trying “theme system journaling.” But since I’m not very good at keeping physical journals, I’ve recapitulated the system in emacs using org-mode, yasnippet , and some additional…
On rare occasions, I end up needing to plug a second monitor into my
laptop. This is a problem
 I solved in the past 
with a GUI, but it turns out there’s also a pretty easy-to-use command-line tool for this purpose: xrandr . 
 To use, first run it by itself 
 xrandr
 This will list your current monitor configuration, which will look something like this: 
 Screen…
While I’m pretty happy with my recipe system , I recently learned about
 org-babel , which is now
integreated into the core of org-mode. It turns out this does almost exactly
what I want; it’s designed to allow embedding and running code snippets inside
an org document in multiple languages. With just a few tweaks, I adapted my
previous approach to use org-babel.…
A common pattern while working on computer projects is running through a
sequence of “semi-automatic” operations, where you can’t quite automate all
the steps fully, but the formula is basically the same every time. I call these
workflows “recipes,” and they have these shared properties: 
 
 There’s a set of steps that’s almost always…

 The flash card viewer 
 
 

 I’ve created a simple
 flash card viewer as a study
aid. It currently defaults to flash cards for the FIRST Robotics Competition
2024 game manual, but you can load your own into it by clicking the “Cards” dropdown
and pasting text like the following into the box: 
 Card front 1

Card back…
In a previous post , I talked about things I really enjoy about Mastodon. This time around,
I’ll go over some challenges I see for the tool as a platform, product, and
ecosystem. Before reading too much into these, note that it’s possible not all
of these need to be fixed! Some can be interpreted as an improvement over the
status quo of Twitter / Reddit / Facebook…
I’ve been maintaining my own Mastodon node for
a few months now, enough to feel pretty moved-in, all things considered. To
nobody’s surprise, I’m really enjoying it! 
 I’m going to do a back-to-back pair of posts about the pros and cons I’m seeing
in the ecosystem right now. Leading off with my favorite things. This is the
stuff that completely…
Recently after making some changes to my Mastodon server, I began suffering a
host of 502 and 500 errors. The root cause turned out to be something
unexpected, so I thought I’d document my debugging process to explain how I
tracked it down. This post will also serve as, I hope, an answer to someone
wrestling with their own server if they have the same problem. 
 Spoiler:…

 “We keep that name moving in the Overhead,” he said, and it seemed to Princess that the wind in the shutter arrays above her blew more forlornly, and the everlasting clicking of the shutters grew more urgent. “He’d never have wanted to go home. He was a real linesman. His name is in the code, in the wind, in the rigging, and the shutters. Haven’t you ever heard the saying ‘Man’s not dead…

 Out-of-the-box, Mastodon supports post translation using an external service. But to take advantage of
it, you have to set up the services and bind your Mastodon instance to them. 
 It turns out this is a relatively simple process with only a few sharp edges. I’ve documented my
walk to a working configuration here. This process was supported by the Mastodon documentation…
Having put all the pieces in place, we’re now ready to modify the UI to display
the attached note next to the user’s name. We’ll have to do a bit of plumbing to
account for our own sins (denormalizing the field into the post means we’ll need to
re-normalize it into accounts on the client-side). But then it’s just a few short
tweaks to the React…
This post is part 2 of a 3-part series on adding the ability to show notes about
users on Mastodon next to their display names. Here, I talk a bit about setting
up a dev environment to make changes to the Mastodon UI. 
 Parts of this series: 
 
 Part 1: Adding a field to the Mastodon API 
 Part 2: Setting up the UI dev environment 
 Part 3: Surfacing a new field in the…
When I was younger, I expected everyone in the future would have computer
handles we’d mostly go by, and names would be secondary. I gleefully memorized
hundreds of online handles for all the folks I knew in school and online. 
 
 Also, we’d all dress like this. 
 
 

 It turned out, that didn’t exactly happen. People still keep their…
Now that my Mastodon server is
 making regular backups , I
want to preserve some of the backups on the off chance something goes
desparately wrong with my configuration and I have to do a very large rollback. 
 It turns out, while cron is maybe not the friendliest tool around, it makes
this task very easy. What I want to do is a three-tier backup: daily, weekly,
monthly. I…
My Mastodon server has reached the point where it’s complex enough that backing
up would be prudent. I was a litle surprised to discover that a script to do
this for me is not provided in the default project. The project does have
 a comprehensive overview of the
steps to backup, so I set about making my own backup script. In the process, I
also discovered a need for way…

 I recently set up a Mastodon node on a Raspberry Pi 4 in my home. By and large,
the process went smoothly, but I hit a couple of corner cases I wanted to
document (both for myself and anyone else following this path in the future). 
 For the most part, I followed the
 admin setup guide provided by the
Mastodon team. I had to deviate from it in terms of three pieces:
About four years and one detour through some self-teaching in control system
theory later, I have returned to Donald Knuth’s famous tome, The Art of Computer
Programming (volume 1). My previous attempt to read it was extremely
discouraging as I stumbled on the first part of the first chapter. Taking a
second read through, it made sense this time. When I first got stuck, I…
React is a clever user interface library designed around a
very functional paradigm, where the input is some state (represented as
properties) and the output is a tree of renderable user interface components (represented as, usually, something that can be translated to another UI representation, such as an HTML element tree). 
 That’s all well and good, but what if the render…
I bundled up the things I learned about driving a Brilliant Labs Monocle into a
new Python package . While doing the fine-tuning, I learned a bit more about driving the MicroPython UART interface. 
 Worth noting: I only discovered it after I completed this project, but another
good example of using Python to drive Monocle actually comes from the
 Monocle’s creators . 
…

 I recently got my hands on a
 Brilliant Labs Monocle , which is a nifty
little tiny-screen device that connects to a host machine via Bluetooth
Low-Energy protocol and offers a simple API for controlling its content and
receiving input. The documentation is a little thin-on-the-ground on how to
interface it to a host, but after a little bit of hacking on it I pieced…
Recently, while working on the
 WPILib codebase , I found that my
poor Linux laptop was not upgraded enough to do the heavy-lifting, as the
codebase has pulled in a dependency on GLIBC 2.32 and I’m unwilling to risk my
laptop upgrading from Ubuntu 20 to 22. Rather than give up, I shifted my
development work to a Windows PC that I drive from my laptop. 
 I’ve…
So I’m in Blender and I’m generating asteroids using the Add Mesh -> Rock Generator tool (part of the “Add Mesh: Extra Objects” add-on) with an Asteroid template. 
 
 click 
 
 

 Each of these rocks is created using a few overlapped mathematical algorithms. The math is pure math, procedurally understood, with no hidden-node neural network in play.…
So I have found myself in the market for a new job recently. This isn’t the best
feeling in the world, but I’m not letting an opportunity go to waste. Today,
let’s talk about how to create a simple script that injects some content into a
LaTex document, in the context of creating a script that emits different
résumés with command-line-specified objectives. 
…

 An announcement by FIRST Robotics earlier this year revealed an interesting bit of news: next year’s kit would include AprilTags as vision targets. I’m completely unfamiliar with these, so I figured it’d be fun to dive in and see what they’re all about. 
 Generating some tags 
 AprilTags are a so-called “fiducial” system that identifies not only a…
Having created a new empty custom plugin in the
 previous post , we are now ready
to change it to make it play sounds when the boolean value it monitors goes from
false to true. The plugin is available in this GitHub repo . 
 Adding some visual feedback 
 Before we add the sound support, we’re going to add some visual feedback so we
can test the widget and assure…
Well, it’s off-season for the FIRST Robotics competition, which is always a good time to try new things. This year, I became more interested in Shuffleboard , which is one of the dashboard programs you can use to visualize telemetry from the robot on an attached laptop. Shuffleboard works by inspeting the shared Network tables that the robot and its control computer keep updated and drawing…
On a previous post, I discussed creating a simulator for a simple flywheel in
the FIRST Robotics WPILib framework in Java. We last discussed the high-level
framework and simulating a motor; here, we’ll go into simulating friction and
how we put it all together. 
 Friction is deceptively complicated 
 On the surface, friction is extremely simple. As is taught in high…
Well, the off-season of FIRST Robotics is upon us. A time when young people’s
minds turn away from robots and towards other things. Like simulating robots! 
 To give the team something to play with on the software side, I’m putting
together a couple of simulators of robot subsystems to experiment with. The
first one is a simple flywheel connected to one motor and…
I recently had to pipe some audio from my browser to a file. This may not be the most elegant way, but I found it works. 
 Using SimpleScreenRecorder 
 For capturing audio and video, I use SimpleScreenRecoder . It’s a pretty no-frills recording program that is intended for (among other things) streaming content from a machine. While it supports both audio and video, I only care about…
Recently, I had an Ubuntu laptop I use regularly develop a weird quirk: sometimes when I plugged it into USB-C, neither the monitor nor power would connect. I discovered I could fix this by simply running lspci on the laptop, which somehow forced both to come back. 
 As this made no sense, I dug down a bit more. I can’t say I found an answer, but I did find some more things worth…
One of the things I’ve missed, having moved my blog off of Blogger, is the metrics. I don’t use the metrics for much, but there’s a nonzero serotonin hit to knowing that my content is read by someone. It’d be nice to be able to restore at least that piece of the Blogger feature-set. 
 Fortunately, I have access logs and a log analyzer. 
 I’ve settled on…
In an earlier post, I added self-hosted static comments via shortcodes in Hugo. This approach had some benefits, but I didn’t like how it required modifying every blog page to support comments, even if no comments were present. 
 Hugo has a system of partials and templates to allow for similar pages to have the same layout. We can take advantage of these to handle comments on every blog…
Having chosen to self-host my Hugo comments as part of the static page content, there are a couple of ways to do it. In this article, I explore embedding them in the page using shortcodes. 
 The method 
 Comments in my blog are represented by two shortcodes. 
 comment.html 
 The first shortcode collects comment data in a semi-structured way and emits it as HTML. Here’s the…
After putting a bit of thought into it, I’ve decided to start the process of switching my personal blog to self-hosting on Hugo instead of hosting through Blogger. This blog is staying where it is, but I’ve been playing with the Hugo framework for awhile and am finding I really enjoy it. Expect to see some posts about my experiences with it in here from time-to-time. 
 Why switch?…
Privacy Policy 
 last updated: 2025-08-02 
 Change history 
 
 2025-08-02: Updated Comments policy to reflect new comment engine 
 
 Overview 
 
 General Principles 
 Site Access 
 Comments 
 Additional Concerns 
 
 General Principles 
 Balancing personal privacy with operational needs 
 This policy attempts to find middle ground between…
How to comment 
 To comment on this blog, send an email to blog+comment@fixermark.com in the following format: 
 
 Subject: “Comment on URL of page or ID of comment to reply to ” 
 Body:
 
 The name by which you’d like to be known 
 An icon (image or Gravatar icon URL); 128x128 pixels 
 The text of the comment. Markdown formatting will be copied…