Standard flicker mitigation techniques?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

slobu
Posts: 275
Joined: Tue Jul 12, 2011 10:58 am

Standard flicker mitigation techniques?

Post by slobu » Wed Oct 16, 2013 9:01 am

Are there now standard or typical flicker mitigation techniques for sprites? If so, what are the most common ones?

tepples
Posts: 22356
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Standard flicker mitigation techniques?

Post by tepples » Wed Oct 16, 2013 9:29 am

Search for sprite cycling

One common method is drawing sprites in forward order one frame and backward order the next, so that you get flicker instead of dropout. But the only surefire method is to reduce sprite coverage. For example, you could put certain objects into the background if possible. Or if your sprite cels have thin parts, you could stagger the sprite grid to use fewer sprites on a row. I can make another illustration if you want.

One interesting thing I saw in one of the Gradius games was storing a long, thin, horizontal laser beam sprite with only the top three rows filled. This way, it could be drawn with alternating normal and flipped, causing less flicker in the adjacent scanlines.

slobu
Posts: 275
Joined: Tue Jul 12, 2011 10:58 am

Re: Standard flicker mitigation techniques?

Post by slobu » Wed Oct 16, 2013 9:47 am

So, does this mean some games look for chances to change a sprite to a background tile if it's aligned advantageously?

Also, would a pseudo random distribution look better than the front/back technique?

P.S. Thank you for a heads up on the correct keyword to look for!

tepples
Posts: 22356
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Standard flicker mitigation techniques?

Post by tepples » Wed Oct 16, 2013 9:56 am

slobu wrote:So, does this mean some games look for chances to change a sprite to a background tile if it's aligned advantageously?
Yes. Mario Bros., Super Mario Bros., and Super Mario Bros. 3 turn ? blocks and brick blocks from background into sprite when bumped from below and back after a short delay. Super Mario Bros. 2 lets the player pick up a mushroom block, turning it from a background into a sprite, and then toss it somewhere, after which point it turns back into background. The same is true of the critters and bombs that Toad carries in Wario's Woods and anything round that doesn't have something under it in Crystal Mines and its reskins Exodus and Joshua. In games like Tetris, Dr. Mario, Puyo Puyo, Magic Jewelry/Mystic Pillars, Rampart, and Pipe Dream, the falling piece is a sprite, but it turns into background tiles once it locks. Some games draw the playfield as a CHR RAM pseudo-bitmap so that they don't even have to worry about alignment, such as Hatris, Qix, 3D Block, the BlockOut prototype, and Videomation.
Also, would a pseudo random distribution look better than the front/back technique?
Some Konami games use more complex shuffling patterns.

Some games flicker everything to fit twice as much on the screen. This could help especially with complex particle systems as might be seen in bullet hell shooters. Thwaite draws even numbered explosions and smoke particles in even frames and odd numbered ones in odd frames.

But ultimately, you need to design your game around NES sprite limits and not try to make, say, a Street Fighter/Mortal Kombat style fighting game with full-size characters. A better concept for an NES fighter, for example, might be a platform fighter like Smash Bros.

User avatar
Bregalad
Posts: 8025
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Standard flicker mitigation techniques?

Post by Bregalad » Wed Oct 16, 2013 10:19 am

Pseudo-random looks the best.
If you have 9 sprites on a line, and that 2 of them are flickering at 1/2 while the 7 others are solid, it will be very noticeable.
If all of them flickers at 8/9 you almost won't notice anything.

However, if there is 12+ sprites on a line, it'll look horrible no matter what you do. That's what happens in Gradius games, and the worse flickering-slowdown NES game of all time : Parodius.
This one is plain ridiculous, it comes to apoint it's completely unplayable. The only way the NES version of parodious would be playable would be to simulate a seriously overclocked NES with an emulator that disables sprite flickering.

tepples
Posts: 22356
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Standard flicker mitigation techniques?

Post by tepples » Wed Oct 16, 2013 11:10 am

Image
Naïve 8x8 sprite coverage of some hero and monster cels

Image
Efficient staggered coverage of the same cels

slobu
Posts: 275
Joined: Tue Jul 12, 2011 10:58 am

Re: Standard flicker mitigation techniques?

Post by slobu » Wed Oct 16, 2013 1:04 pm

Thanks for the diagram! I guess my brain always thought of tiles in grids.

Is flicker mitigation ever part of enemy AI? Something like an enemy will intentionally avoid being on the same horizontal plane?

tepples
Posts: 22356
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Standard flicker mitigation techniques?

Post by tepples » Wed Oct 16, 2013 1:35 pm

On Atari 2600, it was common to make enemies move back and forth in horizontal strips of the screen because the system really had only two sprites per scanline. Look at the sneakers from Fast Eddie (which inspired the critter shown above): only one is on each row.

slobu
Posts: 275
Joined: Tue Jul 12, 2011 10:58 am

Re: Standard flicker mitigation techniques?

Post by slobu » Wed Oct 16, 2013 1:45 pm

tepples wrote:On Atari 2600, it was common to make enemies move back and forth in horizontal strips of the screen because the system really had only two sprites per scanline. Look at the sneakers from Fast Eddie (which inspired the critter shown above): only one is on each row.
Gawd, I know all about flicker on the 2600! Thankfully you can simulate additional vertical sprites since player0 and player1 can be pretty tall.

My game M.M.S.B.C. II shows up two 8 enemies, 2 ships and lasers. Has paralax scrolling to boot :p
Image

User avatar
Dwedit
Posts: 4431
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Standard flicker mitigation techniques?

Post by Dwedit » Wed Oct 16, 2013 2:40 pm

I used a really simple method to do sprite cycling:
Add 9*4 to the output address after every complete sprite in the sprite table. When it reaches 0, you've written all 64 sprites.
This of course assumes that sprite draw order or priority doesn't matter at all.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

User avatar
tokumaru
Posts: 12059
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Standard flicker mitigation techniques?

Post by tokumaru » Wed Oct 16, 2013 4:13 pm

Dwedit wrote:This of course assumes that sprite draw order or priority doesn't matter at all.
Precisely. When I want to preserve the sprite order within an object, I randomize the order in which entire objects are drawn, and the objects get to chose which end of the OAM they want to use, so there are 2 global layers that are preserved. Also, objects are free to draw sub-objects at the time they're drawn, so they can make sure that explosions and other effects always show up in front of them.

ccovell
Posts: 1036
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: Standard flicker mitigation techniques?

Post by ccovell » Wed Oct 16, 2013 5:48 pm

slobu wrote:Is flicker mitigation ever part of enemy AI? Something like an enemy will intentionally avoid being on the same horizontal plane?
It very much is. I think it was Streets of Rage (1? 2?) on the Genesis that did this, with enemies programmed to walk up or down if more enemies come on the screen, also never aligning all enemies on a single horizontal strip, for obvious reasons.

Drag
Posts: 1342
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: Standard flicker mitigation techniques?

Post by Drag » Wed Oct 16, 2013 11:33 pm

The way I do it:

Start: Offset = $00, CurrIndex = $00

On sprite clear: Offset += $34, CurrIndex = Offset

Upon allocating a sprite: Copy sprite to CurrIndex, CurrIndex -= $0C

This "scatters" the sprites so that the flickering on the scanline is more evenly distributed, creating more of a "rolling" flicker effect.

If you used the simple method of just reversing your sprites every frame and had 9 sprites on a scanline, you'd get two sprites that flicker each frame (and thus are at 50% opacity), and 7 sprites that are solid. Although it's pretty iconic looking for older games, it doesn't look as good in my opinion.

If you need to have some semblence of priority, you can split the sprite OAM into two parts: one part is shuffled, and the other part is not. To do that, you just repeatedly apply your incrementation/decrementation to CurrIndex (and possibly also Offset) if the value is within the section that isn't shuffled, so you skip over it.

Bananmos
Posts: 542
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: Standard flicker mitigation techniques?

Post by Bananmos » Thu Oct 17, 2013 3:42 pm

Just want to add that besides staggering the sprite layout like Tepples mentioned, it can also be useful to make the sprites used to cover your cel overlap each other. Tilificator favours this sort of overlap in its sprite coverage algorithms.

megaman_original.png
Above image shows original tiles in Megaman. Notice how the two sprites making up the top of Megaman's head have no overlap, so if one disappears then ~50% of the graphics the two tiles cover will disappear as well.
megaman_tilificator.png
Above show an alternate tile coverage, where the same two sprites have up to 4 horizontal pixels of overlap. If one of them disappears, only ~25% of the graphics the two tiles cover will disappear.

Of course, favoring such overlap can have a drawback as well: Covering more of your cel can also mean less opportunity to to re-use the sprite for similar cels where only some pixels differ, so it can be trade-off between minimizing flickering pixels and minimizing your tileset. This is quite dependent on how your cels look though, and the optimal coverage given a particular set of cels is most likely an NP-complete problem. (though I personally lack the computer science math skillz to formally prove it)

User avatar
Bregalad
Posts: 8025
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Standard flicker mitigation techniques?

Post by Bregalad » Mon Jan 20, 2014 3:49 pm

Now that I had a second thought about it, it sounds like it could be possible to reach "ideal" sprite cycling at the price of extra CPU power the following way :
You have a list of numbers (for example 0-63) and you shuffle it every frame using something like this.
Then you just render the sprites following the order of the list. This way you're guaranteed their priorities are as random as your RNG is, and they will flicker evenly (if you have N (>8) sprites, each one of them has a (N-8)/N probability of disappearing on a given frame).

If you need priorities between various metasprites, you can shuffle only the individual sprites within the metasprite.
If inversely you need priorities within a metaprite for layering, you can shuffle the metasprites but not individual sprites within it.

You can of course only shuffle the part that needs to be shuffled, and keep order in parts that require orders.

However the major problem would be that it would be extremely slow, as there would be multiple calls to the shufflers every frame, and sprite drawing is already often the CPU bottleneck of a NES game. Shuffling requires random numbers in non-power of two ranges, which in turn requires either the modulo operator (-> division -> slow) or a re-call to the random algorithm if out of range (probably better as it's not biased and can be made faster than a division).

So I wonder how useful it would be to use shufflers in the context of sprite cycling. I think that at global scope in a game where priorities never matters, it can be a great idea, as shuffling is only done once per frame. In a case where it would be required to shuffle among smaller set of sprites might be more ambigious as the overhead would eat significant time.

Post Reply