This year I participated in the PC 1k intro category in the Assembly 2019 demoscene competition with my entry “Fluid Dynamics 101” and placed 3rd (check out 1st, 2nd and 4th). This is a byte by byte analysis of the entry. The rules of the competition are that you must create an executable or a website that is only 1024 bytes in size. This is an extremely limited amount of space to produce audio and visuals. This first paragraph is already 515 bytes or characters long, so the entire entry is only twice as long.
PNG compression and bootstrapping
I’m using a slightly adapted compilation pipeline what was seen in Core Critical. Instead of relying on JSEXE doing the PNGification, I opted to do that myself inspired by p01’s write up on BLCK4777. Using better optimized bootstrapping code saved me 3 bytes vs. JSEXE’s version. Another 3 bytes was saved by better PNG compression using combination of PNGOUT, ZopfliPNG and PNGWolf. So, in total this approach saved 6 bytes. The code above should run in any modern browser. You could save 4 bytes by removing IDAT checksum and Chrome will still happily run it, but Firefox wont.
Rendering pipeline and Speech Synthesis
Now let’s take a look at what is hidden within that compressed section. Below you can see it after decompression. Because it’s been minified with all line breaks, spaces and such removed, it remains very hard to read.
To make it more readable, I’ve added indentation, line breaks and comments to the code. If you would remove those, it would be identical to the code above.
The fluid simulation is nearly carbon copy of the one presented in Chapter 38. Fast Fluid Dynamics Simulation on the GPU. To save space, some steps were merged together. I also dropped boundary conditions, which creates somewhat weird interactions at the edges, but it’s a 1k, we aren’t looking for perfect realism here.
We can’t really afford space wise to have multiple textures to store velocity, pressure and divergence, so the whole simulation state is stored into a single texture. We then read texture A and write to texture B and then swap them after each draw call except when rendering, since we don’t want to save that, just display it. Red and Green channels are used to store X and Y velocity, Blue for pressure, and Alpha for smoke which is used for rendering.
That’s it. Fluid simulation and speech synthesized audio in 1024 bytes. I think that there isn’t too much room for creativity with this tech in 1k space. I don’t know how much space the setup of textures and shaders take in native code, but at least sound is much easier to access, so perhaps something can be done on that side. In a browser you could omit audio to write slightly better visuals, however silent intros aren’t very captivating and extra 30 bytes isn’t much to work with.
That said, in 4k, 8k or 64k intros I think you could use both fluid simulations and speech synthesis to great effect. I haven’t seen too many intros using them and as demonstrated here, neither takes that much space. Additionally, the SpeechSynthesis API allows altering the sound with SSML tags, so you could make it sing something rather than just read the source code in a monotone voice.