256b intros round-table
Tiny intros are the latest fashion in the scene. 2008 has seen a lot of releases sized 256 bytes or even less. This article focuses on what's it like producing such intros and what's different from making larger scene productions. I've interviewed six coders to get answers to these questions.
First a bit about the history of tiny intros. Originally there were just demos in the PC scene, often small, but in general, without a size limitation. The first PC scene competition with a size limitation I know of was a 100-kbyte-intro competition at Assembly 1993. This compo category could also be found at some other parties up until 1996. At The Party 1993 and some other parties there was a 80 kb intro compo, and at the OSO meeting 1994, there was a 32 kbyte intro compo. It was Assembly 1994 that introduced the two main intro categories that have existed until today: 64k and 4k intros.
But the scene cried for competition with even smaller size limitations that would enable coders to concentrate on optimizing single effects. The first 256 byte intro competitions came up in 1996. On the IRC channel #coders, there was a fire effect in 256 bytes competition. In the same year, 256b intro compos were also held at an Italian and a Canadian scene event. In the following years, it was especially Hungarian, Czech/Slovak and Russian parties that used to have competitions for intros sized 256 bytes or even less. Many tiny intros are however also released outside of party competitions just for fun. There is a website dedicated to 256b intros, it's called 256b.com. There you can download an archive with 478 intros, sized about 2.3 MB. At another website, HardCode, you can download an archive with 43.2 MB of intros sized 4k or less for various platforms.
Now let's come to the interviews. Baze, Digimind, Rrrola and Pirx are coders who are mostly known for their tiny intros sized 256 bytes or even less. Baze's best known works are "Tube" and "Lattice". Digimind's most famous works are "Demoplex" (a ray-poly intersection test) and "Color Dream" (128b, a fractal animation of a modified Mandelbrot set). His most recent work is "Neon Station", from March 2008. Rrrola made several extremely tiny 32b intros and a couple of slightly bigger ones, one of his latest works being the 128b "vyhen". One of Pirx's works is the 256b intro "Phobia", which he made together with Tigrou. Optimus has a history of small intros, too. His most recent work is "Plasma128". Seven has also recently released a 128 byte intro, "picky", which came second in the combined 128b compo at Outline 2008.
What is it like working on a 64b/128b/256b intro?
It's a fun exercise in math and 3d unlike larger projects. Something like solving a quick crossword puzzle.
Building small worlds that fit in an "invisible" space. That feeling..
Well, actually sometimes it gets frustrating for me because I can't get motivation to use those extra bytes left and I am more motivated by speed optimization in general than size, especially when I know there is nothing wrong with few or less additional bytes with the huge space available. But I guess I am missing the point here :)
Also it's the lonely coder's last resort. And a nice way to release something in an evening without planning/working for months or requesting art/music.
Coding an extremely small intro is like having sex with a virgin.
It's a major pain. ;-) The x86 in 16-bit mode is space-efficient, but weird. Everyhing can be coded in many ways (with different side effects) and you keep running out of registers. I learned to love the addressing, the carry flag magic and all the funny instructions (imul, aad, rcr, loopnz...). Also, the FPU is like a different world.
I've only made a single 128 byte intro, but the experience is quite similar to the old assembler fast-coding compos at parties: you have a clear idea about what you need to see on the screen and you must use all your creativity to fit it in a very small size. The space is so limited that you can't use compressors such as crinkler or apack, so you can't use those to improve inefficient code. Without compressors, you know beforehand how much space each instruction will take up exactly, so you can abuse exotic instruction combinations to do unexpected stuff. So it's a fight between you and your idea on the one side, and the instruction set on the other.
What is your approach to coding a tiny intro? Do you first code something and then see if you can make it fit the size-limit or do you have another approach?
It depends. Sometimes the idea breaks down to a sequence of assembly instructions quite naturally and the only thing left is to squeeze as much "eye candy" you can from the remaining bytes. More often though you are left with unpleasing visuals and a piece of code well above the size limit. It can take even several weeks of careful examination, tweaking and brainstorming to get rid of those 50 or 100 extra bytes. And I really mean brainstorming - asking for the help of your fellow code mates is about the best thing you can do. Single person gets stuck with one particular way of thinking too easily. Generally, it is also a good idea to write a simple prototype app in C just to see if your concept works.
When I have an idea, I usually write simple C++ code to see if it works at all. The size can be estimated quite early - if the core algorithm cannot be represented in few lines of high-level code then it's not worth trying :)
By the way, most development is in C++, which means easy tweaking and debugging. Writing a simple class to emulate CPU instructions, registers, stack, memory and FPU really pays off - it makes the transition from C++ to Assembler easy, one line at a time. For example, you change a += b; to add(ax, bx); this is still C++, and then, after all lines are converted and everything is ok, just erase the parentheses. :)
No, I plan what could fit in say 256b and go for it directly. Maybe in the process I bump over the 256b limit for few tens of bytes or so and then try to get under. But it never occurred to me to start a regular effect in asm without thinking of the size and reach something like 600 bytes and then decide to push it for size. Of course, if an effect is new for me, I try first to make it work in a C compiler and then think of how could i squeeze it in an asm intro. Only lately it occurred to me to accidentally produce some nice things in a C compiler and think about port it back to a tiny intro. Maybe soon..
Generally I have the feeling which ideas can be accomplished as 128B/256B productions. At first, the effect is implemented without optimizations, tools like Evaldraw or C compiler are often used - after achieving all visual features byte-crushing mode is activated. A good 256B intro is the one which initially has about 300 bytes of optimized code and you don't see the obvious way to make it smaller. Of course there are exceptions, in CLITORIS we had too much free space, and you can try to find the hidden part in this intro.
I start with a bunch of nice routines I'd like to use someday and an effect in C. Then I convert it to assembler and optimize it to death. As we're getting to know each other, I usually discover something unforgivable about the algorithm and start from scratch, storing away the routines I like. ;-)
When I start to feel that it can't be improved, I let it lie for a few weeks (party coding doesn't work for me). The hardest part is to admit there's no way to reduce the size further and sacrifice a part of the effect. But in the end I just convince myself that it looks better that way.
Seven: Yes, you typically start with running code that is too big, and then you start byte-hunting and looking for corners you can cut without sacrificing too much of the original. When you start, you may not know if it's possible at all to get to the required size, and your expectations may swing around between "This will be a piece of cake" and "I'll never get this small enough". It feels really great to finally remove those last 1 or 2 bytes from an effect that you doubted could fit in the size limit. Don't give up too soon, sometimes a good night's sleep and a fresh look at the code can give you that final idea you needed.
How is it different from working on a demo or a 64k intro?
The obvious difference is the size limit. Not only can't you afford any precomputed data but you also spend considerable amount of code just to be able to initialize your rendering environment and to generate some interesting textures and palettes. Perhaps the unwritten rule of 256b programming is "reuse every number you can", including the use of code itself as a data. Also, programmers often prefer brute-force approach in their algorithms since they can't afford those few extra bytes for optimization. This is not the case in demos and intros where you usually don't have to sacrifice code size for speed to such extent. What is considered a clever trick in 256b would be called a nasty hack in every other piece of code, and rightly so :) One can also notice slightly different types of effects being presented - since polygon rasterization is difficult in 256 bytes, programmers often opt for fractals, ray casting and cellular automata.
Tiny intros are quite specific on the scene - you can't offer any nice-looking visuals, not to mention the music, so there has to be something else to make them interesting at all. That's why I try to make such intros at least somewhat impressive (I hope) from the technical point of view - and that's the minimum requirement.
It's like building unique small worlds that fit a bit less or more than this line of text.
It's like the last resort for me to write X86 assembly and VGA coding, when there is no need or actual motivation/dedication to do this in a big demo anymore.
It's like an easy way to release something that might be appreciated, without the tons of graphics, without the need of music or some special design. It's good when you are a lonely coder and still want to have a part in the scene without necessarily belonging to an active group.
I don't know, I have never worked on bigger productions. Patience, precision, passion, skills - I think all these attributes are as important for making tiny masterpiece as for creating a great demo, but during tiny intro development the main effort isn't concentrated on direction, music, sync etc., but on the code. 256B is the art of the code.
Compression and (collapsed) Windows headers start making sense around 512b, so you're stuck with your brain and mode 13h (say goodbye to shaders). I haven't found the patience for a larger prod yet - most of my intros are around 6k in gcc/mingw before switching to asm. :-)
I can't speak about 64K intros (never did one yet), but in a demo there's no question about whether something is possible to do in code. You have all the space you want, so it's more a matter of having enough time to code it, and maybe about having it run fast enough. The code in a demo is also less important, in the sense that there is music and 3D or 2D art to flesh out your production, while a micro intro is 100% code. Another nice point of micro intros is that, since they are maybe 100 assembler instructions at most, you can easily start again to try out a completely different approach to the same effect. In a demo, you may notice there is something non-optimal in the code, but you keep it in anyway because too much other code depends on it.
Where do you get the ideas for your intros from?
There are many sources to draw inspiration from. Sometimes I just reuse the old tricks of our demoscene forefathers but often I run into something while googling. There are many interesting web sites dealing with computational art, shader programming, fractals or 3D surfaces. The longer you deal with 3D graphics, the easier it is for you to spot something that could serve as a good basis for an intro. Still, getting a good idea is hard work for anyone. The core math must be advanced yet simple. It must allow for a variety of tweaks and adjustments. You have to strip the idea to the very core and to think of creative ways of presenting it in an appealing and even surprising way, often taking advantage of various coding tricks and symmetries.
There is a great deal of suboptimal stuff surrounding us. When I see such examples with lots of resources being wasted, I usually come up with some obvious solution how to impove it. Sometimes this can have a visual interpretation.
And finally, there is one thing I constantly encountered - sometimes significant size-saving opportunities come up out of nowhere - the ones I would never expected before actually trying. So here is my advice for tiny intro coders: don't think if it's possible or not - just try it.
Primarily watching other intros and thinking how could I do this better or differently. Or wondering what hasn't been done in a tiny intro yet. Or lately by coding something in a C compiler that I see it could fit nicely in 256b and would rule (just wait for that :)).
Ideas for small intros come from various sources, most of them are spontaneous projects. For example, my first released intro is extended in contents and shrinked in size result of some trivial task on studies, the concept for the latest 256B cracktro struck me when I was bored at work. The most impressive intros from ind, like KOBRA or PHOBIA, are brainchildren of Tigrou, who is a better mathematician than me.
I've started with classical intro effects (cellular automatons, fractals...), but realized that they're mostly simulations of nature, so I'm just looking around. The actual algorithms are mostly by-products of CG research, enhanced by lucky discoveries. I also like interactivity if it doesn't hinder the effect.
But sometimes I just get angry and optimize someone else's intro.
Other demos, the internet,... there are a million effects that I haven't done yet or don't know yet how to do, and you can always put a personal spin on an existing effect. Coding tricks can be learned by checking out other people's productions: the source code for this type of gems is released far more often than for demos/64k intros, and even if it's not, they are quite easy to run through with a debugger.
Links related to this article
All releases of 3sc (Baze's group)
All of Digimind's releases
All releases of ind (Pirx's group)
All of Optimus' solo releases
All of Rrrola's releases
All releases of Fulcrum (Seven's group)