Share this project

Done

Share this project

Done
Put on a lizard and go for an adventure! A new game for Nintendo Entertainment System, PC, and Mac.
Put on a lizard and go for an adventure! A new game for Nintendo Entertainment System, PC, and Mac.
Put on a lizard and go for an adventure! A new game for Nintendo Entertainment System, PC, and Mac.
325 backers pledged CA$ 18,440 to help bring this project to life.

My lizard is the Lizard of Pause

15 likes

Lizard is rapidly approaching completion, and a lot of what I'm working on right now I'd rather keep a surprise, so instead I thought I'd write a little bit about a very small feature of the game that probably has taken a bigger engineering toll than it looks.

I'm talking about the pause overlay. Here's how it looked in the alpha demo:

An overlay slides up from the bottom of the screen when you pause.
An overlay slides up from the bottom of the screen when you pause.

Here's a couple of things I was trying to accomplish with this device:

Alpha

Since the original concept for Lizard was a single screen game, and the NES is more or less a "two screen" system, it seemed convenient to just put the text on part of that unused second screen. Here's a slow motion peek at the the full video memory:

Showing the two-screen background view as the pause overlay is animated.
Showing the two-screen background view as the pause overlay is animated.

Aside from needing to put that text somewhere in video memory, I also had to switch the hardware to display it on the correct part of the screen. I covered the technique in my scrolling update, but basically I need to place a single sprite tile at the point on the screen where it switches, and then my program has to wait for the moment when that sprite is drawn. At that moment, it switches the hardware scroll registers to start showing the other screen.

A problem with this, though, is that that sprite has to be on an opaque part of the screen, meaning it can't be the black colour I use for the background. This affects the bottom right corner of every room in the demo, as I have to make sure there is a solid column of opaque pixels for the sprite to overlap; failing to do this would result in a glitchy pause overlay!

You'll notice that the bottom right of many rooms in the demo are actually black, though. There's a workaround here: I can use a second black colour as a substitute, but this takes up very precious space in the palettes! I've only got 12 colours to assign, and having to give up even 1 here is actually a huge problem. The tiles are drawn with 3-colour palettes, so giving up a colour for a redundant black means that I'm stuck with some tiles that can only use 2 colours, or otherwise wasting that whole set of 3.

Showing the palette of a screen using an "extra" black colour, highlighted with yellow.
Showing the palette of a screen using an "extra" black colour, highlighted with yellow.

I elaborated on this point in my update about sprites, but I think managing the limited colour palette is the one place where the NES hardware imposes most strongly on the design of the game.

The other thing that happens at that scrolling split point is I turn off sprite rendering. The sprite layer and the background layer are entirely separate, so I need to do something at this point to hide sprites below the overlay.

Showing the sprites versus the overlay. Note the timing sprite on the top right corner of the overlay.
Showing the sprites versus the overlay. Note the timing sprite on the top right corner of the overlay.

Originally I wanted to slide the overlay in as smoothly as possible, one pixel at a time, but it's 64 pixels tall and that takes over a second. It turned out to be way too slow! In the demo I ended up using steps of 4.

A very early build of Lizard, featuring a very slow, very smooth pause overlay.
A very early build of Lizard, featuring a very slow, very smooth pause overlay.

Finally I had to do something special for the River Zone. The River Zone always used two screens, so I made a special pause for that one that just erased all the sprites on the screen and replaced them with a row of sprites that said "PAUSED". A lot of NES games hide the action like this when they are paused (Super Mario Bros. 3 is a common example), but I wasn't entirely happy with this.

The special pause in the demo's river prototype, and a pause in Super Mario Bros. 3 for comparison.
The special pause in the demo's river prototype, and a pause in Super Mario Bros. 3 for comparison.

After the kickstarter campaign, though, I made the switch to double wide rooms and the old overlay wasn't going to work anymore, and this special solution for the River Zone wasn't good enough for the rest of the game either.

Beta

So... double wide rooms happened, and I had to find a new way to do the pause overlay.

The first major problem here is that I no longer have free space in the background to put it. I need to draw this overlay directly on top of the visible screen instead. An immediate advantage of this, since it's no longer appearing on a separate region of video memory, I don't need to change the scroll to show it. It appears in its place with no special interaction with the hardware, and no more need for meticulously prepared sprite timing!

Even better: in a lot of rooms I get back that wasted extra black palette colour, since that opaque-pixel requirement is gone! This is a huge bonus.

I have to shift the position of the text to match the scroll, but that part wasn't difficult:

Showing the two-screen background for the new pause. The text is now placed very intuitively where you see it, instead of a separate location.
Showing the two-screen background for the new pause. The text is now placed very intuitively where you see it, instead of a separate location.

A new problem is introduced, however. The timed split let me simply turn off sprites below the overlay line to hide them. I can't do this anymore, so I have to figure out a different way to keep them off the overlay. I can remove any sprite tiles that are roughly below the overlay, but the tiles are 8 pixels high. This is too coarse, and will leave either a gap or an overlap.

Without the timing sprite to turn off sprite rendering, I can only remove sprite tiles on a very coarse 8-pixel basis. There is some overlap error here.
Without the timing sprite to turn off sprite rendering, I can only remove sprite tiles on a very coarse 8-pixel basis. There is some overlap error here.

To get that sprite cutoff clean, I ended up intentionally exploiting a flaw in the system. You may remember from my sprite update the cause of "flickering" on the NES being a limit of 8 sprites per scanline. What if I deliberately put 8 sprites on the cutoff region to make the rest drop out?

Sprites with the new pause method, intentionally abusing the 8 per line sprite limit to hide the overlap errors.
Sprites with the new pause method, intentionally abusing the 8 per line sprite limit to hide the overlap errors.

In the picture above, that one sprite halfway off the edge of the screen on the right is actually a stack of 8 sprites, perfectly cutting off all other sprite tiles that overlap that region of scanlines! You can't actually see these 8 extra sprites, as they're carefully hidden, but they're still there doing their job.

Here it is in action. Sorry about drowning the pandas, but it was for science.

The finished pause overlay, at half speed so you can get a good look.
The finished pause overlay, at half speed so you can get a good look.

It doesn't really slide up quite like the original version, though it's a bit quicker: 8 frames to draw black lines, 1 more to set the background palette to a text colour, and 5 more frames to draw the text. The last thing drawn is the START indicator, which gives you an immediate visual indication that you can now press START to continue.

This fits the set of goals I had pretty well. It may be surprising to say, but it took a very long time for all of these pieces to come together. Some ideas I did not have right away; other things I put off solving while I worked on different things. It was only a few days ago that I finally implemented the last, most subtle pieces of this. One less thing on my list of unfinished tasks, which is getting very short by now!

.

I hope you've enjoyed this explanation of a very small but important feature of Lizard. I now go back to working on the game... which is almost complete! (AAAAH!!!)

 

Hellblazer1138, Paul Molloy, and 13 more people like this update.

Comments

Only backers can post comments. Log In
    1. Brad Smith Creator on October 24

      Lucian Depold: I'm working hard to make that happen!

    2. Lucian Depold on October 22

      hey brad, looking forward to play the full game , maybe before christmas ?!?

      Lucian

    3. Maciej Korzeniowski
      Superbacker
      on September 17

      Excellent write up! This increases the value of the game once in hand. And I see your lizard is the the lizard of Coffee. =)