OAM cycling on hypothetical 15-sprite PPU with X as priority

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

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

OAM cycling on hypothetical 15-sprite PPU with X as priority

Post by tepples »

Kenny Rogers won a Grammy for the song 'The Gambler', in which Don Schlitz wrote:Said "If you're gonna play the Game Boy, you gotta learn to play it right."
NES games use a display list in RAM, also called shadow OAM, and then DMA that to the PPU during vertical blanking period. OAM DRAM refresh bugs in the PPU make this necessary even when few sprites move from one frame to the next.

But apart from sprite 0, I've gathered that it's also considered best practice not to hardcode a particular game object's starting position in the display list. For example, don't always draw the main character using sprites 1-8, enemy 1 using sprites 9-14, enemy 2 using sprites 15-20, etc. Instead, NES games are supposed to reassign slots every frame, especially if there's a possibility that more than eight will be displayed on the same scanline. This also allows the game to make enemies intentionally Z-fight if they overlap.

But in the community for another 8-bit platform, it's common to hardcode OAM indices for actors, and I'm trying to understand why they do that. The best way I know to do so is to generalize from what I know, and I know the NES. So for comparison, I'll describe the other platform's PPU as if it were a famiclone:
  • Like the AVS, this famiclone's PPU has enough secondary OAM to draw 15 sprites per line instead of 8, using the alternate fetch pattern I described in Enhancement#Overdraw. Thus sprites can cover nearly half of the screen's width rather than one-fourth.
  • The PPU determines which sprites to draw by finding the 15 lowest-numbered sprites in OAM whose Y range overlaps each scanline, just as the authentic NES PPU does. But then it sorts these frontmost 15 sprites by their X coordinate before displaying them. Sprites to the left are drawn in front, with position in OAM only breaking ties.
On a hypothetical famiclone like this, with more overdraw and less control of sprite-to-sprite priority, would it be less of a bad practice to statically allocate OAM space?
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by Bregalad »

It would be less of a bad practice, but still not really great.
The second problem is that you have to use meta-sprites, and fixing how many metasprites an object can have is limitating.

Other than that I don't think there's any problem, assuming objects still have logical X/Y coordinates stored separatedly and copied to OAM every frame. How does most GameBoy and GameBoyColor games handle this ?
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by FrankenGraphics »

Yes, less bad, because the bad thing you want to avoid is

1) cancellation of the rendering of information that is critically important to the user on a frame-for-frame basis.
2) cancellation that offends the users' subjective, aesthetic sensibilities.

imo in that order.

Both are less likely to occur with a more tolerant coverage per scanline.


but honestly, there's no universal law that says what is best/worst practice. If the game relies on z-depth, you can't have universal cycling. Examples: any game that is isometric. any game that relies on depth as a mechanic. any game that is using sprites for background decoration (functional or otherwise). Ideally, you don't want an owl to z-compete with the moon. If you think presentation issues like this are important to adress, you need to divide cycling into tiers, or create special clauses. Assume the moon is high up and most entities are ground bound, it'd be perfectly safe to keep said moon at the lowest z-priority, kept apart from the rest.
Last edited by FrankenGraphics on Sat Mar 31, 2018 9:38 am, edited 1 time in total.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by psycopathicteen »

How can there be a community for a hypothetical 8-bit system that doesn't exist?

I know the people on smwcentral do this, and the explanations I've seen are all like "because rewriting non-animated non-moving sprites will cause slowdown." Even though they end up causing more slowdown by searching through inactive sprites for large objects like Banzai Bills and Big Boos.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by tokumaru »

This is about the Gameboy, right? How the hell do they do sprite cycling if sprite priority is dictated by the X coordinate? Won't sprites to the right ALWAYS get shafted?
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by psycopathicteen »

I don't think drop out on the Game Boy has to do with sprite priority. Although I could swear I remember Game Boy games that use sprite priorities. Are there no Final Fight style beat'm'ups on the Game Boy?
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by rainwarrior »

tepples wrote:But in the community for another 8-bit platform, it's common to hardcode OAM indices for actors, and I'm trying to understand why they do that. The best way I know to do so is to generalize from what I know, and I know the NES. So for comparison, I'll describe the other platform's PPU...
Once again tepples is being intentionally obtuse about something's identity for mysterious reasons. :P

I would say it's quite common for new NES developers to hardcode OAM indices too. It's just that they probably pretty quickly get beat back by the problems that creates. On a system with wider tolerance you wouldn't necessarily create a problem at all.

Overlap is often a big problem in a platform game with a flat plane of play, since gravity brings everything to the same level. But... 4 sprites on one platform is usually a pretty busy situation in NES games already... 8 sprites? How crowded is this?
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by tepples »

Bregalad wrote:It would be less of a bad practice, but still not really great.
The second problem is that you have to use meta-sprites, and fixing how many metasprites an object can have is limitating.
Super Mario Bros. limits each enemy to six 8x8 pixel sprites. Bowser and Fake Bowsers are the only enemies I can think of that use two enemy slots to circumvent this.

Haunted: Halloween '85 reserves 16 tiles of CHR RAM for each enemy's current frame (and 16 for its next frame; it's double buffered). This practically limits each enemy to eight 8x16 pixel sprites per cel. The second, fifth, and sixth bosses use two slots, just as SMB1 does for Bowser.

Another option that's still kinda-sorta hardcoding is to store an actor's starting OAM index in one of the actor's fields, just as you'd store its logical X and Y coordinates, velocity, health, etc.
Bregalad wrote:Other than that I don't think there's any problem, assuming objects still have logical X/Y coordinates stored separatedly and copied to OAM every frame. How does most GameBoy and GameBoyColor games handle this ?
Game Boy Color I think reverts to the NES behavior of relying entirely on the OAM index to determine priority. The "X determines priority" is a monochrome thing. But even if an actor's logical coordinates are separate, the OAM slots into which those coordinates are copied every frame can still be statically allocated.
psycopathicteen wrote:How can there be a community for a hypothetical 8-bit system that doesn't exist?
The "other 8-bit platform" exists. I mentioned the Game Boy by name in the song lyric I quoted at the top of my post. I was describing properties of the system using a famiclone analogy, as if an AVS in extra sprites mode were to apply the same sprite priority algorithm described in the Game Boy Pan Docs.
rainwarrior wrote:intentionally obtuse about something's identity for mysterious reasons
My intent in making the famiclone analogy was twofold. I wanted to explain the problem to people who are familiar with how sprites work on the NES, in order to know how a particular change (more coverage and different priority) would change programming practices. I also wanted to help keep to the topic of OAM index hardcoding in the context of more coverage and X-as-priority, not derail it into a flame war about other unrelated differences between the Game Boy and the NES or between the norms of gbdev.gg8.se and those of NESdev.com. If you would prefer, I could reword this and repost it in GBDev.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by rainwarrior »

tepples wrote:My intent in making the famiclone analogy was twofold. I wanted to explain the problem to people who are familiar with how sprites work on the NES, in order to know how a particular change (more coverage and different priority) would change programming practices. I also wanted to help keep to the topic of OAM index hardcoding in the context of more coverage and X-as-priority, not derail it into a flame war about other unrelated differences between the Game Boy and the NES or between the norms of gbdev.gg8.se and those of NESdev.com. If you would prefer, I could reword this and repost it in GBDev.
I think there would have been less irrelevant chatter if you'd just said "game boy" instead of made a big show of not saying it, inviting people to comment on the way you danced around it.

I don't give a hoot which forum this appears in, but it's NES dev enough to be where it is. I don't see the point in moving it.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by Oziphantom »

If you can do fixed allocation then you do fixed allocation. It saves a lot of clocks and makes code a lot easier. If you can't get away with fixed allocation then you do dynamic allocation.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by psycopathicteen »

What speed benefit does this have?
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by rainwarrior »

psycopathicteen wrote:What speed benefit does this have?
Fixed addresses do not require indexing. Use of an index register has a cycle penalty for some instructions, as well as the general penalty of having one less register to work with.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by tokumaru »

Beginner tutorials often start with controller input directly manipulating OAM slots' properties, and end up never going into advanced sprite topics like meta-sprites or priority cycling, so it's no surprise that a lot of "first games" end up using hardcoded OAM positions for its game objects.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by psycopathicteen »

You would only be allowed one copy of an object at once unless you duplicate code.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: OAM cycling on hypothetical 15-sprite PPU with X as prio

Post by tokumaru »

I know it sucks, but beginners do it. Copying and pasting is often easier to grasp than indexing and indirection for a beginner.
Post Reply