Off-screen displays in Mini Micro
Tags: miniscript, minimicro, graphics, rendering
Published: 2024-03-06 20:18:31

[Mini Micro](https://miniscript.org/MiniMicro/) has an 8-layer display system.  Each layer can be configured to any of several types, including [PixelDisplay](https://miniscript.org/wiki/PixelDisplay), [SpriteDisplay](https://miniscript.org/wiki/SpriteDisplay), [TileDisplay](https://miniscript.org/wiki/TileDisplay), and [TextDisplay](https://miniscript.org/wiki/TextDisplay).  The default configuration looks like this:

![Default display layout in Mini Micro](https://miniscript.org/w/images/2/2e/DisplayLayout.png)

Layer 0 is in the front, and you can see that the first three display layers are off by default (as is layer 6).  Then we have a text layer, a sprite layer, a graphics layer, and finally a solid color layer in the back.

If you've used Mini Micro before, you've probably changed the display type in one or more layers to suit your needs.  But did you know that you can create and use a display completely separate from the screen?  Let's explore how to do that, and why it's useful.

## Creating an off-screen display

...is as simple as using [`new`](https://miniscript.org/wiki/New) with the display class.  Fire up Mini Micro, and try this:

```
]t = new TextDisplay
]t.print "Hello world!"
]t.install 2
```

This creates a new, offscreen TextDisplay, and prints a greeting to it.  This doesn't have any visible effect until you install it with the third command.  Then, the text from this new (now _on_-screen) TextDisplay gets layered with the one you're typing on, in layer 3.  Upon `t.`[`install`](https://miniscript.org/wiki/Display.install)` 2`, our new display `t` replaces whatever was previously installed in layer 2 (which by default, was an `OffLayer` which never draws anything).

Here's a larger (and slightly more realistic) example.

```
import "mathUtil"
corners = [[780, 320], [630, 580], [330, 580], 
   [180, 320], [330, 60], [630, 60]]
draw = function(frac, steps=300000)
	p = [480,320]
	i = 0
	while i < steps
		corner = corners[rnd * corners.len]
		p = mathUtil.lerp2d(p, corner, frac)
		gfx.setPixel p[0], p[1], color.aqua
		i += 1
		if key.pressed("escape") then return i
	end while
end function

clear
gfx.print "Rendering, stand by...", 100,300, "#CCCCCC", "large"
gfx = new PixelDisplay
draw 0.62
gfx.install 5
print "Done!", 10, 600
```

Here we want to draw something that takes a while, and to be mysterious, we don't want to let the user see it until it's all done.  So we create a new PixelDisplay, assigning the global `gfx` to point to it.  Drawing takes place there, safely off-screen.  Then when the job is done, we install the detached display in slot 5 (kicking out the previous display, including the "stand by" message).

![Snowflake display from the chaos game](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q20idaexlmor72lsubmp.png)

(Incidentally, the trick used to make this snowflake is an algorithm called the [Chaos Game](https://en.wikipedia.org/wiki/Chaos_game), and is probably worthy of a blog post in itself — leave a comment below if you agree!)

## Uses for offscreen displays

The example above is one common use case: preparing a drawing ahead of time, so that it can be displayed instantly when needed.  But there are many others.  Here are some actual uses I found by searching my own code:

- An offscreen PixelDisplay is commonly used as a "scratch space" to composite several images and/or some text together; and then pluck the result out (with getImage) for use as a Sprite.

- To temporarily display something like an assertion failure, we create a new TextDisplay, install it while noting the previous display in that layer, and then restore the previous one when finished.

- I often use a TileDisplay as a distance map or heat map, using the cell tint to represent things like distance to the goal.  I keep this off-screen during the actual game, but when developing and debugging, I can just install it in some convenient layer to see exactly what my heat-map looks like.

## Conclusion

The ability to create arbitrary displays "out of thin air" beyond the standard eight layers, and actually manipulate these displays while off screen, is a powerful tool in your toolbox.

What might you create with it?