VOLTRA: Grinding the Universe, a gritty JavaScript demo, winner of the 1024 bytes demo competition at the Assembly 2017.
The Assembly is a 25 years old demoscene event with the most anticipated 1kb, 4kb, 64kb and 256mb demo competitions. And I can not be more excited of winning the 1kb competition again after winning 2 years ago with BLCK4777 and getting 2nd place last year with ASTRA.
Grinding the Universe in 1024 bytes
With VOLTRA, I wanted to do something gritty. Extremely gritty. Something with a soundtrack out of this world, vocals ( yes! vocals in a 1kb demo ) and some visuals inspired by PETSCII and CGA graphics with a modern twist of 3D and post processing.
Here is a video capture of the final result, just in case.
Technical breakdown
The rules of the Assembly, and other demoscene competitions, is that the entry must be released as a single file, ready to run from file system. For the 1kb competition, the size limit is 1024 bytes. Since the entry must run from file system we can not use Gzip. To get the most we must somehow compress our entry and fit the compressed data and the decompressor code into 1024 bytes.
Minified code
The minified code of VOLTRA is 1345 bytes long.
c.style.width=c.style.height=`100%`,c.style.position=`fixed`,document.body.style.background=`radial-gradient(#023,#000)`,document.body.style.font=`0 a`;for(x=0;x<64;x++)c.width=c.height=12,b.shadowBlur=4,b.fillStyle=b.shadowColor=x%11?`#cff`:`#f26`,b.globalAlpha/=x<40?1:4,b.fillText(` V0LTRA ][ R1BB0N `[x]||S(9584+x),2,8),c[x]=b.createPattern(c,`repeat`);c.height=384,g=new AudioContext,p=g.createScriptProcessor(2048,c.style.top=c.style.left=a=m=0,1),p.connect(g.destination),p.onaudioprocess=o=>{for(u=o.outputBuffer.getChannelData(0),d=Math.sin(m/32),e=Math.cos(4*Math.cos(4*d)),f=Math.sin(4*Math.cos(4*d)),c.width=12*64,c.style.transform=`perspective(64vh)rotate3d(0,1,${f},${m/8}deg)scale(${1+(m/96)**64})`;a/64+64<8*m;b[i+64]=1&(-4&d*64)>>(4*b[i-1]+b[i]*2+b[i++])^1.01*Math.random())i=a++%2048;for(i=y=0;y<32;y++)for(x=0;x<64;x++)m+=1/g.sampleRate,j=2^y/5|1^x/20?(n=x/8*e-4*e-y/8*f+4*f+u[i]/4,o=x/8*f-4*f+y/8*e-4*e+16*d-8,n=0<o&[n%o,n&o+e*m,m+b[384|n+(o<<6)],n%o][3&m/24],b[i]|n&&(y^x&m)%16+40-20*n):12==y&&x<4*m?x-20:0,j&&b.fillRect(12*x,12*y,12,12,b.fillStyle=c[j^1.01*Math.random()]),u[i++]=(j/8+`9584`[3&m/24]*8)*m%1*d*d;b.globalAlpha/=x<40?1:4,b.drawImage(c,12*24,12*12,12,12,0,12*12,12*64,12),b.drawImage(c,12*12,12*24,12*3,24,0,0,12*64,384),3&m/24&&(h=speechSynthesis.speak(h,h.rate=0))};h=new SpeechSynthesisUtterance(`voltra`)
It assumes the following setup which takes another 81 bytes + some to load and run the minified code above.
<canvas id="c"></canvas><script>b=c.getContext`2d`;S=String.fromCharCode</script>
All in all, this about 1460 bytes of minified code that we'll have to compress down to 1024 bytes of self extracting code.
Compression & PNG bootstrapping
The final file, VOLTRA.htm, is a polyglot file which is both a PNG image and an HTML page with a bit Javascript that loads the file in an IMG
element, draws the pixels in a CANVAS
and treats them as the ASCII value of a long string of character which is finally evaluated. This way of bootstrapping a PNG image allows to ship a single file and to benefit from the compression ratio of PNG and ZLIB, and all the tooling that comes with it.
The code of the PNG bootstrapper takes 161 bytes.
<canvas id=c><img onload=b=c.getContext`2d`;S=String.fromCharCode;for(i=e='';t=b.getImageData(0,0,1,!b.drawImage(this,i--,0)).data[0];)e+=S(t);(1,eval)(e) src=#>
This means the PNG image must be no bigger than 1024 - 161 = 863
bytes after removing the IEND chunk. Taking into account the PNG header and various chunk headers, this leave a mere 818 bytes of DEFLATE stream for the code of our demo.
In other words: there really isn't much space to do something cool.
To be continued with the technical breakdown of the following topics...
Rendering
Sprite sheet
Cellular automata
Rotozoom
3D camera
Post processing
Music
Speech Synthesis
Additional links
- Packed version that fits in 1024 bytes
- Full archive submitted at the Assembly 2017
- Video capture of VOLTRA on YouTube
- VOLTRA on Pouet.net, the demoscene portal
Other recent experiments
There are many experiments and projects like VOLTRA to discover other here.
- FRONTFEST MOSCOW It was an honour to be invited to Fronfest Moscow 2017 with the little family to give my first workshop; implementing a Twin-stick shooter using ES6 and Canvas, and to continue my CODE🎙ART series of talks + live coding aiming to inspire new web developer artists. on November 18th, 2017
- BREATHING EARTH Another take on Nadieh Bremer mesmerizing Breathing Earth visualisation, running at 60fps on a 2D Canvas without libraries or frameworks. on June 26th, 2017
- CODING⯌ART AT RENDER CODING⯌ART at Render 2017 was part of my series of talks + live coding aiming to inspire new web developer artists. on March 31th, 2017
- JAVASCRIPT IS JARIG Javascript is 18 years old! Let's celebrate with a nice little tune. on September 14th, 2013
- WOLF1K The idea of this entry for the JS1K contest was to do the impossible: a 1K remake of the famous WOLF5K that rocked the final edition of the5K. It does not feature guns, evil grins and violence for in WOLF1K there is no room for guns or any form of violence. on September 10th, 2010
- MANDELBROT TRACER Possibly the smallest Mandelbrot tracer ever in JavaScript: 101 bytes on September 21st, 2008
- TERRA A voxel landscape rendered using a plasma in a valid 480bytes Atari bootsector. TERRA ranked #2 at Outline 2006 on June 6th, 2006
- OOMA The winning bootsector of Outline 2005, featuring two images zooming with experimental music in a valid 480bytes Atari bootsector. on March 30th, 2005
Let's talk
Don't be shy; get in touch by mail, twitter, github, linkedin or pouet if you have any questions, feedback, speaking, workshop or performance opportunity.