How Did Game Developers Pack Entire Games into so Little Memory Twenty Five Years Ago?

04/22/2013 11:26 am ET | Updated Jun 22, 2013

This question originally appeared on Quora. 2013-04-22-rbaba.jpeg Answer by Razvan Baba, electronics engineer

Assembly writing - very efficient, ultra-compact code size. Essentially, you are directly instructing the chip what to do.

  • Music generated on the fly, not stored. Midi is a good example, but it still uses a lot of data. If we chop down the number of available voices and pair it with some generation assembly lines of code, you could generate thousands of hours of music at the cost of CPU power.
  • Unorthodox lossy data compression algorithms - tailored for only a certain kind of data - sprites, bitmaps, etc. These are the kind of broken programs that you think they work, but fail miserably when you change the data set. perhaps they did discover them by accident, other times it is pure brilliance.
  • Reliance on hardware - computers rarely came with sound cards, but when they did, sound cards where very complex synthesizers in their own way, with their own sound generation packages on a chip. Now this is done mostly software.
  • Tricking your brain: pseudo 3D effects can be achieved by scrolling 2D images at various rates. 2.5D (usually in the 90s) can leave a believable impression if done right, but true 3D was limited to wireframe models. Here's an idea of how a 2.5D Mario Brothers would look like (note: cubes are 3D. The 2D textures may rotate to face the player.):

  • Lotus Esprit Challenge. Looking as bonkers as the real thing:

    an example of parallax scrolling that simulates perspective

  • In order to absolutely limit the program size, one would avoid the use of arrays, constants, and other fixed data as much as possible. However, often more complex computations are required, so it would have been a compromise with raw speed. The following table shows a period of a sin(x) function with 120 sample points converted to output hex: 0x00 - 0xFF

  • Linked lists, draconian stack management, every addressed bit accounted in the memory. Remember that there were no useless classes, objects, automatic memory allocation. Pointers were your friend.

  • Building your own libraries from the ground. Oh, that abs() function accounts for too much stuff! Ok, I don't care if a pixel appears black instead of gray if the program is 6B smaller.
  • 8 bit data path attracts less slack space due to more efficient memory management. When you need to address 8bit at a time and you only need 3, you only loose 5 bits, not 27 for a 32bit cpu. Same reason why 64bit executables are nearly always larger than the 32bit ones. Also when you have a bitmap with 4bit depth (16 colours), it doesn't consume that much space! For a 20x20 block you'd have 4*400/8=200bytes. If done well enough, you can get a theoretical of 32colours by making pixel patterns and tricking the eye. Better off, you can process two pixels per CPU cycle.

  • Patterning. Furthering the previous points, mixing two colors black and (yellow) in a chess pattern can seemingly do a new color. Here is an example on the edges with green and magenta (I had to take the color picker out to make sure!)

  • With only 16 displayable colors, many more can be simulated, see Eric Pepke's excellent answer here about Wang patterns.

  • The same thing happens with 8bit sounds. Place a few patterns, mix them on the spot. Instead of defining the musical notes, you define the pattern order, which uses significantly less space.

  • Well organized, predefined areas on cartridge assigned for different purposes.
  • Minimal or absent OS on a console or C64. Most of them had a bootloader with memory, but not a proper OS by modern standards. Multi-tasking was unheard of outside research labs.

  • In all honesty, only the state of the art games used every one of these techniques, especially the (tech) demo scene. A lot of these dirty tricks are still in use in the hardware world today. Arguably, such minimal programming elegance is only reached in ASIC design - custom chips, because each extra mm of silicon is very expensive to manufacture.

    Here's what 64kB can do in 2008:

    Of course, it will expand to fill the RAM and video RAM, so it's not a fair comparison. But similar techniques were used in order to reach the 64bit constraint. It may not run on your computer, or it may find it as a virus (proof that they really used some odd compression algorithms), but here is the link with the windows executable: Panic Room by Fairlight.

    More questions on Game Development: