[plug] MIMEcroft.sh: a 3D game written in BASH

mccabedj mccabedj at proton.me
Sat Aug 22 09:36:54 AWST 2026


My current toy project is MIMEcroft.sh. [MIMEcroft.sh](https://gmatht.github.io/j.cmd/www/MIMEcroft.html) is a parody of every 3D game ever, that lovingly pokes fun of bash's reputation for poor performance - by subverting it. MIMEcroft.sh is written entirely in Bash. The game logic, GPU shaders, even the sounds and textures are procedurally generated with bash commands.

One may wonder how MIMEcroft.sh pumps out 90fps at 4K given bash's reputation for poor performance. Indeed, the official GNU bash reference interpreter is poorly optimised compared to languages more commonly used for game development like C++. However, if your web-browser has a GUI it almost certainly also has a highly optimised JavaScript interpreter.

The online JavaScript Commandline OS (https://gmatht.github.io/j.cmd) did not port the reference implementation of bash and coreutils. Instead it takes the abstract language they describe. This language is translated into JavaScript, which a modern runtime can often reduce to machine code, resulting in performance over a thousand times faster than the original bash implementation.

For a concrete if somewhat contrived example, say that as a PLUG member you are (1) a square, and (2) 1337. As such, you may be interested in finding numbers that have 1337 squares, and use the one-liner:

for i in `seq 1 10000`; do if echo $((i*i)) | grep 1337 > /dev/null; then echo $i; fi; done

In the official bash interpreter, this may take a minute. However, j.cmd implements it by first [transpiling it into](https://gmatht.github.io/j.cmd/www/otranspiler.html#lang=sh&target=js&example=sqrt1337):

for (let i = 1; i <= 10000; i++) {  
  if (String(i * i).includes("1337")) {  
     process.stdout.write(i + "\n");  
  }  
}  
sh2.lastExit = 0;

Then it is all over in the blink of an eye: https://shorturl.at/8iD1O

One might well argue that this is not a real bash game since it has to transpile to JS before being run. A stronger argument could be made that C++ games are not real C++ games. A C++ game also has to be compiled. In most "C++" games the developer doesn't even give you the C++ source, you only ever get the compiled machine code. [MIMEcroft.sh](https://gmatht.github.io/j.cmd/www/MIMEcroft.html) is stored and distributed as bash. You can edit it as bash (try e.g. `vi /bin/mimecroft.sh` in j.cmd, changing `cys=0.900` to `cys=3.900` and playing the game again). The current version of j.cmd doesn't even cache the transpiled JS version of the game.

_______________________

It is important to note that j.cmd is experimental and still has many bugs. One little way it is more robust than the traditional bash implementations is that traditional shells tend to break if they source a file that isn’t in their own special format. On the other hand, j.cmd sees different shell formats as just different ways of saying the same thing. It will quite [happily run](https://gmatht.github.io/j.cmd/www/#prefill=for%20f%20in%20/home/examples/source.%7Bbat,c,fish,sh,zsh%7D;%20do%20.%20$f;%20done):

   for f in /home/examples/source.{bat,c,fish,sh,zsh}; do . $f; done

Sourcing C files is still a work in progress in j.cmd. I recently added support for passing [linked lists](https://gmatht.github.io/j.cmd/www/otranspiler.html#lang=c&target=js&example=linked-list) and [pointers to bash variables/functions](https://gmatht.github.io/j.cmd/www/otranspiler.html#lang=c&target=js&example=my_qsort) into sourced C functions, and cd'ing around C pointer structures.

otranspiler is also very experimental. It isn't just buggy, it is gradually being re-architectured into a general purpose X-to-Y converter but most the code assumes that much of the core logic is language specific... so its current architecture is fundamentally broken relative to its current design.

-------------------------
See also the YouTube game play and customisation video: https://www.youtube.com/watch?v=33OYvXuDTPo


More information about the plug mailing list