Back at the E-Werk: The development of GAIA: Poetry of Life

Introduction:

Revision 2023 was the first physical Revisiondemo party after a few years of online Revisions, so everybody was very excited to come together again during Easter in Saarbrucken.

So me and Blossom started planning a new intro for this edition based on a raymarched scene of pillars with bridges and winding roads running through it. I had written a prototype using relatively simple SDFs and and Blossom had done the first FPU implementation on DOS and we were confident that with tight FPU code, small iteration loops and clever pixel skipping, we would be able to get this running in DOSBOX.

But after seeing our first prototypes crawl across the screen and we didn't want to sacrifice sound, we realised we were in trouble and we needed a change of plans.

Design:

I had been playing with several voxel-prototypes the year before, and one of them was a minimal type of landscape using a generate heightmap, which already ran reasonably well in DOSBOX. So with pain in our hearts we had to side our original ambitions and start focusing on getting this project off the ground.

The idea for the intro was to make a multi-part intro with progression that slowly fades from one state to another and goes through the different seasons of the year. This was accomplished by assigning a state or part to each of the pixels and slowly but seamlessly turn them from one state to another.

Eventually when the gaia logo came into play the progression and order was adapted to only reveal the logo and winter setting first for the first minute, holding back deliberately on the smooth transitioning and then wow the audience with the season transitioning in the second half.

Video Init and Palette Setup:

We knew early on that we wanted to use the same palette we had been using for Enigma as well, because it has color ramps for the earth, grass and sky that were needed for the intro. To save on space I did use the BIOS method of setting the color, which ment the color-ramps were only 16 colors each, which is why i'm also using a form of dithering to cover up for the lack of colors.

; palette and video setup (13 bytes)
xchg ax,cx ;1 (cx=0 )
mov al,13h ;2
palloop:
int 10h ;2
sub dh,4 ;2
sub ch,2 ;2
mov ax,1010h ;3
inc bx ;1
loop palloop

Generating the Heightmap:

The heightmap is generated into its own 64K segment at the start of the intro. With only using 22 bytes for the entire setup its pretty compact and consist of a simple automaton that I let run ont itself for 90 iterations before storing its value into the heightmap segment. Here is the innerloop for the texturegen (13 bytes)

imul bx,byte 117 ;3
mov al,byte [bx+64] ;3
adc al,byte [bx+63] ;3
neg al ;2
shr al,1 ;2

Text and Display Routine:

The logo consists of just using magnified text characters to make up the logo: <⌂ /\ | /\.
Obviously it took a little time fiddling around to get the right look and feel for the logo.

The text is printed at the start of the intro and then quickly copied over to a backbuffer, only to be read back at the apprioriate time in the intro.

Voxel Engine:

At the core of the intro is a heightmap based voxelscape raycaster with a dynamic camera, running entirely on the CPU.

This basically means we're running fixed step through a 3D world in 64 z-steps, checking the heightmap at x,z and extracting the height at that location.

Here is a bit of pseudo code that explains the concept:

for each pixel on screen
xray = 'rotated' x- raydirection for each column
yray = 'rotated' y- raydirection for each row
for z=0,64 do
  height = heightmap[z*xray][z+time];
  yprojected = z*yray;
  if (yprojected is smalled than height) break;
end
; determine pixelcolor based on depth and/or heightmap
end

Because voxel engines can be a little rough on the eye, i'm adding some subtle 'height dithering' for each odd/even vertical line, providing both a better looking gradient and taking a little bit off the rough edges that voxel engines tend to have. Furthermore i'm reusing part of the heightmap lookup to give the sky some texture as well.

Camera Operator:

To make the different parts/ scenes look distinct I added different camera perspectives for each. So horizontally that ment switching between looking and moving from left to right in one scene, to looking from right to left in the next scene. This was achieved by using a simple zig-zag pattern moving the camera left and right (about 8 bytes).

Furthermore I wanted to bend perspective along the z-axis either upwards (suggesting the camera diving into the valley) or downwards giving the illusion of the horizon curling upwards to the viewer. Initially I was able to just self-modify XOR an instruction from an add to a sub an back, but DOSBOX wasn't having it. It seems that after exactly 3 Self-Modifying alterations to the code, DOSBOX just refuses and jumps back to the slowest-core possible.

Because of this DOSBOX quirk I had to waste no less than 14 bytes(!!!) on the branching and alternation of the perspective bending. But I didn't want to loose that feature so I decided to swallow my pride and cut back a little on the audio to make it happen.

Sound:

Because I really wanted to have sound in the intro, I did spend a good chunk of the sizebudget on making a piece of music that evolved over time and fitted with the visuals. The sound consists of a kick+droning bass sound that work together, offseting eachother, with a single string on top. The strings and kick are masked depending on the part of the intro.

The original music also had a lead part to it, but I had to remove that towards the end to make room for the camera-perspective distortions.

Conclusion:

By the end of the development, I was pretty confident the intro would have a good chance of winning Revision 2023, and it turned out the audience agreed. Little did I know at the time that this would start my journey away from full scale DOS intros because mentally I decided to never ever want to have to make the a choice again between having sound vs cycle-heavy effects.

In either case, I had a great time at Revision 2023 and it was nice to talk to people that I hadn't seen in a while.

The original intro we had intended for Revision eventually made its way to MicroW8 as Pharos, winning the 256 byte intro competition at Evoke later that year.

You can find the intro at: demozoo

Return to blog overview