How Copyover MUD Servers Worked

Posted on February 6, 2025 by Jack Kelly
Tags: c, mud, coding

When I was younger, I played a lot of MUDs (“Multi-User Dungeons” — the text-only predecessors of modern MMORPGs, often played over Telnet). They were great fun, particularly during high school: a lightweight multiplayer game with no client state meant you could log in from any machine in any lab, even Windows shipped a Telnet client in those days, the Telnet protocol was light enough to run on my school’s slow PCs and limited internet connection, and the lack of flashy graphics meant it was easy to hide the window from a passing teacher or librarian.

At some point, building and tinkering with MUDs became more interesting than playing them. In those days, MUD builders and wizards (admins) were often recruited from each game’s playerbase, and many MUDs let builders edit the world through in-game commands. This was incredibly cool at the time — even through a clumsy line-oriented (ed-style) editor, there was something magical about summoning blank rooms from the void, writing rich descriptions to turn them into “real” spaces, and adding items and “mobs” (Mobile OBJects — NPCs) to make them come to life. A few of my friends and I signed up to a “builder academy” MUD, where everyone got a zone to mess around in, and we tried our hand at crafting our own areas. Most of these projects didn’t get very far, and all of them have been lost to time.

There’s only so much you can do with builder rights on someone else’s MUD. To really change the game, you needed to be able to code, and most MUDs were written “real languages” like C. We’d managed to get a copy of Visual C++ 6 and the CircleMUD source code, and started messing about. But the development cycle was pretty frustrating — for every change, you had to recompile the server, shut it down (dropping everyone’s connections), bring it back up, and wait for everyone to log back in.

Some MUDs used a very cool trick to avoid this, called “copyover” or “hotboot”. It’s an idiom that lets a stateful server replace itself while retaining its PID and open connections. It seemed like magic back then: you recompiled the server, sent the right command, everything froze for a few seconds, and (if you were lucky) it came back to life running the latest code. The trick is simple but I can’t find a detailed write-up, so I wanted to write it out while I thought of it.

Read more...

NixOS and Actually Portable Executables

Posted on January 15, 2025 by Jack Kelly
Tags: nix, cosmopolitan, coding

I’ve been very impressed by the Cosmopolitan Libc project and the αcτµαlly pδrταblε εxεcµταblε file format that makes it all possible. Building a crazy polyglot binary that works on two architectures and half-a-dozen operating systems is one thing, but Mozilla’s Llamafile project showed that APEs were more than just a cool hack: it’s stunning that I just download a reasonably smart LLM to my computer, chmod +x it, and begin a conversation. LLM use-cases aside, single-file dependency-free programs that work basically anywhere are just a great thing to be able to stick on a USB stick.

But APEs have been a little finicky for me. I run NixOS as my primary operating system, and sometimes an APE will refuse to launch, or I’ll need to pass --assimilate to it and permanently turn it into an x86-64 Linux binary before it’ll work.

The Cosmopolitan project, of course, has a couple of answers ready. One is to install a system-wide APE loader separate from any one binary and register it with binfmt_misc; the other is to patch the kernel so it can natively detect APEs. I don’t want to wait for a full kernel compile each time I need to update, so until the patch lands in mainline binfmt_misc is the way to go.

I have set up a Nix Flake at https://git.sr.ht/~jack/cosmo.nix to hold my experiments joining the Nix and Cosmopolitan universes. For now, it has convenient NixOS options to register the APE loader with binfmt_misc:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";

    # Import cosmo.nix and plumb our nixpkgs rev through it
    cosmo-nix = {
      url = "sourcehut:~jack/cosmo.nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs@{ nixpkgs }: {
    nixosConfigurations.myMachine = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        # Include the cosmo.nix module...
        inputs.cosmo-nix.nixosModules.default

        # ...and register the ape-loader with binfmt_misc
        { programs.ape-loader.binfmt = true; }

        # Your other NixOS config here.
      ];
    }
  }
}

Not bad for an evening’s hacking! I hope to take it further at some point in the future: I’d like to build the loader itself from a known bootstrap path rather than fetching a binary, and I’d especially love to be able to do the same with Cosmopolitan Libc and cosmocc. I’m a big fan of bootstrappable builds, and reliable building of ultraportable binaries from a documented bootstrap path would be an incredibly cool achievement. I currently get so much useful stuff out of nix develop — all my build dependencies, pre-commit hooks, useful CI targets, and more — and I have projects in mind where I want Cosmopolitan Libc to be a “tier 1” platform. Nix-based access to a cosmocc toolchain and all cosmocc-built build dependencies would make that so much easier.

A Dictionary of Single-Letter Variable Names

Posted on October 12, 2024 by Jack Kelly
Tags: haskell, coding

Haskell’s expressive type system means that type signatures can carry a lot of information. Haskell’s polymorphism means that you sometimes write functions that work across an enormous range of types, and are left wondering “what do I actually call my variables?”. It is often the case that there’s nothing to say beyond “this variable is a Functor”, or “this variable is a monadic action”, and so a single-letter variable name is appropriate. An unofficial and largely undocumented convention has emerged around these variable names, and so I wanted to write them all down in one place.

It should go without saying that single-letter variable names are not always the answer. Like point-free style, it sometimes obscures more than it helps and people get carried away with it. But when you have a highly polymorphic function and no good words to use, choosing the right letter can convey a surprising amount of meaning.

This dictionary is not and cannot be exhaustive. Variable naming often relies on context to convey information, and shorter variable names should only be used when they make sense in context. That context could be:

With the warnings out of the way, the dictionary is after the jump. The bulk of the dictionary documents type variables, where overly long variable names can blow out complicated type signatures. Important value-level variable names are also documented, and are explicitly labelled as such.

Read more...

Travel Tip: USB-C Desktop Chargers

Posted on October 6, 2024 by Jack Kelly
Tags: travel

I have travelled a lot this year, and after yet another trip where I lugged too many things around, I’ve been thinking about ways to cut back. The classic guide for this is onebag.com, which covers a very interesting mix of techniques and some carefully-chosen lightweight gear that will take you to the farthest corners of the map. Perma-nomad Vitalik Buterin has his own take on living out of a 40L backpack; one of his key points is to run everything you can off of USB-C. The benefits should be obvious: you cut down the number of charging cables you need to carry and your power bank can recharge any of your devices. While I’m a bit of a luddite, I can see a lot of people travelling with at least a laptop and phone, and possibly also a tablet, earbuds, and/or a smartwatch, all of which need power.

Vitalik’s guide mentions a USB-C “wall wart” charger that he uses to power his stuff. I disagree with this choice, at least for international travel: I think you want a desktop USB-C charger that takes an IEC C7 (“figure 8”) cable.

I’m not aware of any good articles that spell out the “desktop charger + replaceable cable” trick and how to actually find a suitable one, so a full explanation, research procedure, and some tentative recommendations are spelled out in laborious detail after the jump.

Read more...

I'm Funding Ladybird Because I Can't Fund Firefox

Posted on July 6, 2024 by Jack Kelly
Tags: rants, web

I’ve been meaning to write this one for a while, but the announcement of the Ladybird Browser Initiative makes now a particularly good time.

TL;DR: Chrome is eating the web. I have wanted to help fund a serious alternative browser for quite some time, and while Firefox remains the largest potential alternative, Mozilla has never let me. Since I can’t fund Firefox, I’m going to show there’s money in user-funded web browsers by funding Ladybird instead. You should too.

Read more...
All Posts | RSS | Atom
Copyright © 2025 Jack Kelly
Site generated by Hakyll (source)