Introduction:
I've been wanting to visit Deadline Demoparty for a couple of years now, but for some reason there was always something else happening for me around that time. But this year I was finally able to plan a trip to Berlin for some touristing and visiting the party and had a great time doing so. Obviously I didn't want to come empty handed, so I made sure to have a production with me for the 256 byte intro competition.
Design:
The original idea of this intro was done about a year ago, when I wanted to try to create something more organic looking in 256 bytes, throwing off a 'Shadow of the Beast' (Amiga game) vibe. I had a very clear image in my mind of what I wanted this to look like, but getting this done in a ~180 byte size budget (leaving some space for audio) was going to be a tough challenge. But after lots of work and optimisation, I think it turned out fine.
Visuals:
The heart of this intro consists of a CPU non-scalar raymarcher with a fairly basic/usual setup. Meaning your typical loops for scanning across the width and height of the screen as well as a loop for travelling along the ray-direction (u,v
). I usually use the variable z
for indication the total distance travelled (z=z+d*factor
).
I figured that starting out with an apolonion fractal would be a good starting point, as those tend to look kind of organic to start with.
Here is the pseudo code for generating the visuals:
// extract UV coords with some camera tilting (st) over time
u = (x / 320.0 - st);
v = (y / 128.0 + st) + 1.0;
// Distorted start position
px = z * u - cos(z) + t;
py = z * v;
pz = z;
// the fractal loop
s = 1.0; // initial scale
for i=1,5 do
k = 3.0 / (px*px + py*py + pz*pz);
s = s * k;
// calculated new point using sin as a shortcut to do cheap
// non-accurate (and in this case extra organic) domain repetition
px = sin(px * k);
py = sin(py * k / 2.0);
pz = sin(pz * k);
end
// Calculate distance to the final position anstretchedde by scalar s
d = (px*px + py*py + pz*pz) / s
Given the complexity of the SDF with the 5 iteration steps the rendering is speed up a little by skipping scanlines and only drawing half of the screen. A 'faster' version was also provided (and ran at the party) that skips horizontal pixels as well, making it more performant.
Layering:
The MicroW8 palette isn't that great, with only a few gradient ramps being somewhat usable (grey, deep blue, brownish) and lacking the deep colors. So after I had the visuals running I just didn't like the overall look and colors. They were not giving me the mood I was aiming for. So the effect was laying idle for a while until a week before the party when I had the idea to try and blend 2 different layers of the visuals into a single cohesive image.
So here I render the pure depth as a sort of blue fog layer on the even lines, and the actual texture and details of the output on the odd lines using the brown colors, blending them nicely together into a single output frame that is closer to my original vision.
Audio:
This intro uses a custom softsynth in the 'snd' function callback. After spending a good amount of time on it, I finally settled on a more droning sound to better match the vibe of the entire production. Still, even this minimized plan still took a good bit of the size-budget to pull off:
; Given t as sampleoffset
T = t / 16384;
freq = t / 32768.0;
fade = sin(freq / 96.0);
n = mod(freq,2.0)-1.0;
// kick 'n drone
n = mod(freq,2.0)>1.0 ? pow(n, 0.5) : (1-T%3) * n;
// filtered sawtooth
n = mod(n * 16.0, 1.0);
sin(n*n-n) * fade
The code above basically alternates between a kick sound using the power function and a rythmic pulsing of drone notes. Both the kick and notes are then slightly filtered before output to make it sound a little more polished.
Conclusion:
Visiting Berlin and Deadline has been a great experience. Was great to meet and talk to the many nice folks at the party. Compos were filled to the brim with quality content across the board.
You can check out the releases from Deadline 2025 at Demozoo