Posted by matt_d 12 hours ago
https://github.com/ioccc-src/winner/blob/master/2025/ncw1/pr...
The author, Nick Craig-Wood, is the creator of rclone!
If you want to see how the sausage was made, here is the source:
https://github.com/ncw/ioccc-gameboy
You'll find an unobfuscated version (kind-of) there too. This the the one I actually worked on then I had a program squash all the variable names and squeeze it into the gameboy shape
The size limit for the entry was the killer. You are allowed 2503 non white space characters (a simplification - the rules are complicated) in IOCCC entries and 4K total code size. This isn't a lot to fit a Z80 processor and a GameBoy hardware emulator in!
I first wrote a full Gameboy emulator in C. It started out at about 6000 non white space characters. I then spent about about 100 hours work trying to get it to fit into the 2503 limit. For a long time I wasn't sure it was going to fit.
I decided making the emulator play Tetris (which is a fairly simple game) was the target so I stripped out features like the half carry flag in the Z80 emulator and the windowing system in the Gameboy emulation which Tetris didn't need. I also abused the C code terribly doing things with implicit int I can never un-see. I also got creative with the IOCCC rules which are implemented in a C program which checks your source and I spent some time reverse engineering that looking for loopholes! I discovered that the operators defined in <iso646.h> only count for one token which was very useful.
Once I had it small enough I had to supply some games to run with it. I created 4, a test program written in z80 assembler, a pi calculator (written in assembler), a 3d tic tac toe game (written in C with gbdk-2020) and a chess program also written in C. I discovered that quite a few open source games ran on the emulator too so I added a downloader for those where I could. Apparently not many games use BCD arithmetic - who would have thought!
It was a fun project.
GCC says there are a bunch of undefined symbols, first one being "R" right in the beginning:
typedef unsigned char u;
u w,X,T,D[1<<16],t[]=R,U=255;[0] https://github.com/ioccc-src/winner/blob/master/2025/cable/p...
[1] https://github.com/ioccc-src/winner/blob/master/2025/cable/R...
I could have gone all out writing standard library routines for opening files, running shell commands, coding strstr, strcpy, and similar. And to be honest I did implement some things I didn't need as part of the learning process (for example print(getenv("HOME")) works). But I soon realized I needed some example programs to test things and show off.
So of course the first real program I implemented was a brainfuck interpreter. Which means my language is now, indirectly, turing complete!
My early versions took 9 minutes to output the famous mandelbrot program, so I had to make a bunch of optimizations, and later implemented support for switch/case statements to speed things up. Now I can generate the same output in two minutes - so room for improvement, but also a good bit of progress!
Cheating by implementing another language in my own was very very satisfying. Though of course this is all for fun/learning and not intended to be used seriously by anybody, not even myself!
>This VM implements an OISC - a One Instruction Set Computer. That instruction takes three signed 32-bit operands, a, b and c, and runs a program from memory m[] as follows:
1 PC (program counter) starts at 0
2 Fetch the next instruction (32-bit signed operands a, b and c)
3 If the low bit on any operand is set, remove it, and replace that operand with m[operand] i.e., a dereference of that address
4 Set m[b] = m[b] - m[a]
5 If m[b] is 0 or negative, set the PC to c, otherwise increment PC by 3 words
6 Go to step 2
There's the one here: Set m[b] = m[b] - m[a]
Then it links to the reference implementation on github [2] which says you just need the napkin notes [3], which is dividing everything read by 4, which is corroborated by the reference implmentation [4], but it's not clear why 4 is chosen here rather than 2, as it seems to waste a bit. Was this bit needed, or is it reserved for future expansion?
I presume the original implementation didn't do the divide by 4 and it was added later, but I don't see why it was needed, other than perhaps just making LLVM code gen a little easier. I'd need to work through lots of examples to work out if the system as described is impossible without dividing by 4 (although you'd presumably only be able to access even addresses, and the PC increases by 3 each time, so it would definitely be annoying to refer to code locations).
Then the reference implementation starts doing magic when location 64 is accessed, overwriting locations 64-67 with the current time, which is mentioned in the napkin description, but not the description on the main page.
Both descriptions mention the magic -1 address, so it seems strange that the very implementation-dependent UTC clock isn't also implemented with -ve addresses rather than trashing memory that is otherwise free for the implementation to use as desired.
Both descriptions also mention the regular timer interrupt process, which also seems disappointing, reusing address 0 as the interrupt handler location and 1 as the saved PC, which means that you have to overwrite the initial entry point at location 0 as soon as the program starts.
[1] https://eternal-software.org/
[2] https://github.com/adriancable/eternal
[3] https://github.com/adriancable/eternal/blob/main/docs/napkin...
[4] https://github.com/adriancable/eternal/blob/main/vm/vm.c
https://www.youtube.com/live/MoWCwZx1Swc?si=eIOlRsKWNKRVRZeB...
"The IOCCC has a rich history of remarkable winning entries created by authors who skillfully employed various techniques (often their own tools) to develop their code."
Also, the reverse is interesting: how well can they guess the function of the obfuscated code?
I think it's great that IOCCC accepts code that might have been built with machine assistance, because it makes the purely handcrafted winners seem even more valuable.
https://www.ioccc.org/2025/rules.html
It seems to refer to custom code generators. Why would they mean AI if they explicitly talk about a "rich history" (when AI wasn't available)?
The long tradition refers to the use of tooling in general, and could mean that, since past tools were accepted, recent tools like LLMs can be fair game as well.
But, since there can be doubts about this interpretation, them saying explicitly if LLMs are permitted or not could be beneficial. But then again, maybe they don't want to commit to an hard rule and have more freedom to decide on a case by case basis, or just don't advertise that LLMs are welcome to prevent a flood of vibe-coded submissions.
In both cases you cannot get permission.
One of the main characters is called Fern, and she almost exclusively uses the common offensive magic of Zoltraak.
– And?
– I'm sorry I wasted your time. I just can't understand it.
They burst into laughs and asked me to start the joining process.
I wonder if people still make fun of interns. I still have a good laugh when I remember myself freaking out.