Are there now standard or typical flicker mitigation techniques for sprites? If so, what are the most common ones?
Search for sprite cyclingOne 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.
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!
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.
Quote:
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.
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.
Naïve 8x8 sprite coverage of some hero and monster cels
Efficient staggered coverage of the same cels
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?
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.
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
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.
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.
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.
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.
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.
Attachment:
megaman_original.png [ 23.46 KiB | Viewed 6707 times ]
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.
Attachment:
megaman_tilificator.png [ 25.76 KiB | Viewed 6707 times ]
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)
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.
If priority matters, you could reserve sprites 1-31 for top halves and sprites 33-63 for bottom halves.
I have 16 objects, and I have a small table of numbers relatively-prime to 16. Each frame I cycle through the objects adding a relatively-prime number to choose the next object index, and call each object's draw routine in that order (the draw routines just fill up the OAM buffer in linear order as tiles are added). Every frame I just advance to the next number in the table. I always start the index at 0, allowing me to use sprite-0 hit if necessary and to always prioritize one of the objects.
Luckily, my project doesn't require priority, so I use a simple technique that I got from Bregalad where you draw sprites in the order of sprite #1, #3, #7, #10... #58, #61, #0, #2, #5... (except I use sprite #0 so I skip that) and then I think you start from a different index the next frame. This naturally cycles all the sprites.
I had an idea. I think it might be beneficial, if you were designing a system were priority is a concern, to never have to worry about priority within a metasprite. When drawing metasprites, the individual sprites can always be cycled. But then you'd have another layer that says what metasprites an object is made of (so you could have multiple metasprites making up an object), which would handle priority of those metasprites. So an object that would normally be one metasprite with defined single sprite priority could be turned into multiple metasprites, which are prioritized by this engine. I'm struggling with words today; I hope that makes some sense.
Hello Kitty World uses an RNG for its oam cycling. It kinda looked messy. I think a regular pattern would be more aesthetic, when compared to complete randomness.
This game has so many flaws, that you can't use it to compare it with anything. I didn't ever manage to get sprites to flicker, and it looks VERY messy before that. Relatively close to Ghostbusters or Action52 level of mediocrity.
From the very beginning of the game, allow the fourth balloon to scroll on screen, float up to be in the same vertical position as it, and then pause.
Also, just because you personally don't enjoy a game doesn't mean you can't learn anything from it.
An RNG seems like a bad idea. It tends to be 50% whatever on average but since it's not uniform that means there can be runs of one or the other state, thus uneven flickering. Audibly it's like the difference between a low tone and a geiger counter clicking rapidly.
It has nothing to do with me personally not enjoying it, it runs at 15 FPS and you barely control what is going on.
And if RNG is a bad idea, please come up with a better one. The forward/backward trick is great, but sprites will disappear completely if there is more than 16 on the scanline, and if there is like 9 of them, two of them will be flickering in a much worse way than if it was random (or sort-of-random).
Bregalad wrote:
It has nothing to do with me personally not enjoying it, it runs at 15 FPS and you barely control what is going on.
No problem, it was just an example of the technique you were curious about.
Even though it didn't run at 60 fps, you could still get a glimpse of the chaotic nature of the technique. I personally don't prefer it, but I don't actually care if someone chooses to implement it or not.
Bregalad wrote:
And if RNG is a bad idea, please come up with a better one. The forward/backward trick is great, but sprites will disappear completely if there is more than 16 on the scanline, and if there is like 9 of them, two of them will be flickering in a much worse way than if it was random (or sort-of-random).
The method I posted earlier should address your concerns.Castle Excellent uses this same idea, if you want to see an example. (They also combined it with the forward/backward technique, but it doesn't really look much different in my opinion)
Mmm.... yeah looks pretty nice ! I don't know where the numbers $34 and -$0c came from but I don't really care anyway.
They're just from me playing around with different numbers until I got flicker pattern I liked. They're changable of course, but the currIndex increment/decrement must be an odd number * 4.