This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Attempt 1 at an object system

Attempt 1 at an object system
by on (#152662)
I've been working on making an object system that can work with what I have in mind for a game engine.

  • 6 sprites are reserved for the player (2x3 sprites)
  • 3 sprites are reserved for the player's weapon (Which hasn't been implemented yet)
  • Right now I've made it so that there can be at most 3 2x2 sprite Enemy objects in a screen. I could change this, but I think it's enough for the type of game I have in mind (Which is focused more on exploration rather than constant action.)
  • The rest of the sprites can be used for everything else; enemy projectiles, powerups, etc. (Which also haven't been implemented yet)
  • There's no animation right now. I decided that I should make the object system first and have a seperate system for animation, and trying to make both at the same time would unnecessarily complicate things.
  • Chr ROM

Any thoughts, feedback, or input on my design would be appreciated, I'd like to know if I'm taking the right approach, if something could be improved/optimized/etc. I tried to comment all the subroutines and variables to make it easy to understand, but if there's anything cryptic, I'd be happy to explain it.

Re: Attempt 1 at an object system
by on (#152710)
Hardcoding objects to OAM locations is not a good practice, unless the game is really simple and you're sure there will never be more than 8 sprites in a scanline. If the player and his weapon (which use the highest priority sprites) and a few enemies end up in the same scanlines, some enemies might disappear completely. Also, the way in which you use several big routines to handle the sprites of the different types of objects is a little clumsy.

The recommend way to use the OAM is to fill it differently every frame, so that the priorities of the sprites change every time, causing objects on the screen to flicker when there are too many on the screen, instead of some objects disappearing completely. So I recommend you stop using these hardcoded labels at $0200-$02FF, and start using indexed addressing to output sprites to that region, starting fresh every frame. The actual "randomization" algorithm you're going to use to cycle the OAM positions can vary a lot, most people play with the possibilities a bit before deciding on a particular solution. One common technique is to start outputting sprites at a random position in the OAM, and advance a prime number of spaces (such as 17) after each sprite, wrapping around when the index goes beyond 255.

Indexed addressing allows you to read data from an indexed object, and output sprites to indexed OAM positions, meaning you only need one (admitedly big) routine to read from any object and write to any OAM position, instead of several routines.