The development of Pharos

Introduction:

After hosting Lovebyte Turbo the year before, the Evoke organisation showed some interest in organising a Tiny Intro Competition at Evoke 2023. This was ofcourse great news for the sizecoding community and I immediately offered to host a seminar on sizecoding as well at the event.

Design:

The original concept for the intro was conceived around Christmas 2022/January 2023 as a sort of spiritual successor to Silos (2022) and consisted of rows of pilars with various roads/tracks curving through the scenery.

We figured we could potentially try to do this as a DOS Intro for Revision 2023 and early prototype code for the intro was written. However we wanted to have sound for the intro and ran into performance issues with some early DOS implementations. So when Evoke 2023 came around we revived this original prototype and targeted the MicroW8 using CurlyWas and optimisations using WebAssembly.

Visuals:

To generate the visuals we started with a fairly basic raymarching setup for rendering vertical cylinders that had a camera moving through the scenery that was tilting left and right.

From here we started experimenting with various (dynamic) cylinder shapes, curved roads and at some point even some moving platforms. It was important to get a somewhat upwards looking perspective to make the scenery look a bit more massive in size.

The main structure is created using a larger mirrored arcs spread across in X/Z space and repeated more frequently in height. Then the tracks were layed around the vertical center of the world by taking the maximum value between the absolute py coordinate and the squared domain repeated px coordinate + a pmove offset (which swirls back and forth when moving the Z-space).

Colors and Texture:

Once geometry is hit we calculate a simple vertical colortexture of repeating bands that fade away in the back to get a sense of depth for the scene.

Most of the default colors/hues on MicroW8 weren't really working for the scene so in the end we settling for the last colors and the first colors of the palette to cover mostly tinted greys with some parts of the scenery being colored a bit dark-cyan.

Progression and Title Logo:

Overall progression was achieved by having a single global fade-value over the entire intro that is used for the overall color fading, determining the maximum rendering distance, audio filter offset and audio volume.

Then for the title text, there is a piece of empty memory that holds the 'pharos' character textdata. There is a way in MicroW8 to have a piece of text in memory printed using the default 8x8 character-set so at some point in the intro we just flip the text-offset from a piece of empty memory to the pharos text to reveal the logo.

Optimisations:

So here are the different size and speed optimisations tactics we used on the intro to get everything within the size limit:

* Given the complexity of the scene only a quarter of the pixels are calculated and drawn.
* Both the x and y loops have the same iteration counter ( 320 ), so technically its overdrawing.
* Using the same divider for extracting u,v ray directions from the x,y loop.
* Moving from actual more-complex cylinder-type of geometry to mirrored arcs.
* Placing the swirling roads around the vertical world-center, not requiring an additional vertical offset
* If possible use as few different float values as possible.
* If possible use as few different i32 values as possible.
* If possible use 'int-value as f32' to represent float values.
* Use inline variables/code as much as possible.
* Don't initialise any variables unless you really have to.

Audio:

This intro uses filtered bytebeat for music. Note frequencies are calculated by a piece of code and then fed to a minimalistic low/high-pass type filter that changes over time to make it sound less monotonous.

; freqmul is either 5 or 6 depending on the key it is playing the notes.

T = t / 14353 ; note-trigger timing
note frequency = ( (( (1 + T%4) * freqmul) ) * t / 32));

The note frequency is then divided and put into a soundshape like a saw-wave or in this case a sine-wave (which resulting in slightly smaller code) to get the actual soundwave.

This pure soundwave was then multiplied by a simple low/high-pass type of filter that slowly changes over time as the intro progresses.

Conclusion:

Had a blast at Evoke 2023 where I hosted and seminar and was able to enter and win their first ever 256 byte intro competition.

For more information, you can check out the intro at demozoo right here

Return to blog overview