This is the story of Leviathan Sun, a poor and helpless 4k intro for the modern day browser, that uses the HTML5 canvas and audio api's with javascript to create a generative audiovisual experience.
The quest started when noticing i had a ticket but no entries for the Payback demoparty which was occuring in just a few weeks in Helsinki, Finland.
I had a few leftover javascript effects that never got used and decided to try something out, either a 64k or a 4k. Slapping the "framework" together was quite simple, just a few copy pastes from older similar projects.
The first bump on the road was getting some sound. The alternatives were to try and get a musician to do a .ahx, it kinda worked out ok when we used it on Parsley State, but it's hard to find people willing to track in ahx in 2013. A close alternative was to convince the musician to do a .mod, but only replayer for mods on javascript is buggy, so you might be shooting yourself in the foot by trying to use it. Ofcourse there already are some softsynths ported to javascript like js-sonant and sorollet. And then there was also the possibility of trying out GLSL audio, which seemed like an interesting concept, but i was running out of time and the prospect of having to learn the ropes by myself wasn't very appealing at this point. I ended up trying some algorythms of bytesize music code and after discarding most of them i finally figured out a couple of nice drone loops and some subtle glitch percussion texture.
The idea was to make the intro generative, that means that it takes a seed value and the content is slightly different depending on that seed. I had already implemented a similar concept regarding haikus for my Recycle Bin Laden web art project. So it felt obvious to connect both projects under the same roof.
The original idea for the generative aspect of the audio was to have several channels of different loops, which would be randomly selected to be included or not, and all of them have generative ADSR, that means that out of 4 channels, there was a possibility that only 2 of them could be played, and one of them have a quick fade in and long fade out while the other have not. Additionally the speechsynth would read out the current seed value, marking the tempo of the audio. After a few tests and debug sessions it became obvious on aesthetic principles that the tracks weren't really fitting together very nicely and that the ADSR trickery was mostly not working out at all. So i picked the best drone loop, turned it into a slow buildup, tuned the percussion elements to work abit better together and added some generative parameters to the sound (such as the tone of the drone, the probability of the speech synth being played at all, etc)
The visuals were 2 similar effects overlaid on top of each other. Both of them simple implementations of psychedelic centric circle effects references. Added some generative parametrization to some of the variables used, some occasional extra elements like the circles, the glitching bars and the possibility of a strobe effect.
Following Murphy's law to the book the version that was randomly selected to play on the big screen at the partyplace was of a horribly high pitched drone with an extremely abusive strobe and no speechsynth at all, which managed to alienate anyone from wanting to watch it till the end, forcing the orgas to censor it and causing everyone to completely miss out the build up hypnotizing concept of the piece. In retrospect, it quite successfully maintained the long track record of minimalartifact releases failing miserably to get displayed as intended on a big screen at party events.
After party comments seem to be mostly positive. Which is quite nice.
One last issue worth mentioning in this report is the heavy RAM required to load the audio buffer. Even 2 gigs sometimes aren't enough and manages to freeze the browser. Generated audio is a lot of data, but it shouldn't choke a browser to death. It only goes to show how beta the realtime usage of audio and graphics on browsers still is, hope to see some improvements on this department, not sure who to poke on the browsers teams to get this investigated and added to the dev roadmap but sure would be nice to be able to use improved audio api's.
Javascript Light & Magic
Monday 4 February 2013
Saturday 26 January 2013
Making of: Parsley State
Parsley State
A 10k intro made for DemoJS. (link)
Planning
Following up the disapointment of Cyboman 5 placing so low at Stream i decided to try again with a new javascript intro. I had also recently finished work on the "Under a Seering Sky" javascript game. Another disapointing competiton result, this time from Atparty wild competition. The new target event was DemoJS, a demoparty in Paris focusing on javascript and browser technologies. DemoJS popped up last year sponsored by Mozilla during their 2011 campaign to get more demos for the browser with a few events across the world. Competition would probably be harder but atleast the attending audience would more likely know what they are voting on. Aimed again for pure canvas, no webgl. There are still lots of things on the canvas specification that folks don't seem to be using that much, i wanted to explore that a bit.
There were 4 categories at DemoJS: 1k, 10k, demo and wild. 1k is mostly for 1 trick ponies and it's typical playground for webgl experiments, not what i was looking for. Demo would require a dedicated graphician to work with, so i also set it aside. Wild would have been great for something similar to "Under a Seering Sky", but i was running out of time to make two prods. 10k seemed more appropriate to aim for. So now that i knew the target, what i was missing was a good tune with small size. Fellow TPOLM'er Kaneel was recruited for the job. Our aim was to do a haterztro, sending joyful fuckings to all the folks that enjoy talking shit about us whatever it is we do. Inspiration from the epic B.o.B. track Haterz Everywhere popularized by machine drum on lazy sunday radios of old.
Research and development
Focusing on the 10k category i did some research on available sound apis and concluded we had 4 options to chose from for our plan to world domination to have appropriate sound:
1) bytecode music. Has the advantage of taking much less size, ideal for 1k and 4k. Has the disadvantage of always sounding like crap made my coders fooling around.
2) sonant-js, a javascript port of a softsynth some other sceners been using for native and web 4k intros. Has the advantage of a gui, useful for letting the musicians do the music. Has the disadvantage of generaly sounding overly simplistic. Great for simple pads and melodies, but that has all been done before to exhaustion.
3) ahx replayer, a javascript replayer of the famous ahx amiga sound format. Has the advantage of a well tested tracker gui and established format. Great fun for chiptune / oldschool fetishists.
Has the disadvantage of the replayer being unstable and relatively large in size.
4) jsmodplayer. Has the advantage of the musician being able to use a trackers interface to compose the track and the replayer been around longer then the other options so more likely to be something stable. Has the disadvantage of easily getting too big in size if the musician is careless with selecting his samples and patterns.
In the end we decided to go for AHX. Kaneel felt motivated to try some oldschool chiptune sounds despite having had a little trouble installing the amiga emulator and learning the tracker. I had to crunch any of the players anyways so as long as it sounded good any of the options 2) 3) or 4) would be ok. The choice of AHX had it's drawbacks: mild-high learning curve to learn the format, it's replayer actually emulates some amiga opcodes and can be quite unstable when you're trying to debug things in javascript debugger. But it had sound support for both the webkit audio and mozilla sound api, which is nice, the more browsers supported the better.
Guidelines
1 week before the event we started having some test tunes we were both happy with. We did a couple of interactions of syncing effects and reworking the track a bit. Unconsciously we morphed the original haterztro into something more TPOLM like.
We tried to follow a few basic TPOLM guidelines:
1) being informative
2) featuring tunnels
3) greeting TPOLM
4) being short and to the point
Information on Parsley was added. Unfortunately we had to cancel the second point of compliance with TPOLM technology guidelines. Even though we actually had a tunnel effect working, it was running in much too low framerate to be worth releasing. Greetings featured TPOLM. We focused on the theme keeping it short and not boring.
So the guidelines were more or less followed, further consultancy with our vintage superhero Antti "fthr" Jadertpolm confirmed the authenticity of our alignment. We spent some more iterations polishing colors and lyrics.
Travelling
At some point in time i was spending a bored evening and checked flight prices through ryanair to Paris, it was quite cheap to go from Porto, which i would be visiting at the time, so i booked the tickets on impulse. From that point on i really had to finish something decent to present at the event despite starting to run out of time.
Then, suddenly, just a few days before the event, i heard of a planned air traffic controlers strike being announced for the dates of the event. Confirmed the clash at the Ryanair website, they only mentioned to stay tuned for more information. Unsure if the flights were still flying i carried on polishing the intro with the help and consultancy from kaneel and fthr.
Then, just as suddenly, Portugal lost the semi-finals match of the euro to Spain.
Then, even more suddenly, the air traffic controllers strike was canceled and all flights were announced to be back on schedule. Hooray! The plan to become hopsters in Paris was reinstated once more. I informed the family, swapped meet up information, set my alarm clock and packed my computer bag to go to Paris the next day.
At this point the intro still had some small things needing polish and we were deciding between an easter egg secret part or adding some vector graphics to fill up the remaining space of the intro. We had 500 bytes left to fill up with something.
I met up with Kaneel on Friday afternoon after a long travel without food and we babysitted his daughter for a while, then went shopping for beer and took her for a walk in the park before another party visitor and the babysitter showed up. The afternoon was going by quite fast, the beers also, and we hadn't even made it to the partyplace yet. But it was now just a couple of metro stops away! We exited the metro at Bastille and found our way to ISART, the partyplace.
Party coding
Upon arrival we immediately met some other foreigners and instead of working we continued our hopster beer adventure through the night. After too many beers we finally decided we should probably try to get the intro finished instead of just getting drunk.
We only needed to fix some syncs in the greetings and add the coat of arms graphics, should be easy to do. Right?
Getting a place to setup was easy, everyone was watching a screening of Moleman 2 while we wrestled with the WiFi... It was supposed to exist but it didn't. We needed internet to convert the SVG into canvas code, so we bothered the organizers. After a few hours and a few more beers the internet was working again and a converted version of the SVG was now in place. The intro had just bumped from 9k to 12k. Let the optimizing begin!
Kaneel was playing demo VJ with the big screen while i tried out a few optimization tricks. First manually removing the weird animation junk code from the svg conversion. Then removing some decimals from the bezier curve data. Then removing all decimals from the bezier curve data. Then removing some of the bezier curves themselfs. Just had to make sure the quality was still acceptable.
At some point Kaneel had to leave for home and i took the wonderful opportunity to get some food. Returning to the partyplace most of the people had already gone to sleep. Our intro was still at 11k so I carried on optimizing some more. Next step was removing functionality from the AHX replayer that wasn't beeing used by the track and hacking some functions to generate data instead of using the lookup tables. Still too big.
Compress me beautiful
Re-watched p01's talk on creative coding and size optimization to remember a few tricks. Replacing all Math.floor calls with 0|, dirty trigonometry, function hashing, etc. Function hashing called for some more wrestling with closure compiler to get the intro working again.
After a long night of trying several updates and reverts i was still 500 bytes too big. Trying out JsExe instead of PNGinator would give some better results but still always 40 or 80 bytes too big from the 10240 limit.
I started comparing the code directly with the closure compiler version. I noticed that some optimizations i would do would size down the closure compiled version significantly but have little impact on the final .PNG size. This can be explained by common compression entropy, the compression takes heavy advantage of repeating elements, so the more and longer repeats you have the better it's ratio of compression. When you replace the long repeats for smaller versions you are doing work the compressor would do, and probably doing it in a less optimized way, so you end up losing compression ratio, making your optimizations worthless.
Ofcourse i could just cut the graphics out of the intro and go to sleep, but that would be cheating! I took a couple of breaks to refresh myself and went back at it. But i was still at a dead end, trying some new desperate hacks and the best result i could still get out fo JSexe was 10260. I decided to bug Gasman, asking for his opinion if i should keep trying to optimize the closure compiler to the max hoping that eventually the final size would start also decreasing or try to rearrange data in hopes it would pack better. Gasman took a look at my code and paused at the AHX track loader. I been loading the track by including a base64 encoded version of the track and decoding it on load. Gasman had the idea to replace the base64 with an url encoder. The string would no doubt be longer but the PNG compression should compress it better, also we would be able to replace the 2 functions related to the base64 utf8 decoding with an eval().
Gasman went off to write a binhexjs.rb while i forked the sourcecode and aimed for some heavier closure optimization. Half an hour later we merged both our efforts and the final size was now around the 9700 bytes. Success!
Idling with style
Entry finished and submitted! Now all that was left was one whole day of doing a bucketload of nothing.
Saturday morning was completely uneventful.
Saturday afternoon had some interesting talks, most of them in French sadly enough for us poor foreign visitors. Went outside for some beers with old scener friend Flod who was briefly visiting the partyplace. Bastille was of the centers of the Parisian gay parade happening that day, so everything was packed with colorful people and rainbow mayhem. We eventually found a bar and after a couple of beers headed back to DemoJS.
The rest of the afternoon was spent socializing with other foreigners and making some new friends. Mostly drinking beer, explaining the scene to a new musician and waiting for the compos to start. DJ Pie was playing a set but we somehow managed to miss it.
Compos
The organizers came outside to warn us the compos were about to begin. "Everybody in, everybody in, the show is about to begin."
First up were the 1k. Plenty of entries, most of them without music but still mildly interesting. The last to be shown was Matraka, a joint work of p01 and 4mat, blowing all the competition into second league.
Next the 10k, featuring only 3 entries. The first was Reborn by tmp & Adinpsz, a simple terrain generator with some 2d trees, nothing fancy but people seemed to like it. Second up was a co-op by Rift and DSS titled mwwnwormer, a dark side of the moon raytracer with some music using jssonant. The graphics looked pretty good and it quickly became clear they would win the compo. Last up was our entry, Parsley State by TPOLM, there were a couple of bugs showing, but people didn't seem to notice and veemently applauded when it ended. I was pretty confident we would get second place at this point.
Still left to show was the wild compo, only 4 entries, one of them didn't really work due to an unexpected update on chrome. The best one was clearly the Turbo Out Run clone game, even if it didn't have sound.
Last but not least was the demo compo. Not many entries, only 5. A couple of compo fillers and fast made prods. The most polished entry seemed to be BIGintro by The Matadors who oddly to me ended up placed 3rd in the final results. The democompo winner being Burnt by Games From Mars, which was nice but clearly rushed for the compo.
After a quick online voting session final results were presented with a little closing ceremony. We were granted the last place and asked to come on stage. :( I thanked the audience with an important message from the moomin: "Remember to use more parsley when you cook!"
Aftermath
The remaining night was dedicated to uploading the entry online, decompressing and getting some sleep. Next day was travelling back home day. Spent some airport time getting started on this making of report and figuring all the things i had left to do when i arrived home.
Was happy to notice people on pouet seemed to be thumbing up Parsley State. Nice not to get hated on a new release for a change. Even though we still got last place in the compo.
Next day i uploaded the source code to github.
This report was originally posted at The Herring and xDA.
A 10k intro made for DemoJS. (link)
Planning
Following up the disapointment of Cyboman 5 placing so low at Stream i decided to try again with a new javascript intro. I had also recently finished work on the "Under a Seering Sky" javascript game. Another disapointing competiton result, this time from Atparty wild competition. The new target event was DemoJS, a demoparty in Paris focusing on javascript and browser technologies. DemoJS popped up last year sponsored by Mozilla during their 2011 campaign to get more demos for the browser with a few events across the world. Competition would probably be harder but atleast the attending audience would more likely know what they are voting on. Aimed again for pure canvas, no webgl. There are still lots of things on the canvas specification that folks don't seem to be using that much, i wanted to explore that a bit.
There were 4 categories at DemoJS: 1k, 10k, demo and wild. 1k is mostly for 1 trick ponies and it's typical playground for webgl experiments, not what i was looking for. Demo would require a dedicated graphician to work with, so i also set it aside. Wild would have been great for something similar to "Under a Seering Sky", but i was running out of time to make two prods. 10k seemed more appropriate to aim for. So now that i knew the target, what i was missing was a good tune with small size. Fellow TPOLM'er Kaneel was recruited for the job. Our aim was to do a haterztro, sending joyful fuckings to all the folks that enjoy talking shit about us whatever it is we do. Inspiration from the epic B.o.B. track Haterz Everywhere popularized by machine drum on lazy sunday radios of old.
Research and development
Focusing on the 10k category i did some research on available sound apis and concluded we had 4 options to chose from for our plan to world domination to have appropriate sound:
1) bytecode music. Has the advantage of taking much less size, ideal for 1k and 4k. Has the disadvantage of always sounding like crap made my coders fooling around.
2) sonant-js, a javascript port of a softsynth some other sceners been using for native and web 4k intros. Has the advantage of a gui, useful for letting the musicians do the music. Has the disadvantage of generaly sounding overly simplistic. Great for simple pads and melodies, but that has all been done before to exhaustion.
3) ahx replayer, a javascript replayer of the famous ahx amiga sound format. Has the advantage of a well tested tracker gui and established format. Great fun for chiptune / oldschool fetishists.
Has the disadvantage of the replayer being unstable and relatively large in size.
4) jsmodplayer. Has the advantage of the musician being able to use a trackers interface to compose the track and the replayer been around longer then the other options so more likely to be something stable. Has the disadvantage of easily getting too big in size if the musician is careless with selecting his samples and patterns.
In the end we decided to go for AHX. Kaneel felt motivated to try some oldschool chiptune sounds despite having had a little trouble installing the amiga emulator and learning the tracker. I had to crunch any of the players anyways so as long as it sounded good any of the options 2) 3) or 4) would be ok. The choice of AHX had it's drawbacks: mild-high learning curve to learn the format, it's replayer actually emulates some amiga opcodes and can be quite unstable when you're trying to debug things in javascript debugger. But it had sound support for both the webkit audio and mozilla sound api, which is nice, the more browsers supported the better.
Guidelines
1 week before the event we started having some test tunes we were both happy with. We did a couple of interactions of syncing effects and reworking the track a bit. Unconsciously we morphed the original haterztro into something more TPOLM like.
We tried to follow a few basic TPOLM guidelines:
1) being informative
2) featuring tunnels
3) greeting TPOLM
4) being short and to the point
Information on Parsley was added. Unfortunately we had to cancel the second point of compliance with TPOLM technology guidelines. Even though we actually had a tunnel effect working, it was running in much too low framerate to be worth releasing. Greetings featured TPOLM. We focused on the theme keeping it short and not boring.
So the guidelines were more or less followed, further consultancy with our vintage superhero Antti "fthr" Jadertpolm confirmed the authenticity of our alignment. We spent some more iterations polishing colors and lyrics.
Travelling
At some point in time i was spending a bored evening and checked flight prices through ryanair to Paris, it was quite cheap to go from Porto, which i would be visiting at the time, so i booked the tickets on impulse. From that point on i really had to finish something decent to present at the event despite starting to run out of time.
Then, suddenly, just a few days before the event, i heard of a planned air traffic controlers strike being announced for the dates of the event. Confirmed the clash at the Ryanair website, they only mentioned to stay tuned for more information. Unsure if the flights were still flying i carried on polishing the intro with the help and consultancy from kaneel and fthr.
Then, just as suddenly, Portugal lost the semi-finals match of the euro to Spain.
Then, even more suddenly, the air traffic controllers strike was canceled and all flights were announced to be back on schedule. Hooray! The plan to become hopsters in Paris was reinstated once more. I informed the family, swapped meet up information, set my alarm clock and packed my computer bag to go to Paris the next day.
At this point the intro still had some small things needing polish and we were deciding between an easter egg secret part or adding some vector graphics to fill up the remaining space of the intro. We had 500 bytes left to fill up with something.
I met up with Kaneel on Friday afternoon after a long travel without food and we babysitted his daughter for a while, then went shopping for beer and took her for a walk in the park before another party visitor and the babysitter showed up. The afternoon was going by quite fast, the beers also, and we hadn't even made it to the partyplace yet. But it was now just a couple of metro stops away! We exited the metro at Bastille and found our way to ISART, the partyplace.
Party coding
Upon arrival we immediately met some other foreigners and instead of working we continued our hopster beer adventure through the night. After too many beers we finally decided we should probably try to get the intro finished instead of just getting drunk.
We only needed to fix some syncs in the greetings and add the coat of arms graphics, should be easy to do. Right?
Getting a place to setup was easy, everyone was watching a screening of Moleman 2 while we wrestled with the WiFi... It was supposed to exist but it didn't. We needed internet to convert the SVG into canvas code, so we bothered the organizers. After a few hours and a few more beers the internet was working again and a converted version of the SVG was now in place. The intro had just bumped from 9k to 12k. Let the optimizing begin!
Kaneel was playing demo VJ with the big screen while i tried out a few optimization tricks. First manually removing the weird animation junk code from the svg conversion. Then removing some decimals from the bezier curve data. Then removing all decimals from the bezier curve data. Then removing some of the bezier curves themselfs. Just had to make sure the quality was still acceptable.
At some point Kaneel had to leave for home and i took the wonderful opportunity to get some food. Returning to the partyplace most of the people had already gone to sleep. Our intro was still at 11k so I carried on optimizing some more. Next step was removing functionality from the AHX replayer that wasn't beeing used by the track and hacking some functions to generate data instead of using the lookup tables. Still too big.
Compress me beautiful
Re-watched p01's talk on creative coding and size optimization to remember a few tricks. Replacing all Math.floor calls with 0|, dirty trigonometry, function hashing, etc. Function hashing called for some more wrestling with closure compiler to get the intro working again.
After a long night of trying several updates and reverts i was still 500 bytes too big. Trying out JsExe instead of PNGinator would give some better results but still always 40 or 80 bytes too big from the 10240 limit.
I started comparing the code directly with the closure compiler version. I noticed that some optimizations i would do would size down the closure compiled version significantly but have little impact on the final .PNG size. This can be explained by common compression entropy, the compression takes heavy advantage of repeating elements, so the more and longer repeats you have the better it's ratio of compression. When you replace the long repeats for smaller versions you are doing work the compressor would do, and probably doing it in a less optimized way, so you end up losing compression ratio, making your optimizations worthless.
Ofcourse i could just cut the graphics out of the intro and go to sleep, but that would be cheating! I took a couple of breaks to refresh myself and went back at it. But i was still at a dead end, trying some new desperate hacks and the best result i could still get out fo JSexe was 10260. I decided to bug Gasman, asking for his opinion if i should keep trying to optimize the closure compiler to the max hoping that eventually the final size would start also decreasing or try to rearrange data in hopes it would pack better. Gasman took a look at my code and paused at the AHX track loader. I been loading the track by including a base64 encoded version of the track and decoding it on load. Gasman had the idea to replace the base64 with an url encoder. The string would no doubt be longer but the PNG compression should compress it better, also we would be able to replace the 2 functions related to the base64 utf8 decoding with an eval().
Gasman went off to write a binhexjs.rb while i forked the sourcecode and aimed for some heavier closure optimization. Half an hour later we merged both our efforts and the final size was now around the 9700 bytes. Success!
Idling with style
Entry finished and submitted! Now all that was left was one whole day of doing a bucketload of nothing.
Saturday morning was completely uneventful.
Saturday afternoon had some interesting talks, most of them in French sadly enough for us poor foreign visitors. Went outside for some beers with old scener friend Flod who was briefly visiting the partyplace. Bastille was of the centers of the Parisian gay parade happening that day, so everything was packed with colorful people and rainbow mayhem. We eventually found a bar and after a couple of beers headed back to DemoJS.
The rest of the afternoon was spent socializing with other foreigners and making some new friends. Mostly drinking beer, explaining the scene to a new musician and waiting for the compos to start. DJ Pie was playing a set but we somehow managed to miss it.
Compos
The organizers came outside to warn us the compos were about to begin. "Everybody in, everybody in, the show is about to begin."
First up were the 1k. Plenty of entries, most of them without music but still mildly interesting. The last to be shown was Matraka, a joint work of p01 and 4mat, blowing all the competition into second league.
Next the 10k, featuring only 3 entries. The first was Reborn by tmp & Adinpsz, a simple terrain generator with some 2d trees, nothing fancy but people seemed to like it. Second up was a co-op by Rift and DSS titled mwwnwormer, a dark side of the moon raytracer with some music using jssonant. The graphics looked pretty good and it quickly became clear they would win the compo. Last up was our entry, Parsley State by TPOLM, there were a couple of bugs showing, but people didn't seem to notice and veemently applauded when it ended. I was pretty confident we would get second place at this point.
Still left to show was the wild compo, only 4 entries, one of them didn't really work due to an unexpected update on chrome. The best one was clearly the Turbo Out Run clone game, even if it didn't have sound.
Last but not least was the demo compo. Not many entries, only 5. A couple of compo fillers and fast made prods. The most polished entry seemed to be BIGintro by The Matadors who oddly to me ended up placed 3rd in the final results. The democompo winner being Burnt by Games From Mars, which was nice but clearly rushed for the compo.
After a quick online voting session final results were presented with a little closing ceremony. We were granted the last place and asked to come on stage. :( I thanked the audience with an important message from the moomin: "Remember to use more parsley when you cook!"
Aftermath
The remaining night was dedicated to uploading the entry online, decompressing and getting some sleep. Next day was travelling back home day. Spent some airport time getting started on this making of report and figuring all the things i had left to do when i arrived home.
Was happy to notice people on pouet seemed to be thumbing up Parsley State. Nice not to get hated on a new release for a change. Even though we still got last place in the compo.
Next day i uploaded the source code to github.
This report was originally posted at The Herring and xDA.
Making of: Under a Seering Sky
Under a Seering Sky
Under a Seering Sky is a web gamebook about a sci-fi world of cyberpunk hackers struggling to survive under big brother and a zombie outbreak. Click here to play.
Background
While growing up in my teens i used to read a lot of fantasy. In fact i almost had the complete series of Fighting Fantasy books. Used to spend evenings locked in my room with multiple fingers of one hand marking different pages on the book while the other hand would cheat a frustrated dice roll and pretend my 7/12 character was actually good enough to beat a 12/10 giant worm or something.
The imaginary of those books had a certain call and fascination about them. When i began coding on the ZX Spectrum one of the first games i developed was a haunted mansion interactive fiction type of game. I didn't actually like playing that genre of games, I recall trying to play The Hobbit on the Spectrum and never getting very far. But i had just learned coding BASIC so the graphics of the good games was still unachievable. These kind of text based games were the ones i could invest my creativity into.
When i got a PC and started learning Turbo Pascal on MS-DOS, again those where the kind of games i developed before i started programming graphics. They were all crap, and i'm unsure if any copies of them are left anywhere, but i made them, they were mine, i invented the story, i invented the monsters, i decided the plot, i decided how the player would die! And that was a great feeling i had back then, the feeling i could create other worlds for people to explore.
I never played Zork, I liked graphic adventures much better. I disliked the interface of the first Leisure Suit Larry, where you had to figure out what you're supposed to type. It was impossible for anyone to know all the possible interactions, and that just made it frustrating. Clicking on things made much more sense. I disliked the Quest series, mostly because you could randomly die at any point. I disliked Goblins III for the exact opposite reasons, you couldn't die but you also couldn't progress, you would just get stuck in the same screen clicking everywhere you could think of clicking and not really making any progress anyways. That didn't feel like a game, it felt like bruteforce. It was equally frustrating.
When i got more into computer stuff i discovered the so called cyberpunk genre through different games and movies. Mostly Dreamweb made a big impact in me. It was very graphic and raw, the ambience it created was superb. Ghost In The Shell anime was also a big influence. Around 1997 i wrote a sci-fi short novel which i later converted into a movie script. My goal was to make it into an animated movie some day. It got thrown into some backup cds encrypted with a password i probably don't even remember anymore. I abandoned writing and focused on learning how to produce music.
Years later, in 2012, i find myself paying less attention to music and wanting to take on writing again. One night, out of insomnia and without putting too much premeditation into it i write the first chapter of Joey Crass, a sci-fi short novel about a depraved and socially inept hacker kid living in a messed up world where artificial intelligence controls society and a zombie outbreak is happening. Joey has to earn his credits by running illegal hacker missions online, most of them with zombies who got chip hacked. Guess i was inspired by having read The Walking Dead recently.
I wrote a couple more chapters, revised them abit and sent them to a few graphician friends of mine with the intent of trying to make a comic out of it. They ofcourse ignored the email or told me it was too much work. One of them told me it reminded him of Neuromancer. I had never actually read Neuromancer before, believe it or not. Only had read the 1 chapter comic adaptation of it. So i actually borrowed a copy of the book soon after and decided to take care of that. Great book.
Development
A month ago i noticed a competition for Interactive Fiction (IF) entries at a demoparty in Boston. I recalled the old days and decided it might be cool to have a go at it. In fact, ever since having seen the Get Lamp documentary and played Nullsleep's Void Gaze that i had been yearning to do something in that area again. I did not want to make a typical get lamp go north go east open door eat grue kind of thing though, so i immediately started thinking on how to enhance the experience.
I had been trying out some things with Dan involving javascript canvas element, so i thought "wouldn't it be interesting to include animation graphics on the game?", to represent the state of mind somehow. We could have those instead of the occasional illustrations that these games usually have.
I took a look at Inform 7 and if it could be made to work on a browser. It can, but i felt like i was learning a new "natural" programming / scripting language especially for the project. It felt stupid. Plus i considered it would be hard to hack these libraries to combine it with other javascript things i was envisioning such as playing sound, canvas animations, complex puzzles, etc. So i dropped the idea of a traditional interactive fiction using Inform 7 and thought of a gamebook style of interaction instead.
I wasn't even aware these things were called gamebooks at this point, didn't even knew computer games based on this system existed, but i figured it probably did so i looked it up. Some research online made me realize there was actually a strong community of folks who had migrated the definition of a gamebook into a computer game genre. There was also an ongoing dispute within IF circles discussing if gamebooks are considered "real" IF. Some claim "real" IF requires a world and language parser, or atleast having puzzles instead of pure plot branching. Now, if you know me, you should be aware of what my thoughts are on any "real" definitions of anything. I don't care much for them. I just want to make something cool with my ideas. Categories are good for references, not to serve as bounding boxes.
So now apparently i was developing an IF / Gamebook for the browser. "How can it be improved with todays technology?" That was my challenge. Compared to standard IF, i could easily do more advanced things with state machines, variables and algorithms than if using a standard language parser. And compared to gamebooks, i could also do more complicated puzzles and interactive things. Having a programming language to abuse that books never had. Even modern videogame adaptations of the gamebook genre tend stick to those deprecated formulas of rolling dice and entering your paragraph. It might have a certain nostalgia charm to it but it completely wastes the potential of the platform, which in my case was the modern day browser. Of course different folks have different motivations to chose their battle grounds, and they might be just as valid for them as these are for me, but these were my own reasonings and ethos for action.
I wanted to do something immersive, something that didn't explain itself to the reader. I always preferred those kind of scenarios, the kind where things aren't explained to you and you just have to explore your way around to start to make sense of it all, to figure out the rules of the game. At the same time i wanted to do something that could be finished victoriously on a first attempt. Provided the reader was careful enough while playing ofcourse. Might not happen for some folks, but i tried not to make it completely random choice, always giving a slight hint to the right course of action.
So i got started work on a new story, based on the world of Joey Crass. Developing a storyline as more forks were branched. Eventually i came up with the koreans situation. I then decided to focus chapter 1 on escaping the koreans. Chapter 2 on unveiling the world and thickening the plot. And chapter 3 was left for the conclusion. I must confess i ran out of time on chapter 3 so the ending was a bit sloppy. Might still improve that at some point. Revising chapters 1 and 2 with more graphic animations and soundtrack felt more important at the time.
Wanted to keep the graphic animations abstract, not use actual illustrations. The idea was to let the user imagine the world for themselves instead of showing it to them. That is what sets the literature and game worlds apart after all, the former always leaves more room for the reader to imagine how things are, the latter aims for immersion.
Adapted two libraries to run with the project. The first one StripThis by KesieV, an awesome webcomic tool, which was used to picture an instant messaging interface in the game. The second MetaGenHaiku, a javascript generative haiku system developed by myself a few years ago. This was used to create generative haikus which were used as part of a puzzle in the game.
As the project was being developed i was tweeting about it and got some folks curious about the project. I sent a few mails and got help from Dan, Antti and Timo to polish things up. Also asked Havoc to deliver the entry at the partyplace to earn a few extra days for development. Finally finished things up the best way i could. And waited for the competitions to show on the party stream at scenesat.
The entry was shown in the wild competition. The audience seemed interested with it and clapped in the end, so things were looking good.
Aftermath
The day after the compos i got a mail saying the entry was disqualified. I mailed them back asking why, tried catching the orgas at irc, no reply. Later on got another mail saying i was undisqualified, "but just barely", still not mentioning why. I dismissed it on organizers being busy organizing and waited for the compo results. Looking back it might as well had gotten disqualified since it ended up being placed last in the compo. Was quite a disapointing outcome after all the time i invested in it.
On the bright side i got a few people playing it who told me they loved it. That motivated me to iron out a few bugs, add support for Safari, place it online and announce it as an Enough Records experiment. For those who don't know Enough Records is the netlabel i curate and where 90% of the soundtrack from Under a Seering Sky was taken from.
The source code is available at github.
This report was originally posted at The Herring and xDA.
Under a Seering Sky is a web gamebook about a sci-fi world of cyberpunk hackers struggling to survive under big brother and a zombie outbreak. Click here to play.
Background
While growing up in my teens i used to read a lot of fantasy. In fact i almost had the complete series of Fighting Fantasy books. Used to spend evenings locked in my room with multiple fingers of one hand marking different pages on the book while the other hand would cheat a frustrated dice roll and pretend my 7/12 character was actually good enough to beat a 12/10 giant worm or something.
The imaginary of those books had a certain call and fascination about them. When i began coding on the ZX Spectrum one of the first games i developed was a haunted mansion interactive fiction type of game. I didn't actually like playing that genre of games, I recall trying to play The Hobbit on the Spectrum and never getting very far. But i had just learned coding BASIC so the graphics of the good games was still unachievable. These kind of text based games were the ones i could invest my creativity into.
When i got a PC and started learning Turbo Pascal on MS-DOS, again those where the kind of games i developed before i started programming graphics. They were all crap, and i'm unsure if any copies of them are left anywhere, but i made them, they were mine, i invented the story, i invented the monsters, i decided the plot, i decided how the player would die! And that was a great feeling i had back then, the feeling i could create other worlds for people to explore.
I never played Zork, I liked graphic adventures much better. I disliked the interface of the first Leisure Suit Larry, where you had to figure out what you're supposed to type. It was impossible for anyone to know all the possible interactions, and that just made it frustrating. Clicking on things made much more sense. I disliked the Quest series, mostly because you could randomly die at any point. I disliked Goblins III for the exact opposite reasons, you couldn't die but you also couldn't progress, you would just get stuck in the same screen clicking everywhere you could think of clicking and not really making any progress anyways. That didn't feel like a game, it felt like bruteforce. It was equally frustrating.
When i got more into computer stuff i discovered the so called cyberpunk genre through different games and movies. Mostly Dreamweb made a big impact in me. It was very graphic and raw, the ambience it created was superb. Ghost In The Shell anime was also a big influence. Around 1997 i wrote a sci-fi short novel which i later converted into a movie script. My goal was to make it into an animated movie some day. It got thrown into some backup cds encrypted with a password i probably don't even remember anymore. I abandoned writing and focused on learning how to produce music.
Years later, in 2012, i find myself paying less attention to music and wanting to take on writing again. One night, out of insomnia and without putting too much premeditation into it i write the first chapter of Joey Crass, a sci-fi short novel about a depraved and socially inept hacker kid living in a messed up world where artificial intelligence controls society and a zombie outbreak is happening. Joey has to earn his credits by running illegal hacker missions online, most of them with zombies who got chip hacked. Guess i was inspired by having read The Walking Dead recently.
I wrote a couple more chapters, revised them abit and sent them to a few graphician friends of mine with the intent of trying to make a comic out of it. They ofcourse ignored the email or told me it was too much work. One of them told me it reminded him of Neuromancer. I had never actually read Neuromancer before, believe it or not. Only had read the 1 chapter comic adaptation of it. So i actually borrowed a copy of the book soon after and decided to take care of that. Great book.
Development
A month ago i noticed a competition for Interactive Fiction (IF) entries at a demoparty in Boston. I recalled the old days and decided it might be cool to have a go at it. In fact, ever since having seen the Get Lamp documentary and played Nullsleep's Void Gaze that i had been yearning to do something in that area again. I did not want to make a typical get lamp go north go east open door eat grue kind of thing though, so i immediately started thinking on how to enhance the experience.
I had been trying out some things with Dan involving javascript canvas element, so i thought "wouldn't it be interesting to include animation graphics on the game?", to represent the state of mind somehow. We could have those instead of the occasional illustrations that these games usually have.
I took a look at Inform 7 and if it could be made to work on a browser. It can, but i felt like i was learning a new "natural" programming / scripting language especially for the project. It felt stupid. Plus i considered it would be hard to hack these libraries to combine it with other javascript things i was envisioning such as playing sound, canvas animations, complex puzzles, etc. So i dropped the idea of a traditional interactive fiction using Inform 7 and thought of a gamebook style of interaction instead.
I wasn't even aware these things were called gamebooks at this point, didn't even knew computer games based on this system existed, but i figured it probably did so i looked it up. Some research online made me realize there was actually a strong community of folks who had migrated the definition of a gamebook into a computer game genre. There was also an ongoing dispute within IF circles discussing if gamebooks are considered "real" IF. Some claim "real" IF requires a world and language parser, or atleast having puzzles instead of pure plot branching. Now, if you know me, you should be aware of what my thoughts are on any "real" definitions of anything. I don't care much for them. I just want to make something cool with my ideas. Categories are good for references, not to serve as bounding boxes.
So now apparently i was developing an IF / Gamebook for the browser. "How can it be improved with todays technology?" That was my challenge. Compared to standard IF, i could easily do more advanced things with state machines, variables and algorithms than if using a standard language parser. And compared to gamebooks, i could also do more complicated puzzles and interactive things. Having a programming language to abuse that books never had. Even modern videogame adaptations of the gamebook genre tend stick to those deprecated formulas of rolling dice and entering your paragraph. It might have a certain nostalgia charm to it but it completely wastes the potential of the platform, which in my case was the modern day browser. Of course different folks have different motivations to chose their battle grounds, and they might be just as valid for them as these are for me, but these were my own reasonings and ethos for action.
I wanted to do something immersive, something that didn't explain itself to the reader. I always preferred those kind of scenarios, the kind where things aren't explained to you and you just have to explore your way around to start to make sense of it all, to figure out the rules of the game. At the same time i wanted to do something that could be finished victoriously on a first attempt. Provided the reader was careful enough while playing ofcourse. Might not happen for some folks, but i tried not to make it completely random choice, always giving a slight hint to the right course of action.
So i got started work on a new story, based on the world of Joey Crass. Developing a storyline as more forks were branched. Eventually i came up with the koreans situation. I then decided to focus chapter 1 on escaping the koreans. Chapter 2 on unveiling the world and thickening the plot. And chapter 3 was left for the conclusion. I must confess i ran out of time on chapter 3 so the ending was a bit sloppy. Might still improve that at some point. Revising chapters 1 and 2 with more graphic animations and soundtrack felt more important at the time.
Wanted to keep the graphic animations abstract, not use actual illustrations. The idea was to let the user imagine the world for themselves instead of showing it to them. That is what sets the literature and game worlds apart after all, the former always leaves more room for the reader to imagine how things are, the latter aims for immersion.
Adapted two libraries to run with the project. The first one StripThis by KesieV, an awesome webcomic tool, which was used to picture an instant messaging interface in the game. The second MetaGenHaiku, a javascript generative haiku system developed by myself a few years ago. This was used to create generative haikus which were used as part of a puzzle in the game.
As the project was being developed i was tweeting about it and got some folks curious about the project. I sent a few mails and got help from Dan, Antti and Timo to polish things up. Also asked Havoc to deliver the entry at the partyplace to earn a few extra days for development. Finally finished things up the best way i could. And waited for the competitions to show on the party stream at scenesat.
The entry was shown in the wild competition. The audience seemed interested with it and clapped in the end, so things were looking good.
Aftermath
The day after the compos i got a mail saying the entry was disqualified. I mailed them back asking why, tried catching the orgas at irc, no reply. Later on got another mail saying i was undisqualified, "but just barely", still not mentioning why. I dismissed it on organizers being busy organizing and waited for the compo results. Looking back it might as well had gotten disqualified since it ended up being placed last in the compo. Was quite a disapointing outcome after all the time i invested in it.
On the bright side i got a few people playing it who told me they loved it. That motivated me to iron out a few bugs, add support for Safari, place it online and announce it as an Enough Records experiment. For those who don't know Enough Records is the netlabel i curate and where 90% of the soundtrack from Under a Seering Sky was taken from.
The source code is available at github.
This report was originally posted at The Herring and xDA.
Making of: Cyboman 5
Dealing with advanced technology from the future can quickly become complicated, with this in mind the planet of leather moomins intergalactic conspiracy empire, whose sole Portuguese member happens to have co-founded the xDA medialab hackerspace, has emmited this special report about the making of their latest hit single 4k: Cyboman 5 (link).
Step 1) chose your compo wisely
If you are not aware where to find running compos you should consult the internet and for example follow demoparty.net for a listing of recent events on the so called demoscene, several competitions will be provided for you.
For Cyboman 5, the Stream Tiny Intro Compo was selected as target. Once your target is obtained you can have strategic advantages by consulting results from editions of the event and procuring information on what other groups are planning to develop. If you do a careful analysis you may be able to obtain several bonus points and achievement unlocks.
Step 2) select your weapon of mass destruction
To ensure world domination you need to have a weapon. several mixes and dance tracks have been put together in the past, but none can outrun or equal the power of megablast. you should refrain from selecting a weapon of mass destruction you are not very familiar with. this might cause you to waste time dealing with language and operational logistics rather then focusing on the actual extermination of all resistance.
In the case of Cyboman 5 our weapon of mass destruction was javascript canvas. Most players seem to prefer the abuse of shaders under WebGL, or facilitate their byte crunching work with native toolchain compilers. Our objective with Cyboman 5 was to push javascript native capabilities (no WebGL wanking), this ensures higher machine and browser compatibility at the expense of some mindcandy tricks. Finding a creative escape to non sensical limitations is also part of the planet of leather moomins survival ethos.
Step 3) effects
Having a wide range of effects available at hand is always essential for a successful world domination attempt. The typical TPOLM world domination consists of tunnels. I wanted to escape that cliché and focused on doing basic 2D canvas experiments for later complexification.
I developed a total of 10 different effects before even considering a concept or finding a music for the entry. Simple experiments including shape animations, rotozoom, Generative color complementors, repeating text to be used as texture, motion blur, plasma filters, alpha transparency tests, etc.
Step 4) music
Music is one of the key elements of a successful world domination. Good connecting music makes or breaks an entry. Since i was aiming at the tiny intro competition, the most simple way to have music would be to code some.
Luckily for me several experiments with tiny audio code have been done and publically documented. Most of them based on the work of Viznut and a certain pouet.net thread. Online javascript players provided a platform for testing ideas and some sourcecode ready for crunching.
Additionally to the tiny music player a speech synthizer was also used, mostly copy pasted from work of p01.
Step 5) concept
One trick ponies are usually boring. And most tiny intros are usually one trick ponies. Real world domination comes from using your restrictions to break this cliché and do something else.
So after a few audio experiments a concept was developed. Something overly energetic, ahead of it's time, with a technologically advanced mentality. Counterpointing the technologically advanced we have as comic relief the unavoidable fact that it is running on a mundane platform and based on simple 2d graphic effects abusing overlays in an over-complexified manner to produce a more murky, raw and industrial visual approach to connect with the sound.
Cyboman is a series of DOS intros from the 90s, done by different groups at different times, all of which claiming to be technologically advanced, some taking it more seriously then others. A newschool joke sequel to this concept felt appropriate, and so the entry was named Cyboman 5 and introduced as not being titled Cyboman 6.
Step 6) crunching
Crunching your code is the most important part of developing a tiny intro. Some golfing skills are required but not strictly mandatory. For this intro the original source code was 11k long. A few simple size optimizations made, plenty of room to optimize further. A minified version was then packed with UglifyJS to make the code 8k big. Still with plenty of room for further optimization, UglifyJS is good and fast compared to other minifiers out there but still leaves lot of room for manual optimization.
At this point you could pack your intro further, either manually or with actual packers that eval the packed string to self-execute your packed code. But recently there has been some work by Daekan, p01 and Gasman on a PNG self-executable which i wanted to give a try. So i gave Gasman's pnginator a go and managed to have it down to 4k without requiring much further manual optimization.
Step 7) presentation and aftermath
Last step on our journey for world domination was to deliver the entry and make sure it got played properly. The submission system as Stream 2012 wasn't actually working, so i resorted to mailing a link to the organizers and confirming they had received my entry before the compo started.
Entry was played halfway in the compo, music volume too low, mild clapping at the end. Was abit disapointed that people didn't seem to really get into it at all. A few other entries played after mine and got a better public response, so world domination became a dimmer possibility. Personal feedback from other attenders was positive, ranging from borderline indiference to best of compo.
Links
online
sourcecode @ github
pouet.net
This report was originally posted at The Herring and xDA.
If you are not aware where to find running compos you should consult the internet and for example follow demoparty.net for a listing of recent events on the so called demoscene, several competitions will be provided for you.
For Cyboman 5, the Stream Tiny Intro Compo was selected as target. Once your target is obtained you can have strategic advantages by consulting results from editions of the event and procuring information on what other groups are planning to develop. If you do a careful analysis you may be able to obtain several bonus points and achievement unlocks.
Step 2) select your weapon of mass destruction
To ensure world domination you need to have a weapon. several mixes and dance tracks have been put together in the past, but none can outrun or equal the power of megablast. you should refrain from selecting a weapon of mass destruction you are not very familiar with. this might cause you to waste time dealing with language and operational logistics rather then focusing on the actual extermination of all resistance.
In the case of Cyboman 5 our weapon of mass destruction was javascript canvas. Most players seem to prefer the abuse of shaders under WebGL, or facilitate their byte crunching work with native toolchain compilers. Our objective with Cyboman 5 was to push javascript native capabilities (no WebGL wanking), this ensures higher machine and browser compatibility at the expense of some mindcandy tricks. Finding a creative escape to non sensical limitations is also part of the planet of leather moomins survival ethos.
Step 3) effects
Having a wide range of effects available at hand is always essential for a successful world domination attempt. The typical TPOLM world domination consists of tunnels. I wanted to escape that cliché and focused on doing basic 2D canvas experiments for later complexification.
I developed a total of 10 different effects before even considering a concept or finding a music for the entry. Simple experiments including shape animations, rotozoom, Generative color complementors, repeating text to be used as texture, motion blur, plasma filters, alpha transparency tests, etc.
Step 4) music
Music is one of the key elements of a successful world domination. Good connecting music makes or breaks an entry. Since i was aiming at the tiny intro competition, the most simple way to have music would be to code some.
Luckily for me several experiments with tiny audio code have been done and publically documented. Most of them based on the work of Viznut and a certain pouet.net thread. Online javascript players provided a platform for testing ideas and some sourcecode ready for crunching.
Additionally to the tiny music player a speech synthizer was also used, mostly copy pasted from work of p01.
Step 5) concept
One trick ponies are usually boring. And most tiny intros are usually one trick ponies. Real world domination comes from using your restrictions to break this cliché and do something else.
So after a few audio experiments a concept was developed. Something overly energetic, ahead of it's time, with a technologically advanced mentality. Counterpointing the technologically advanced we have as comic relief the unavoidable fact that it is running on a mundane platform and based on simple 2d graphic effects abusing overlays in an over-complexified manner to produce a more murky, raw and industrial visual approach to connect with the sound.
Cyboman is a series of DOS intros from the 90s, done by different groups at different times, all of which claiming to be technologically advanced, some taking it more seriously then others. A newschool joke sequel to this concept felt appropriate, and so the entry was named Cyboman 5 and introduced as not being titled Cyboman 6.
Step 6) crunching
Crunching your code is the most important part of developing a tiny intro. Some golfing skills are required but not strictly mandatory. For this intro the original source code was 11k long. A few simple size optimizations made, plenty of room to optimize further. A minified version was then packed with UglifyJS to make the code 8k big. Still with plenty of room for further optimization, UglifyJS is good and fast compared to other minifiers out there but still leaves lot of room for manual optimization.
At this point you could pack your intro further, either manually or with actual packers that eval the packed string to self-execute your packed code. But recently there has been some work by Daekan, p01 and Gasman on a PNG self-executable which i wanted to give a try. So i gave Gasman's pnginator a go and managed to have it down to 4k without requiring much further manual optimization.
Step 7) presentation and aftermath
Last step on our journey for world domination was to deliver the entry and make sure it got played properly. The submission system as Stream 2012 wasn't actually working, so i resorted to mailing a link to the organizers and confirming they had received my entry before the compo started.
Entry was played halfway in the compo, music volume too low, mild clapping at the end. Was abit disapointed that people didn't seem to really get into it at all. A few other entries played after mine and got a better public response, so world domination became a dimmer possibility. Personal feedback from other attenders was positive, ranging from borderline indiference to best of compo.
Links
online
sourcecode @ github
pouet.net
This report was originally posted at The Herring and xDA.
Preface
I've been doing some javascript audiovisual experiments for a few years. In November 2012 me and Dan Peddle gave a shared talk at Sapo Codebits titled "Javascript Canvas Audivisual Light and Magic" and it featured some thoughts and examples of what kind of demos you can do with javascript on the browsers. It's not comprehensive. I'm no guru of the matter. But i do have some things to share which might be worth reading. And thus this blog was born.
Subscribe to:
Posts (Atom)