What is OAM

#1

I hear about OAM but I don’t know what it actually is except for the fact that animations are related to it and that OAM overload is bad, so I would like to know what it actually means so it can deepen my understanding

1 Like
#2

OAM stands for “object attribute memory”. In short, it’s space in Video RAM where sprites are split up into 8x8 tiles, which can be assembled and put anywhere on the screen (unlike backgrounds, which have to be put together on a grid and cover the entire screen space). OAM also stores the position of each of these tiles on the screen. (Backgrounds have their own space in VRAM, but since their position is always fixed to cover the whole screen, they don’t need to store positional data the same way that sprites do.)

When you insert an animation (or export one via FEBuilder), you’ll notice that “Sheets” are created, which are images with the pieces of the animation all chunked up into these 8x8 tiles. As the animation runs, it will swap out these “sheets” in OAM and assemble the sprite from it. A larger sprite, or an animation with more frames, takes up more “sheets”. The game needs to keep some OAM free for the enemy’s sprite, weapon icons, etc, so not all of the OAM space can be used for a single battle sprite.
(I don’t recall the max number of sheets the animation engine can load for a single animation, but from anecdotal evidence it appears to be 5).

This is also why you can only have 3 portraits on screen if you have map sprites showing, and 4 if you’ve got a background over the conversation. Portraits are treated as really huge sprites and take up almost all the available OAM space.

Some sprites, like Fomortiis/FE6 Enemy Manaketes/Idunn have part of the sprite as a background layer to avoid this, sacrificing some animatability in the process. (e.g. Fomortiis’s body is its own background layer, while it’s his head and arm that move.)

7 Likes
#3

Short answer:

OAM stands for Object Attribute Memory. You can only have 128 objects at any one time; any extras won’t display, and big or complicated animations can take up a lot of objects, leading to OAM overflow.

Long answer (aka a primer on GBA graphics in general):

Graphics in the GBA can take two different forms: backgrounds and objects (or sprites; I use the terms more or less interchangeably). When dealing with graphics, we don’t directly work with individual pixels, but rather 8x8 blocks called tiles.

An image consists of graphics, palette, and possibly TSA.

  • Graphics are a plot of which color goes to which pixel. For example, first pixel is color_1, second pixel is color_3, etc.

  • The palette tells us what color color_1, color_3, and the rest actually are. For example, color_1 is pink, and color_3 is green.

  • TSA (which stands for Tile to Screen Arrangement) maps tiles from the graphics to recreate an image. This is useful if your image consists of a few tiles that are repeated.

    Example:
    Say your graphics consists of 3 unique tiles, which we shall call 0, 1, and 2, and your image consists of said tiles in the following order:
    0 2 1 0 1 0 2
    1 1 2 0 1 1 2
    2 1 0 2 0 0 1
    Then your TSA would say “the first tile of the image is tile 0, the second tile is tile 2, the third is tile 1”, etc.

  • TSA saves space in the ROM, because you don’t need to save those repeated graphics, at the expense of time, because the game needs to use the TSA to put the image together before displaying it.

  • TSA is necessary if you use multiple palette banks! It can also be used if you want to flip (vertically or horizontally) tiles.

To display an image, first we have to decide whether it’s a background or an object, and I’ll go into which one you would pick and why later.

Next, we copy the graphics into the Tile VRAM (vram stands for video random access memory; all the graphical stuff is stored here). There’s a section for background tile VRAM and sprite tile VRAM, but they function the same way, so it doesn’t matter at this stage which one we picked. Here are pictures of what the tile VRAM looks like on the FE8 start screen, using no$gba’s VRAM viewer:

Tile vram

image
Tiles 1 (background)

image
Tiles 2 (background)

image
Object layer (sprites)

Ok, that’s the graphics set up. Now we want to make sure the image uses the correct colors, so we copy the palette to a bank in palette RAM. A bank is a row of 16 colors, and there are 16 banks for backgrounds and 16 banks for sprites.

Palette viewer

image

Finally, we have to construct the image. Here’s where we differ, depending on whether it’s a background or a sprite.

Backgrounds

There are 4 background layers, labeled 0-3. They all function in the same way; which one you use to draw your image on depends on what else you have to display.
A layer consists of a 32x32 tile grid. Each tile is associated with a tile number (and any flipping that may need to be done) and a palette bank number. The tile number refers to, well, tile VRAM. The first tile is tile 0, the second tile is tile 1, etc. The palette bank should be pretty clear, too; it refers to which bank to use with the graphics.

If you have TSA, this is where it comes into play. In fact, if you set it up properly, you can just copy the TSA directly to the relevant background’s buffer and be done with it.

For those interested in what the data looks like in memory, each tile is a short as follows:
PPPP VHTT TTTT TTTT
T = tile number (10 bits, so can go from 0 to 0x3FF)
H = horizontal flipping flag
V = vertical flipping flag
P = palette bank id (4 bits, so can go from 0 to 0xF)

Objects

Objects are, I would say, collections of tiles that are manipulated as one entity. Rather than dealing with 1 tile at a time, you deal with, say, a 8x8 group of tiles, all of which share the same palette (and other attributes) and are moved around together. Unlike backgrounds, however, sprites aren’t locked to a grid, so they can be moved pixel by pixel rather than tile by tile.

Objects are only allowed to be a rectangle of certain dimensions. Here’s what they are, in pixels:
image
So the smallest is 8x8, and the largest is 64x64. If you want to make a larger image, you have to string multiple sprites together. For instance, you can (kinda) see that the FIRE EMBLEM banner is made up of 5 sprites when we look at the OAM viewer:

OAM viewer

image

There is a limit of 128 objects at any one time. Something like a battle animation or a spell animation will be broken up into many sprites. Then there’s also all the other things on the battle screen to look out for. Let’s take a look:

OAM and Obj Tile RAM

image
image

If your animation is too large or too complicated, then the game won’t have room for either the number of objects, or the tile ram (which one depends on how FEditor/FEBuilder turns your animation into data to put in the ROM, which I’ve never really looking into). This is called OAM overflow.

The attributes part of OAM encompasses basic things like size, coordinates, and palette, but you can also do affine transformations (basically, scaling and rotating). Unfortunately, I have no experience with this, so I can’t really explain further.

Which one to use?

There’s nothing about a graphic that says “this has to be a sprite” or “this has to be a background”. In fact, functionally, they’re not all that different. It really comes down to what you space you have open at any given time.
Generally, backgrounds are good for big things that don’t have to move around, while objects are useful for small images that either need to move or aren’t going to neatly adhere to a grid.

For more info, read TONC.

9 Likes
#4

Thanks, it makes a lot more sense, but also is this the reason why flyers and large creatures are difficult to animate (like the lord sprite I made and Ridley)? If so, that’s that will a major hoo boy

1 Like
#5

Yes, that’s correct. Larger animations take up more oam per frame and thus usually end up more choppy to fit within oam.

3 Likes
#6

Guess that means I will have to make things shorter, wish Usenti had a scale option, but alas there isn’t, guess I will probably need backgrounds for animations then.

1 Like