scene.org File Archive

File download

<root>­/­demos­/­artists­/­unic/ultrakill_v1.zip

File size:
16 398 bytes (16.01K)

Preview

  • file_id.diz 5.81K
  • Ultrakill V1.exe 13.13K

file_id.diz

	-= General info =-
Product: Ultrakill V1
Platform: PC / Windows
Author: Unic (aka Takenaki)
Release date: 2026.07.20
Duration: ~4 mins

	-= System requirements =-
CPU: Not too slow :D Tested on i7 8700
RAM: 600 MB for the demo itself
Screen: at least 268x350 (: Runs in borderless windowed mode.

	-= Credits =-
Original soundtrack author: MASTER BOOT RECORD
Original artwork author: Jericho_Rus
Testing: mgua1

	-= Tools used =-
The demo is written in D language and compiled using LDC2 compiler with -betterC flag.
IntelliJ IDEA - IDE used to develop custom tools in Java and the demo in D lang.
FL Studio - to open the soundtrack source score.
Fabinek - custom tool for manual 1-bit images compression.
Mazylek - custom softsynth music sequencer.
Crinkler - tool for extreme EXEcutables compression.

	-= History and technical details =-
The story of this demo started from me blazing on the screen and thinking how well the image I was staring on could be compressed. The image was the Ultrakill artwork.
The image has 1-bit palette colors; its size in PNG was 6866 bytes. So I've decided to convert this image to a sequence of drawing commands.
I've thought out a asm-like language with 16 commands like "draw a line", "fill a rectangle", "switch mode to xor", etc. Each command was optimized in the way how much bytes in will take after compilation to a byte-code. I called the language Fabinek (referencing to the math rock music band Angine de Poitrine, who has a track "Fabienk"). I've implemented a handy GUI editor (in pure Java 17, without any external libs) with real-time command interpreter to have a convenient way to create images using Fabinek. Also I've implemented a compiler and decompiler, which translates Fabinek text commands into compact binary code.
After that I've spent a couple of days to write a Fabinek code for the Ultrakill image. The final image size was 3288 bytes, which is much less than in PNG format. But I couldn't just give the image to a person, because they wouldn't open it. Sharing them Fabinek wasn't an option, because it would require JVM to run it, and the JVM itself weights a lot compared to the image. So I've decided to implement Fabinek decompiler in a natively compiled language.
I did read much about the D lang, so I've decided to try it. I used -betterC compiler flag to achieve the best results in context of executable size. My goal was to make the final EXE file less than original PNG file. I've rewrote Fabinek decompiler, BitStream class and all the drawing methods to D lang, made it work, but final EXE size was quite far from what I expected: ~18 kbytes. And then one word came to my mind: Crinkler.
After spending additional hours to understand how to use that masterpiece tool, I've finally managed to compress my EXE file to just 5978 bytes. It was significantly less than original PNG's 6866, and I felt it like absolute win, because I had a totally independent executable file that renders an image and weights less than the image itself in compressed PNG format. I was happy as never before: I felt I've just touched the great world of demoscene.
I decided to not stop on that, though. The next challenge I've thought out for myself was the music. The "Tenebre Rosso Sangue" soundtrack written by one of my favorite music composers (MASTER BOOT RECORD) did fit the most. I've already made a synthwave cover on that track, so I already had source score in my FL Studio project.
To move the score from FLS project to the EXE file, I've implemented another one tool (also in pure Java) I called Mazylek (referencing to the same music and their track "MATA ZYKLEK"). Essentially it's a GUI sequencer that looked like a very limited version of FLS. The main thing was soft synth generators (instruments): lead synth, bass synth and 4 drums (kick, snare, ride, crash). As for Fabinek, I've implemented compiler and decompiler also for Mazylek - and moved the first little part of the soundtrack to use it for further testing of my little EXEcutable.
As previously, I've implemented a part of Mazylek code in D lang (decompiler, mixer, track generator). After I got a stable working build with properly playing music, I've decided also to add some visuals like simple animations to make it more "alive". After I've added some, I've continued moving the whole soundtrack to Mazylek format. I spent several days to move all the notes for all the instruments, fixing some bugs and optimizing the EXE file size on the way.
After the music work has been completed, I've added the last thing to the EXE: a loading progress bar. Just to eliminate the dull waiting time and window freezing while music track is generating.
In the end, the final total crinklered EXE file size was 14576 bytes. I was more than happy with this result. It even fit 16k category! But at that moment I missed one little part of the soundtrack, so I've decided to add it thinking it won't add too much bytes into the final EXE. But it added. With full soundtrack I had smth around 18500 bytes. I wanted to fit the 16k category again, so I started working hard on optimizing data sections and making them more predictable for Crinkler's algorithms. After spending a whole day, I've got a result of 15997 bytes. I had few more ideas in my head, so I decided to try harder. After sorting music data, fixing few bugs I've found by the way and applying more data structure alignments, I've finally got the final 13441 bytes, which was even beyond my expectations.
Overall, I've spent around 2,5 months (including 16 days of my vacation time, which was mostly dedicated to the demo making). It was my the very first demo making experience and I absolutely loved it. That was a really great true nerdy programming adventure. Sure, I realize I'm a long way from pro demo makers, but at the same time I realize I'm finally into the Scene.

In the name of true art,
PRAISE THE CODE