This is a list of all of the pieces of code I can remember making that I am
even slightly proud of, so that it counts for something, even if I don't get to
work on most of them anymore. I can't be bothered linking all of the GitHub
pages just yet.
jcweb, this website, hosted with nginx, and generated from the subset of
markdown that I have bothered to write a parser for.
adamant, a stub programming language. The design is very exciting to me, of
course, but the parts that I have implemented are a two-pass compiler, that
turns a string directly into sequences of assembly-like instructions, and
then either executes those instructions as is, or emits them to an ELF file,
which it hand-writes using fputc. It has nested infix
expressions, mutable variables and immutable variables, and at compile time
it has function calls, but none of the imperative control flow that it really
needs.
algebraic proof assistant, a newer project (as of 2022) that allows the user
to write computer-verified lines of algebra, that alternate between algebraic
manipulation that is checked with sparse polynomial expansion, and
substitution that is checked through direct comparison of subexpressions. It
is implemented in C as well, with the expressions being parsed in the same
way as in Adamant, this time with literal Reverse Polish Notation for
expressions. It needs a lot more features before it can prove interesting
things, but it proves the concept that readable and ergonomic proofs can be
written and verified without any combinatoric explosions or dynamic
programming or anything.
function plotter, a very simple X11 app that draws a parabola, and supports
clicking and dragging, and zooming. It is based on a stripped down version of
the settlement crafting trading demo. I was going to build it with a kind of
module language for building numerical approximations of functions, but I
might see how the algebraic proof assistant goes, and then rebuild this
plotting stuff as a tool over the top of that.
Colour cube, With the template I made for the function plotter, I also made a
cross section of the RGB cube with it, oriented so that the centre is always
gray, with saturation increasing out from the centre, and hue varying by
angle. The base gray value changes with time, showing an RGB triangle with a
dark centre, then an RYGCBM hexagon with a gray centre, then a YCM triangle
with a light centre, down to a single white point, and then the whole thing
again in reverse.
fixed-point arithmetic math algorithms, I wanted to find my own
approximations of sin and tan and so on, and so for that I needed three
things, sample functions to approximate, a root/turning point finder, and an
implementation of the Remez algorithm, which calculates a polynomial
approximation of a function by iteratively calculating polynomials that would
have error values that are equal at certain points. I managed to implement
the sample functions, using variants of what turned out to be the binary
logarithm algorithm, using my own variable-accuracy integer implementation,
and did nifty things like calculate pi to 64 bits or something, but I
probably should have just used long integers. All of this prompted me to
later try the plotting environment instead, since plotting functions and
their errors and things turned out to be crucial to effective debugging.
SWEEPR, a minesweeper solver that generates levels and then solves them using
all of the local flagging rules I know, although I know some slightly less
local rules that I never implemented. This was my first non-university C
program, back when I was a Rust programmer, and had only just learned that it
isn't actually illegal or stupid to write C programs.
Some haskell code to generate binary trees, to find a counterexample to a
maths research question I was exploring for a project at UTas.
Some C code to generate group elements, to check whether certain groups were
finite as part of my Honours research in quantum computation. (Also that year
I wrote some C code to help me do some Christoffel symbol calculations for a
relativity course.)
A Rust Vulkan pipeline made using Vulkano, for drawing isometric cubes with,
and later for drawing circles and squares with, that I used to make Enigmatic
Influence, a game jam game about navigating a grid and collecting orange and
blue dots, which interact and decay in the player's inventory. I also made
some weird data driven state machine thing and an isometric heightmap thing
with a cube that you could walk around with WASD, while other cubes
transformed over time according to the weird state machine thing. This was
meant to be a civil iteration.
Lofer, a Rust program that uses lalrpop to parse a simple Agda-like language,
and then type checks programs in that language. Expressions were
(variable/global id number, [argument subexpressions]), and
there were no lambda expressions, so you had to write all helper functions
explicitly. In the second iteration there weren't even with expressions, eek!
Other interesting things were that the language wasn't actually lazy, so you
had to write thunks explicitly, and axioms/postulates could be given
unchecked rules for computation, which lets you use Church
encoding/impredicative encoding to implement data types, and lets you
describe conditions under which the fixpoint combinator is safe to use. I
also had ideas that I never finished working out or implemented, for an
implementation of the univalence axiom that computes.
Tactics, a prototype game written in Rust with Piston and Serde, and standard
library TCP sockets, that hosts servers, and then allows clients to play a
Frozen-Synapse style tactical game with NPCs that can kill each other if they
maintain line of sight for a certain length of time. The big thing I was
doing with that was giving the player arbitrary granularity in control of the
units, with the game playing for both players up to the point where their
plan ended. This way the game would be more about perfect information, rather
than the bluffing games that Frozen Synapse devolves to. I didn't actually
add any content that you can use to overcome the perfect information
stalemates though, and ended up prioritising more of the economic simulation
ideas over continuing this one. Maybe I'd be a published game dev by now if I
had stuck with it.
Colliding circles, another Rust + Piston project, where circles would collide
with each other using an overengineered ray-marching logic to work out when
next to check for collisions. I really liked my continuous-time systems back
then. This was meant to be a Civil iteration.
FlOP/Sulphate, an interpreted programming language that was meant to be helpful in
building economic games, but just turned into a general purpose scripting
language. It was going to have my own interpretation of Java style OOP stuff,
as well as in-line asyncronous wait instructions that I have recently learned
make the language much more like Erlang or Smalltalk than Java. Later I split
the asyncronous ideas from the OOP interface ideas, but didn't actually
implement either any further.
HLink, a fairly small Haskell program that records filenames/paths that it is
called with, and then creates symlinks from the old locations of those files
to the new locations of the files, if you call a second program on the same
directory after moving it. This was a fun workflow that let me move lots of
files to an external hard drive, but that isn't something I do anymore.
bf assembly, a simple structural language for generating brainfuck code using
subroutines, compiled into assembly with a simple python script, and then
executed using another.
I basically never use tutorials for the specifics of the algorithms or designs
that I use – I tend to use tutorials to learn how to use languages and
technologies, learn how those things work at a broad conceptual level, and then
figure out the actual algorithms and architecture myself.
One significant example of me working out an algorithm for myself came up when
I started writing my own parsers in C, where I knew of Reverse Polish Notation,
and stack machines, and with those concepts alone I tried to write an
expression parser that would turn expressions into a sequence of assembly-like
operations, and inadvertently invented something similar to the Shunting Yard
Algorithm.
A more extreme example of inventing my own algorithms was when I was making my
sample implementations for arctan and arcsin, it just came from my own
geometric/complex number concepts, and Norman Wildberger's rational
trigonometry, and an understanding of normal bisection algorithms. After these
I also realised the same technique could be used to implement binary
logarithms, after doing the trig functions, but before
discovering that that is already a known algorithm, the binary logarithm
algorithm.
I have also made a number of technologies while experimenting with what to put
in my most recent Settlement/Civil/economic simulation game attempt, some of
which stayed in the game until the end:
A data driven entity system, where a single array of data describes all
possible entities, and another array describes all the crafting recipes
possible.
A data driven NPC resource management system, where arrays of data describe
where NPCs should store their stuff, and which crafting recipes they should
use to create that stuff, and which ones they buy and sell to/from the
player, and for what prices.
A simple dialogue state machine, for buying and selling items to/from the
NPCs, with the sales also data driven.
My own wrapper over WinGDI and X11 to provide a simple drawing canvas I could
do whatever I want with.
A whole software rendering system, to draw the sprites in sorted order every
frame, and then upscale the whole game world to allow zooming in and out, and
even rotation of the camera by 90 degrees, to see things from the side or
behind. (It is slightly disorienting!)
Hand made art and graphics for the software renderer to draw with!
A hand-written GIF exporter that sort of mostly worked, until it didn't.
NPC pathfinding, using a novel algorithm that was not meant to be based on
labyrinths and right-hand paths, but is conceptually quite similar to such
paths through labyrinths. It could be extended to handle complex shapes
better, but it gets around convex objects very efficiently. I figured I
should actually add buildings to the game first, before I spent time making
NPCs pathfind through those buildings.
Swarm pathfinding, to allow a group of NPCs to walk towards the player, then
navigate around obstacles when they hit them, and even step out of the way
if the player gets close to them.
Interaction menus that look at all of the crafting recipes that a given
keystroke could invoke, and lists them all in order for the player to select
with WASD and E.
Containers with container inventories, drawn as a grid of slots.
An experimental instruction system, where you select entities and specify
things that an NPC should do with them, where the virtual/anticipated outputs
of previous plans can be used for subsequent plans, and the whole plan will
get executed by the NPC as you walk off and do other things. This did not
last, because I thought maybe other directions would be more efficient ways
to getting to full city simulation. I don't have much to show for that
decision.
An experimental work allocation system, where multiple NPCs could fill one
large field together, instead of sticking to their own small fields.
A chunk system, that saves loaded chunks to dynamically allocated sections of
memory in a single file, and then only loads the chunks that come on the
screen. The entities in each chunk are manually serialised and deserialised
using fgetc and fputc.
An abstracted file format that the chunk system could be implemented on top
of, allocating space in the file for new data, then freeing the old data,
then writing a new index of all the binary blobs that are now in the file,
and finally 'flipping' with a single byte write, so that the save process is
entirely crash resistant.
A tile rendering system that draws all the dirt and grass in the world, and
draws nice curved grass boundaries between the grass and the dirt.
The iteration before this, written in C, had a vulkan graphics pipeline that
draws little circles and has them craft stuff, using data driven entities and
crafting recipes specified in a plain text file. It also rendered freetype text
using Vulkan copy image commands, to draw a text box where the mouse was
– this was when I realised that I should just do software rendering for
these 2D games.