I put off doing attributes for a long time because I didn’t want to face the nightmare. When I finally sat down to do it the other day, it was extremely fast and easy to implement. The reason? No scrolling.
What’s an Attribute?
The NES has 4 screen-sized pages that you can draw background tiles to. These pages are called nametables. Each nametable has an attribute table associated with it. An attribute table specifies what palettes are used for the different tiles in the nametable. So basically the nametables control what tiles are seen, and attribute tables control what colors those tiles are.
The NES PPU (Picture Processing Unit) maps the attribute tables to the nametables in a very unintuitive way (see this tutorial), which makes working with attribute data a real pain. This is especially true when scrolling is involved as you may have portions of two different nametables on the screen at the same time. The ultimate nightmare is four-way scrolling where you can cross horizontal and vertical screen boundaries at the same time. I foolishly attempted a four-way scrolling engine as my first NES project and attribute tables left a bad taste in my mouth. So I wasn’t looking forward to dealing with them again.

Leftover attribute nightmare from my first attempt at a 4-way scrolling engine.
But as I mentioned, attributes aren’t so bad when there is no scrolling going on. The Explorer game I’m writing shows one room at a time, and I don’t think scrolling will be necessary when changing rooms. I think I will be able to get away with turning off the PPU, drawing the new room in one go, and then turning the PPU back on. This will cause the screen to black out when changing rooms, but only for a second. I don’t think it will be too distracting. We can take a peek at Sivak’s platformer demo to see how this method looks:
Looks just fine to me! So Plan A is to ditch scrolling altogether and instead toggle the PPU off and on when changing rooms. This should save me some headaches when dealing with the attribute tables.
Implementation
When I load a new room, I turn off the PPU. Then I draw the room. Then I color the room (write the attribute data to the attribute table). Then I turn the PPU on. The trickiest part of this process is figuring out what to write to the attribute table.
My test data consists of rooms built from seven possible 2×2 metatiles (16×16 pixels). The first thing I do is assign each metatile a palette number. I don’t like to hardcode any number values in my data, so I give everything an alias using ca65’s .ENUM directive. First the tiles ids, which are used in the map data:
.enum
floor ;these are my tiles, numbered $00-$06
wall
block
water
block_breakable
stairs_up
stairs_down
.endenum
Then the palette ids:
.enum
orange ;my four bg palettes from $00-$03
gray
blue
brown
.endenum
Finally, the attribute assignments for each tile in order:
tile_attribs:
.byte gray ;floor
.byte brown ;wall
.byte orange ;block
.byte blue ;water
.byte orange ;block_breakable
.byte gray ;stairs_up
.byte gray ;stairs_down
With this setup, I can read a tile number from my map data and then use that value as an index into the tile_attribs table. Once I’ve read the palette number from the tile_attribs table, I can do a shift/roll combo to sneak that 2-bit value into an attribute byte:
;-------------------------------
; make_attrib takes a map index in x and creates an attribute
; byte for the metatile box (32x32 px). x is the top-left tile.
make_attrib:
lda room, x ;top left
tay
lda tile_attribs, y ;get the palette number
sta map_temp2
lsr map_temp2 ;shift a bit into the carry flag
ror map_temp1 ;roll the carry flag into a temp var
lsr map_temp2 ;and repeat for the second bit
ror map_temp1
lda room+1, x ;top right
tay
lda tile_attribs, y
sta map_temp2
lsr map_temp2
ror map_temp1
lsr map_temp2
ror map_temp1
lda room+16, x ;bottom left
tay
lda tile_attribs, y
sta map_temp2
lsr map_temp2
ror map_temp1
lsr map_temp2
ror map_temp1
lda room+17, x ;bottom right
tay
lda tile_attribs, y
sta map_temp2
lsr map_temp2
ror map_temp1
lsr map_temp2
ror map_temp1
rts
Looping across the room data I can build a full attribute table in RAM. Then I can simply copy it over to the PPU when PPU rendering is off. It works!
Before:

Here's what a room looks like before attributes
After:

Here's how the room looks with proper attribute data.
Please forgive the ugly tiles. I’m no artist. They will all be replaced in the future. :)
Conclusion
Attributes are done! Room decompression works! I can display rooms correctly! The next step is to design a multi-floor, multi-room test level and make it possible to navigate between rooms. That will likely take me some time, so my next few posts will be about my room data format.

Awesome man, it will be cool to see how you do things. I grabbed your RSS : )
I’ve been really busy lately and haven’t had time to do much devving, so that’s a bummer. Oh well, there will be time some time! haha
@Rob: Thanks for checking the blog out! Feel free to comment anytime. My wife has no interest at all in NESdev, so I don’t get a chance to discuss my project with anyone very often :)
Btw, are you still working on that zombie game?
All my devving is on hold for lots of reasons right now; computer time is limited! But yes, it’s still in the works and what-not. I have some stuff to recode though, as I learned newer techniques that I wasn’t employing when I started the project. So is the way of things haha!
[...] Tummai Games development blog for NES games « Explorer: 2 – Attributes [...]
@Rob: I hear you. Family life comes first :) I’m a little lucky that I can get some nesdev time in at work. There’s quite a bit of downtime teaching English in a Japanese Jr. High School. It’s only going to increase too once summer vacation starts in a week :)
Hope you can get back into coding your game someday. That intro looked great!