Controlled sprite flicker

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Controlled sprite flicker
by on (#228569)
I've been thinking about how to display more than 8 sprites on a single scanline. My understanding is you make them flicker in and out by setting the priority bit in byte 2 of the oam to be behind the background. What I'm not sure is if there is some sort of scanline collision detection that would somehow determine if there are more than 8 sprites on a single line, or if the sprites should be set to randomly flicker at different times to just decrease the likelyhood of them all showing at the same time on the same scanline.

What kind of strategies are generally used? I tried googling this, but didn't really come up with anything.

Thanks
Re: Controlled sprite flicker
by on (#228571)
A search gave me this https://forums.nesdev.com/viewtopic.php?f=2&t=10591
Re: Controlled sprite flicker
by on (#228572)
nesrocks wrote:


Not sure why that didn't come up for me.

Thanks
Re: Controlled sprite flicker
by on (#228573)
The BG bit does nothing to help BTW. Lower sprites in memory always have priority over the higher ones, regardless of the BG bit.
Re: Controlled sprite flicker
by on (#228574)
battagline wrote:
I've been thinking about how to display more than 8 sprites on a single scanline. My understanding is you make them flicker in and out by setting the priority bit in byte 2 of the oam to be behind the background. What I'm not sure is if there is some sort of scanline collision detection that would somehow determine if there are more than 8 sprites on a single line, or if the sprites should be set to randomly flicker at different times to just decrease the likelyhood of them all showing at the same time on the same scanline.

No, the priority bit will not help with this. That only draws that sprite behind the background, but it does not move it to a separate pass, so it will still interfere with other sprites on the same scanline even if they're not behind the background.

The way to deal with this is to change the order of the sprites within the OAM buffer.

The first step is not to put any particular character in a location. A lot of games hard-code sprites like this, but it makes flicker impossible. When you start a frame, set an "OAM index" to 0, every time you add a new sprite, put it at the index location, and add 4 to that index. To finish the frame, fill the rest of the OAM Y coordinates with $FF to hide any unused sprites.

Once you have a system like that in place, cycling the sprite order can be achieved by drawing your sprites in a different order each frame. You might try going through your object list forwards and backwards on different frames, or cycling thruogh them, or maybe have a few different orders.

Simple example:
Code:
jsr oam_begin ; set index to 0
inc order_sequence
lda order_sequence
and #3
bne @order1
@order0:
   jsr draw_player
   jsr draw_enemies
   jsr draw_bullets
   jmp @order_end
@order1:
cmp #1
bne @order2:
   jsr draw_bullets
   jsr draw_enemies
   jsr draw_player
   jmp @order_end
@order2:
cmp #2
bne @order3:
   jsr draw_enemies
   jsr draw_player
   jsr draw_bullets
   jmp @order_end
@order3:
   jsr draw_player
   jsr draw_bullets
   jsr draw_enemies
@order_end:
jsr oam_finish ; fill unused sprite Ys


There are a lot of ways to do this reordering, and what's appropriate depends on your game (often you might want one sprite to always draw first so it never disappears), but this is the general idea. In my last game I use a table of prime numbers as an increment through my game object list, so that they get iterated in a different order each frame.

Though a lot of older games did things in pairs of frames one off, one on, I'd recommend against a sequence with only two steps if you're making a new game, otherwise you'll get the "Mega Man disappears when hit" thing when YouTube or Twitch shows the video at 30fps. Use sequences of 3 frames or longer to ensure that the flickering is still comprehensible at half framerate.

One more general recommendation: don't try to detect overlap, it's easier just keep changing the order every frame. (Technically the sprite overflow flag in $2002 is supposed to detect this in a limited way, but its implementation was broken and it reports false positives. Not very useful.)
Re: Controlled sprite flicker
by on (#228575)
Note: Ninja'd by a lot of people, but I didn't write a reply for nothing so I'm posting anyway.

What you're looking for is called OAM cycling, and it has nothing to do with the priority bit.

Priorities between sprites is dictated by their order in OAM. Sprite 0 has the highest priority, sprite 63 the lowest. If more than 8 are present in any given scanline, only the 8 with the highest priorities will be rendered.

OAM cycling typically means randomizing the order of the sprites every frame, effectively randomizing their priorities, so that different sprites are dropped each frame.

You don't need to know when more than 8 sprites are sharing scanlines for this to work, because all sprites will be displayed when there are 8 or less, regardless of their priorities. The PPU does have a flag that indicates when sprites are dropped, but it only gets set once per frame (so you don't know which sprites are the problematic ones), and a bug in this flag's logic may report false positives.
Re: Controlled sprite flicker
by on (#228576)
Ok, so I need to look around for OAM cycling for more information. I wasn't sure what it was called so googling things like "NES intentional sprite flickering" didn't return what I was looking for.

Thanks for your help
Re: Controlled sprite flicker
by on (#228579)
Strictly speaking, all sprite flickering is intentional. The PPU itself never flickers sprites, it just doesn't draw the ones with lower priority when it finds too many of them.
Re: Controlled sprite flicker
by on (#228585)
So I've attached a little flickering test I wrote. I'm not sure it looks right. Opinions are appreciated.

Thanks
Re: Controlled sprite flicker
by on (#228587)
It appears that you have two sprites for each letter and you're moving them outside the screen? You only should have one sprite for each letter and you don't have to move them at all. You cycle their address in memory so they alternate who's first in memory.
Re: Controlled sprite flicker
by on (#228590)
nesrocks wrote:
It appears that you have two sprites for each letter and you're moving them outside the screen? You only should have one sprite for each letter and you don't have to move them at all. You cycle their address in memory so they alternate who's first in memory.


Actually what I'm doing is alternating the direction I write to oam, so on odd frames it writes from lowest to highest bytes and on even frames in writes from highest to lowest. I'm thinking since you move the whole block of OAM memory with the DMA no matter much it shouldn't matter that the used sprites alternate from one side of oam to the other, but if that's a problem for some reason, please let me know.

Thanks
Re: Controlled sprite flicker
by on (#228593)
This subject comes just at the right time, when I'm considering how to approach it myself ^^;;;

I guess it depends on your system that you have implemented and how complicated is your engine. For example, I'm not doing sprite cycle at the moment (but must find how) and how I manage my sprites is that I add to a buffer a list of meta sprites with their information on every frame. Once everything is added to this buffer, I convert that buffer to OAM data.

I guess in my case, what I could do is on every odd frame I parse the buffer forward and even one backward and it could creates some very basic sprite cycling but it will still be depend on the order things are put inside, which for now it quite basic (player, bullets then soon entities, in that order).

Would it be enough, good question, but I guess I will know soon ^^;;; Is it a bad approach? I don't want to give some advice that are ill advised in the first place but I thought it was the right place to talk about it, instead of creating a new thread.
Re: Controlled sprite flicker
by on (#228595)
battagline wrote:
but if that's a problem for some reason, please let me know.

In cases where you have more than 16 sprites on a line, alternating direction will still leave the ones in the middle unseen, but that's maybe an extreme case.

Maybe a more minor issue is the middle ground where you have 9-15 sprites on a line: in this case only the low and high sprites will be flickering, but the ones in between will be solid. This gives very uneven looking flickering, as only some of the sprite tiles will participate in it. That's pretty normal for NES flickering, though, so this might be acceptable.

The other problem I mentioned above, alternating frames means that on YouTube or streams or some other common situations where there's a reduction to 30fps will leave people seeing only one of the two versions. Though, you could deal with that easily by reversing every 2 frames instead of every frame, or doing some pattern like 01001011.
Re: Controlled sprite flicker
by on (#228598)
rainwarrior wrote:
Maybe a more minor issue is the middle ground where you have 9-15 sprites on a line: in this case only the low and high sprites will be flickering, but the ones in between will be solid. This gives very uneven looking flickering, as only some of the sprite tiles will participate in it. That's pretty normal for NES flickering, though, so this might be acceptable.

The other problem I mentioned above, alternating frames means that on YouTube or streams or some other common situations where there's a reduction to 30fps will leave people seeing only one of the two versions. Though, you could deal with that easily by reversing every 2 frames instead of every frame, or doing some pattern like 01001011.


My thought was I would like to design the game to try and avoid any flickering at all, and the flickering would only happen in cases where things went further than I had intended... just a thought, it may not end up working out but doing it this way doesn't spend many cycles and is pretty easy to implement
Re: Controlled sprite flicker
by on (#228619)
rainwarrior wrote:
Though, you could deal with that easily by reversing every 2 frames instead of every frame, or doing some pattern like 01001011.

I'd consider leaving a sprite invisible for more than one successive frame much more detrimental than a 30hz flicker rate.
If I'm making an NES game, I'm designing it for a CRT, not for YouTube, and a sprite disappearing for a single frame on a CRT will not flicker as clearly, and usually just appear like it goes partly transparent. Lose it for two frames in a row, and the flickering will be much more apparent.

I noticed this effect in my Donkey Kong port. Playing on emulator, a lot of people had issues with the frequent flickering. But playing it on a CRT it's nowhere near as noticeable.
Of course, I realise that most people will probably be playing your game on an emulator, or an LCD TV, but even on those, I think losing a sprite for two frames in a row will look off-putting when it's not intended as an effect (like Mega Man's invincibility frames)

Did anyone ever reverse engineer Dynamite Batman/Return of the Joker? I'd love to know which method they used.
Re: Controlled sprite flicker
by on (#228624)
Sumez wrote:
Did anyone ever reverse engineer Dynamite Batman/Return of the Joker? I'd love to know which method they used.

I don't know if it does anything special... I does flicker a lot, but I guess we don't care on account of every sprite and background looking so awesome.

I'm also impressed by how Felix the Cat is able to have overlaid weapons and vehicles with a budget of only 7 sprites per scanline (the right edge of the screen has a column of high priority sprites hiding scrolling glitches) and still look as good as it does.
Re: Controlled sprite flicker
by on (#228650)
Sumez wrote:
rainwarrior wrote:
Though, you could deal with that easily by reversing every 2 frames instead of every frame, or doing some pattern like 01001011.

I'd consider leaving a sprite invisible for more than one successive frame much more detrimental than a 30hz flicker rate.
If I'm making an NES game, I'm designing it for a CRT, not for YouTube, and a sprite disappearing for a single frame on a CRT will not flicker as clearly, and usually just appear like it goes partly transparent. Lose it for two frames in a row, and the flickering will be much more apparent.

Well, it's up to you whether you care about YouTube, etc. but a lot of people like to experience games through Twitch, YouTube, etc. and the effect of alternating frames is that one of them just doesn't get seen. If you're complaining about 2 frames in a row of invisible character on a CRT, the stream version gets 100 invisible frames in a row instead, one of these problems is dramatically more apparent.

My ideal suggestion though is reordering all the characters' drawing every frame, that way the alternation is more randomized and distributed across all the sprites. The quoted suggestion is just a compromise for having only 2 orders.
Re: Controlled sprite flicker
by on (#228663)
That is a non issue if you upload it at 60 fps. Tasvideos.org has been uploading them at that refresh rate for many years now. It's the standard and the flickering is represented perfectly.
Re: Controlled sprite flicker
by on (#228665)
That's fine for videos that you post on your own website. But If people are watching on YouTube, as opposed to on your own website, a substantial fraction of those people will be watching at 30 fps. This is because YouTube has a policy of downconverting 60 fps video to 30 fps unless all of these are true:

  1. The viewer's computer can decode 720p60 in real time.
  2. The viewport is big enough for 720p.
  3. The viewer's Internet connection can support data rates typical of 720p60.
  4. The video was uploaded in 720p or larger.

I've owned several laptops and smartphones that failed A (decoding rate) and B (display size). Some users here connect to the Internet through satellite or DSL, which may not be able to meet C (sustained data rate), particularly once a cellular or satellite ISP starts charging overage fees. As for D (source size), the NES itself is incapable of outputting 720p unless modded with the Hi-Def NES kit (which I do not own), and I was under the impression that capturing 720p60 required a far beefier device than capturing 240p60 or 480i30.
Re: Controlled sprite flicker
by on (#228666)
I too wouldn't want to compromise anything in the game itself because of how other people may or may not share videos of my game. If was making a video myself, I would maybe put a disclaimer somewhere, stating that the video might not be a faithful representation of the game depending on the viewer's hardware and configurations, but I can't worry about what everyone else in the internet might do. Some people don't even know how to properly capture game footage, and end up with abysmal irregular frame rates (and capture software watermarks).
Re: Controlled sprite flicker
by on (#228670)
Well, whether or not you care about how a lot of people will see your game footage, that's up to you, I was merely trying to point out the existence of this problem, and some ways it can be addressed. If it's not a problem you're concerned with then don't solve it.

Though I don't really think of more distributed/quasi-randomized cycling as a "compromise", but I say that because I'm only considering flicker to mitigate unavoidable sprite overlap here.

That's a different case than intentional 50% transparency (alternating frames), even though they're both subject to that same 30Hz problem. I would definitely agree that the trying to accommodate that must result in some sort of compromise (e.g. a suitable 30Hz substitute for the text of Batman's intro would be difficult). As an alternative to that, 33% or 66% transparency as a cycle of 3 frames can work well for some purposes (and falls back nicely to a half-speed cycle of 3 on 30hz), but YMMV.
Re: Controlled sprite flicker
by on (#228703)
rainwarrior wrote:
Well, it's up to you whether you care about YouTube, etc. but a lot of people like to experience games through Twitch, YouTube, etc. and the effect of alternating frames is that one of them just doesn't get seen. If you're complaining about 2 frames in a row of invisible character on a CRT, the stream version gets 100 invisible frames in a row instead, one of these problems is dramatically more apparent.


Does Youtube default to 30fps? I'm pretty sure you can do 60fps on youtube. If there an emulator setting that just ignores the 8 sprites per scanline limit? It seems to me that would provide a better experience if you're not playing on actual hardware
Re: Controlled sprite flicker
by on (#228706)
battagline wrote:
Does Youtube default to 30fps? I'm pretty sure you can do 60fps on youtube.

YouTube allows 60 fps only under the conditions that I described above. If you can suggest how to ensure that the uploaded file and the vast majority of viewers meet the requirements, I'd be interested to read your suggestion.
Re: Controlled sprite flicker
by on (#228714)
battagline wrote:
Does Youtube default to 30fps? I'm pretty sure you can do 60fps on youtube. If there an emulator setting that just ignores the 8 sprites per scanline limit? It seems to me that would provide a better experience if you're not playing on actual hardware

Emulators do often have that option, but many games rely on the 8 sprite limit to hide stuff too. Depends what games you want to play but it makes many of them worse because of that.

With YouTube you will just have to expect that a significant amount of people (probably the majority) will be watching in 30fps, whether or not you uploaded at 60fps. There's really nothing you can do to change that reality.

With Twitch there's similar problems but here's an example where despite broadcasting from OBS at 60fps it was not capable of syncing with the emulator and you get a very erratic effect. That's very common, really, and people often use OBS to capture video for non-streaming stuff like YouTube uploads too.

It might technically be possible to capture it cleanly from OBS with very careful settings, but basically nobody is going to figure that out. Even people who stream for a living have this problem all the time with NES / retro games that do alternating frame effects. (...and of course, a lot of people are going to be watching it at 30fps anyway, whether or not you got the source version right.)

Anyway, maybe easier to just decide this is an acceptable problem and ignore it, like some people are suggesting, but to me it's worth considering.


Curiously, I was looking at a few older games just for examples and discovered several commercial era NES game that uses 30Hz alternation when you take damage instead of 60Hz, including Super Mario Bros. 3 and Mega Man 2. I don't think they were able to see the future of YouTube and streaming, but I think probably they thought 60 didn't look flickery enough to communicate the effect so they inentionally slowed it down. ;) SMB2 has an interesting progression from 15Hz to 30Hz to 60Hz when you take damage, indicating roughly how close you are to regaining solidity. Swamp Thing goes as low as 7.5Hz on damage!
Re: Controlled sprite flicker
by on (#228724)
I was looking at other games and especially in the case of mega man, when the characters dies, it will show 8 circles that will grow. At is biggest, 1 circle uses 8 sprites, which means you are already at 64 if you want to show all of them. The only way to show the explosion and other entities would seems to alternate every 30hz when over the limit, which would flicker and in the video case make some part disappear.

In my own engine I'm not handling such events yet so this is one problem that I will need to figure out sooner or later ^^;;;
Re: Controlled sprite flicker
by on (#228928)
rainwarrior wrote:
Curiously, I was looking at a few older games just for examples and discovered several commercial era NES game that uses 30Hz alternation when you take damage instead of 60Hz, including Super Mario Bros. 3 and Mega Man 2. I don't think they were able to see the future of YouTube and streaming, but I think probably they thought 60 didn't look flickery enough to communicate the effect so they inentionally slowed it down.

This kind of goes back to the comment I made earlier - there's a very big difference between sprite flickering and an intentional blinking effect. 30hz looks like the sprite blinking in and out of existance, which is what you want it to when taking damage - it just works better as feedback for the player.

Meanwhile with sprite flickering, you want it to look like the sprite is still there even when the console doesn't draw it. We've been used to talk about the NES as a console where sprites flicker all the time, but back in the days before emulation I rarely heard anyone bring attention to the fact. Basically, as long as you stick to 60hz flickering at worst, it's not really that noticeable on most CRTs with a high persistence (which is especially common on cheaper models).
Re: Controlled sprite flicker
by on (#228933)
rainwarrior wrote:
Emulators do often have that option, but many games rely on the 8 sprite limit to hide stuff too. Depends what games you want to play but it makes many of them worse because of that.


The Atari emulator Stella has a feature called "simulate posphor" that smooths out 30Hz flickering into a steady slightly-faded image. Do any of the popular NES emulators have something like that? It seems like that would solve a lot of the problems: 30Hz videos would still display correctly. Purposely faded characters (ie if you took damage) would still look slightly different, and games that rely on the 8-sprite limit would still function correctly.
Re: Controlled sprite flicker
by on (#228939)
The problem with that setting is that "posphor" doesn't look like that at all. Stella shows steady 50% transparency when there's 30Hz flicker, but that's not how CRTs behave, you can see the flickering on a real TV. I think it's a completely inaccurate simulation created just to make sprite multiplexing techniques easier on the eyes.

Also, a setting like that would look terrible combined with scrolling, IMO. Backgrounds would look blurred with every little movement.
Re: Controlled sprite flicker
by on (#228941)
tokumaru wrote:
The problem with that setting is that "posphor" doesn't look like that at all. Stella shows steady 50% transparency when there's 30Hz flicker, but that's not how CRTs behave, you can see the flickering on a real TV. I think it's a completely inaccurate simulation created just to make sprite multiplexing techniques easier on the eyes.


On my TV, flickering looks somewhere in between what Stella does, and what 30Hz on a monitor does. You can see some flicker, but not nearly what you'd see on a monitor with an emulator.


Quote:
Also, a setting like that would look terrible combined with scrolling, IMO. Backgrounds would look blurred with every little movement.

That's a good point. Although you could theoretically enable it only for sprites.
Re: Controlled sprite flicker
by on (#228985)
tokumaru wrote:
I too wouldn't want to compromise anything in the game itself because of how other people may or may not share videos of my game. If was making a video myself, I would maybe put a disclaimer somewhere, stating that the video might not be a faithful representation of the game depending on the viewer's hardware and configurations, but I can't worry about what everyone else in the internet might do. Some people don't even know how to properly capture game footage, and end up with abysmal irregular frame rates (and capture software watermarks).

Not to mention those who simply enlarge retro games in 16:9 and doesn't even notice how wrong this looks... And this is not a rare phenomenon by any mean.

The only "proper" way to scale a 60FPS game into 30FPS (or lower) video would be to average frames, that is, if a sprite is flickering at 60 FPS it should look transparent on the video, which is correct. Having it either be solid or disapearing is wrong.

Regarding to the original question... There is lots of different techniques and strategies to achieve sprite flickering, it really depends on the game, whether you have sprite priority within metasprites, and whether priority between metasprites is important. In the major game engine I developed priorities within metasprites are not important, but priorities between metasprites are important, so I always draw metasprites in the same order, but reverse the order of individual sprites within metasprites.