Personal Projects
Here are my most interesting projects, more or less in reverse chronological order.
Bible Reader (2025–)
A (yet unreleased) Bible reading app. Or rather, web app. It turns out web technologies are really good at displaying static text, so I didn’t bother with any “native” tools.
It’s still in its early stages, though the typesetting is really nice[a]. The most interesting thing I learned was about “scripture formats”. The Bible is so unique in its structure that there are multiple formats only for storing it! I wrote a converter from one of them[b] to HTML so I could display everything as intended by the translators.
[a] A lot of what I learned there I also apply on the web version of this blog.
[b] USFX, not the best choice in hindsight. I should have gone with USJ or USX.
cmod (2025)
cmod: a modern C build system that doesn’t require build files
I wrote about cconf[a] a while ago, when it was still written in awk. I had rewritten it in Python, using TOML for configuration, and with some extra features, but deleted my only copy (argh!) with a misplaced rm command.
[a] cconf, a build system for C
I think the basic idea still has some merit, but after losing the code I reconsidered. Maybe I don’t want a configure script at all! So I wrote cmod, a build system with no mandatory config. It just recursively lists all C files and links them together. You can add a config to link in system dependencies.
It’s a very simple shell script that generates a build.ninja and immediately invokes Ninja. It’s missing some desirable features, such as compile-time options, custom preprocessors, and being written in a real language, but I’m already using it for all my C prototypes. It’s really nice, feels like Go or Rust.
It’s also in a git repository now, so I can’t lose it.
Oken (2022–2025)
Oken is a very ambitious project I redesigned many times and have very little to show for.
The goal was to have a Lisp-style REPL debugger, Tcl-style syntax, a gradual type system, pervasive multimethods, and the ability to compile to C for faster execution. It was supposed to be usable as a system shell, in-process extension language, or for writing full apps.
It was too ambitious and the design never really came together. The closest I ever got was making a prototype interpreter in Lua, following the Mal guide[a], without the Tcl-style syntax, but with all the runtime features I wanted. I saw that pervasive multimethods were... not a great idea. They are really hard to implement efficiently. And the rest was... just Common Lisp with a different syntax. Which you can already do in Common Lisp with reader macros.
Now, I fully appreciate how nice it is to have static typing. Dynamic typing is great when you compare it to crappy static typing systems, like old-school C or Java, but most of the speed of development advantage is pointless when your programs are unreliable because of it. I still don’t like theorem-proof-style type systems, like Haskell or Rust (though they are really cool in theory) because they make the program hard to modify when invariants change, but dynamic type systems provide no help, until you run your program and get a type error.
momOS
For a long time, I’ve been thinking about what operating system I’d recommend for my mom to use. Notably, I’d want it to be the same that I use, so it needs to be something both command-line hackers like me enjoy, but also that a non-technical (but smart) user would enjoy.
There’s no releasable code, but the current version looks like this:
- Chimera Linux as a base
- COSMIC for the UI
- Firefox + a custom version of Phoenix config as the browser
- LibreOffice or MS Office on Wine for a desktop suite
- graphical frontend to apk for the package management (manages per-user world file, and installs it as virtual package)
My mom hasn’t gotten around to reviewing her computer yet (she’s busy with other things) so a lot of this is theoretical. But it’s fun to think about. And even if she doesn’t switch to Linux in the end, I’ll probably switch to Chimera and a version of the above config eventually.
3D Pong (2023)
A really, really bad game I made in a few hours, as a personal game jam, just to know what it’s like to “finish” a game. The “theme” was 3D. Any game, as long as it was 3D. Unfortunately, the end result is so bad I can hardly consider it “finished”.
Lake (2020–2021)
The Lake programming language: C but sweeter
Lake is a “C replacement”[a]. I started this one after I wrote a little server in Rust. I didn’t like Rust, for various reasons, but I also missed some features when I returned to C. So my first try, which I now call lakec-old, was C, with a cleaner syntax and a few features from Rust.
[a] The name is a bad pun, I know, but “P” (from BCPL) was already taken, and “D” was too.
I started from cproc[b], a C compiler, and progressively modified it. I changed the syntax, added operator overloading, improved macros, structural typing in some cases, generics, and several other QoL improvements. I tried adding ownership tracking but it was really buggy. And as soon as I tried using it, I realized that copying features from a language I don’t like (Rust) had created another language I don’t like. Who could’ve guessed!
I gave up when I was trying to implement type inference for generics and was having a lot of annoying bugs. I realized I no longer believed in the language design, and decided to start from scratch.
After two other from-scratch redesigns (only designs, no code), I ended up with... basically Pascal. No, really, the only things I have against Pascal are its known warts (all easily fixable) and its verbose syntax. At this point, I had learned a lot more about using C effectively[c] and so just switched back to using C, putting this project back on the shelf. I still want to revisit it someday.
[c] Mostly from Chris Wellons (check out the rest of his blog too)
SGS/libeverything/libok/libwinr (2019–2022)
This one has had multiple names, for each iteration. Only libwinr has been released[a], and in a rather incomplete state.
[a] libwinr: open a window and get a framebuffer
The idea was to make the application layer for an OS running on the Linux kernel, and then worry about the kernel later (maybe based on Yax, maybe not). I discovered that Wayland is hard to work with directly, if you don’t want to depend on a bunch of other libraries, and that there is a reason we don’t see more graphics libraries today. They are a pain to write.
Now, I just stick to SDL3, on the assumption that it will be ported to any OS I ever need to use in the future.
Craft (2019–2020)
I have a long-standing game design concept that can be summarized as “Minecraft, but better”. My first real attempt at doing something about it was taking Michael Fogleman’s Craft[a] and modifying it.
[a] Craft: a simple Minecraft clone written in C using modern OpenGL (shaders)
I learned a lot about how it worked, and a lot more about how to not write C. It’s a very... interesting codebase. I tried doing some actual game design, but got sidetracked reimplementing everything because it was all so wonky.
In the end, the only new notable features were server-side world generation, and raytracing. I wanted to prove that I could do real-time raytracing on my 2014 laptop, and wrote a pixel-shader DDA raymarcher[b] to do it. It had hard shadows and refraction, but any attempt to cast subrays tanked performance. It ran at 30 FPS if the window was half of the screen size, which was enough for me at the time.
[b] Inspired by noeuclid, though I used a different algorithm.
I know today how to do much, much better, from starting with a depth map to doing path tracing with denoising, but I never want to revisit that codebase again. Maybe I’ll rewrite it someday.
Statically-linked Distro (2018–2019)
I unfortunately lost the code for this one. I had made a small “package manager” shell script, with no dependency support. Then, I compiled musl, binutils, GCC, sbase and other packages until my text editor (vis) and window manager (dwm, at the time) were all packaged as statically-linked binaries, compiled with my system.
I got really far. I was using these packages every day, instead of the distro-provided ones. Packaging the X libraries was interesting; because they are not designed for static linking, I had to merge the static libraries with their dependencies (by unpacking and repacking them) so I wouldn’t get errors for missing dependencies.
Eventually, I realized that it’s impossible to statically link OpenGL because it is a driver that needs to match your kernel driver. Which means every graphical program on modern Linux (with Wayland) needs to be dynamically linked, even if only for this reason. So I gave up on the project.
Yax (2018–2019)
I started this one when I got into college, reasoning that once I started working, I wouldn’t have as much time to hack on this kind of thing anymore. It’s a Unix-like microkernel, with multitasking, paging and a virtual file system. The VFS supports Plan 9-style user mounts, and serves as IPC.
This was my first big C project. I just took the OSDev “Bare Bones” tutorial[a] and went from there. I learned a lot about organizing things to avoid bugs, but my inexperience still shows: nearly everything is reference-counted! I also did the one-header-per-translation-unit thing that’s often recommended but completely pointless. I’d split modules with a larger granularity today.
I gave up on it as soon as I started making a disk driver and realized I really don’t like writing drivers. Also, it’s not different enough from Linux to be worth switching to[b], so I decided to drop it and consider it “done”. It has fulfilled its design goals—a “microkernel” with the VFS as IPC.
[b] Presumably after a large amount of work to make it usable.
It’s named after my middle name, Ieks. My last name (Minicz) sounds like another Unix-like microkernel, MINIX.
There is no unmount call because I forgot to implement one.