Retained vs. Immediate Mode Graphics

A Mini Micro user today asked me to explain why it was designed with sprites that are retained between frames, instead of having users explicitly draw them on each frame. This is an insightful question! It's the difference between retained mode and immediate mode graphics.

What's All This, Then?

This article from Microsoft does a pretty good job of explaining the difference. In a retained-mode graphics API, the programmer sets up data structures that are "retained" or kept around by the graphics library itself. In the context of Mini Micro, Sprites would be a good example. You create a Sprite and load it into a SpriteDisplay. It'll then be drawn every frame, until you remove it. To make it animate, you just change its position, rotation, scale, image, or tint, and the display automatically updates.

A block diagram of a retained-mode graphics API (like our Sprites) looks like this:

Conversely, in an immediate-mode graphics API, the programmer has to redraw everything on the screen every frame, in their own code. If you want a sprite on the screen, you draw that sprite every frame for as long as you want it to appear, in the correct position, scale, etc. for each frame.

Mini Micro doesn't really have any true immediate-mode graphics; even a PixelDisplay retains its pixel buffer between frames. But if you imagine clearing the pixel display and redrawing its content every time through your main loop, that wolud approximate what it's like to work with an immediate-mode graphics API. Keeping track of what should be on the screen — i.e. the scene model — would be up to you.

A Brief History

Early 8-bit consoles, like the Atari 2600, had hardware support for sprites (though they weren't called that until the Commodore 64). The programmer needed only set certain registers to tell the hardware what the sprites should look like, and where they should be drawn.

With the advent of home computers/PCs, however, the situation changed. These had a much higher-resolution pixel buffer (display) and often no game-specific video hardware, at least in the early days. While the pixel buffer was persistent, like the PixelDisplay in Mini Micro, that doesn't help much when the contents of the screen are constantly changing, as is often the case for games. This may be what led to the development of popular rendering systems of that era, like Direct2D and OpenGL, to be immediate-mode APIs.

In modern times, though, that arc has progressed all the way around in a circle. Modern machines have powerful GPUs, often dwarfing the CPU in raw computing power and especially good at pushing textured polygons to the screen. However that power is wasted unless you keep the vertex buffers (which define the polygons) and textures actually on the GPU; moving that data in from the CPU is a major bottleneck. So modern gaming libraries, like Unity and Unreal, are retained-mode APIs. You create objects, position them where you want them, and leave them alone until something about them changes. This allows the game engine to upload all that data to the GPU and leave it there, which makes best use of the hardware — just like the old 8-bit graphics hardware of yore.

So, why use retained mode in Mini Micro?

With all that background, the answer is pretty simple. It boils down to these considerations:

  1. It's dramatically more efficient. It moves the bulk of the work not only out of MiniScript and into more efficient machine code, but in fact much of it gets moved off the CPU entirely, into that powerhouse that is the GPU. It also lets Mini Micro do things like automatically update the bounds of the sprite whenever it moves, which wouldn't be possible in immediate mode.
  2. It's simpler and easier for the programmer. Yes, it takes a few extra lines to set up a Sprite, but then if you really just wanted to draw an image, you could use gfx.drawImage. In most cases the extra setup is more than offset by the ease of subsequently animating a sprite by simply assigning new values to its properties. You don't need to make your own data structures to keep track of what should be drawn; that's all done already.
  3. It is both neo and retro. Mini Micro is the virtual neo-retro home computer, a continuation of the progression of home computers before MacOS and Windows took over. Much like the Commodore 64 and Amiga, which blended home computing and gaming in one machine, the Mini Micro is meant for both serious and fun software. Both modern (neo) and old-school 8-bit (retro) computers/consoles used retained mode graphics, so it only makes sense for Mini Micro to do the same.

So now you know. Go check out some of the "How To" articles about sprites, and get your retained mode on!