More than 64 metatiles

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

Post Reply
iamooos
Posts: 16
Joined: Tue Oct 18, 2022 2:37 pm

More than 64 metatiles

Post by iamooos »

i am not sure if this is a hard limitation but i havent been able to do more than 64 metatiles.

i don't think i can do with so few metatiles for what i want to do.

i heard final fantasy did metatiles up to 256? by storing them directly in the tileset?

i tried it but in one tileset i could only get 64 metatiles. and it was not a good use of space cause i had a bunch of repeat tiles.

on one hand it could be useful to have metatiles with different attributes but i am losing so much real estate in the character set.



or maybe i did not understand really how they did it?
is it possible to have metatiles past 64? how could it be done?
User avatar
Individualised
Posts: 310
Joined: Mon Sep 05, 2022 6:46 am

Re: More than 64 metatiles

Post by Individualised »

This is very vague. The NES does not have "metatiles" as a hardware feature, metatiles are a software feature implemented by games that can mean multiple things and can vary in implementation, so there's no hard limit on them. Could you explain more about what you want to do/what you're trying to do?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: More than 64 metatiles

Post by tokumaru »

If you're just taking groups of 4 tiles from the pattern table and calling them metatiles, then yeah, you can only make 64 of them from 256 tiles, but that's not how most games do it. Games normally have extra data for metatiles indicating which 4 tiles to use, which palette to use, and sometimes, collision and/or behavior properties.

If each of these extra properties goes in a separate table, you can easily access 256 elements in each table, allowing for up to 256 metatiles. If you have the RAM for it, you can simply reserve 256 bytes for the "top left tile" table, 256 bytes for the "top right tile" table, and so on, populate these tables at the beginning of each level, and by placing the metatile index in X or Y, you can access all the properties of that metatile.

If you don't have that much RAM (only a game with extra RAM on the cartridge would have that much RAM to spend on metatiles), you can still use the exact same concept, but instead of accessing the tables using absolute addresses, you'd have pointers in ZP indicating the addresses of all the tables, which could be anywhere in ROM.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: More than 64 metatiles

Post by Dwedit »

Every 16x16px metatile has a list of 4 physical tile numbers are used, then which attribute value is used.

The exact order of the bytes may vary from game to game, but you'll see something like that in every game that uses 16x16px metatiles.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: More than 64 metatiles

Post by tepples »

There are some variations, however.

Super Mario Bros. has four metatile tables, chosen based on the top 2 bits of the metatile ID. This means there's one for metatiles $00-$3F, one for $40-$7F, one for $80-$BF, and one for $C0-$FF. It also determines which attribute value to use based on those 2 bits.

Full Quiet and Garbage Pail Kids have a nested metatile structure similar to Blaster Master, with 8x8 inside 16x16 inside 32x32 inside 64x64. FQ and GPK assign attributes not at the 16x16 layer but at the 32x32 layer, allowing reuse of a 16x16-pixel metatile with different colored lighting. Thus they store 13 different metatile tables per background type: 16x16 top left, 16x16 top right, 16x16 bottom left, 16x16 bottom right, 32x32 top left, 32x32 top right, 32x32 bottom left, 32x32 bottom right, 32x32 attributes (note), 64x64 top left, 64x64 top right, 64x64 bottom left, and 64x64 bottom right.
iamooos
Posts: 16
Joined: Tue Oct 18, 2022 2:37 pm

Re: More than 64 metatiles

Post by iamooos »

ah, i think i understand what you mean now.

i was trying to make an array bigger by saying [1024]
but that wasn't working. i need to use more than one array, that makes sense.

is it because 8 bit architecture can only handle a 256 long number?

that explains a lot lol.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: More than 64 metatiles

Post by Pokun »

"8-bit architecture" basically refers to the size of the accumulator which is 8-bit. It just means that you can load up an 8-bit value at a time, which is great for 8-bit values and a bit worse for other data sizes, but there is no limit how large values you can handle.
In a game you probably seldom needs more than 16-bit values though. To do 16-bit math you just have to handle each byte separately, tutorials like Nerdy Nights should explain how to do that with the carry flag, 6502.org also has many good documents.

To handle an array that is larger than 256 bytes requires using a nested loop (which you need to do to fill the entire screen with tiles). Often you just use both X and Y as loop counters.



There are also various ways of doing data structures and how to access them. For example for metatiles I do something like this:

Code: Select all

metatile_addr:
  .word mtl0,mtl1,mtl2,mtl3

mtl0:                     ;void
  .byte $20,$20           ;topleft & topright BG character
  .byte $20,$20           ;bottomleft & bottomright BG character
  .byte %00000000         ;attributes

mtl1:                     ;grass
  .byte $90,$90           ;topleft & topright BG character
  .byte $90,$90           ;bottomleft & bottomright BG character
  .byte %00000001         ;attributes

mtl2:                     ;wall
  .byte $91,$91           ;topleft & topright BG character
  .byte $92,$92           ;bottomleft & bottomright BG character
  .byte %00000110         ;attributes

mtl3:                     ;water
  .byte $93,$94           ;topleft & topright BG character
  .byte $95,$96           ;bottomleft & bottomright BG character
  .byte %00000111         ;attributes
Here each metatile consists of 4x4 BG characters and has 4 bytes for the 4 chara and a 5th byte for attributes (like the subpalette number and terrain flags such as a solid flag that means the player can't pass it if set).
At the top there is also a word-table which stores the start address for each metatile. This is what I use to load them from a single-byte index number.

To load a metatile you do this:

Code: Select all

  lda #$03             ;load metatile #3 (the water tile)
  asl a                ;x2 for indexing to a word-table
  tay
  lda metatile_addr+0,y
  sta pointer+0
  lda metatile_addr+1,y
  sta pointer+1        ;store metatile data address in pointer

  ldy #$02
  lda (pointer+0),y    ;load byte 2 (bottomleft BG character)

Here I load the metatile number I want into the accumulator, I wanted the water tile (mtl3) so I load the value 3. Then do a left-shift (which is same as multiplying with 2) to navigate the word-table, where the start address for each metatile data chunk is, via indexed Y. The loaded metatile address is then stored into a pointer (a pointer must be 16-bit and located in the zero page).
Finally I wanted to see the bottomleft BG chara of the metatile, bottomleft is byte 2 so I load Y with 2 and use it to do an indirect indexed load of the metatile data. The bottomleft BG character should be BG CHR number $95 (according to the metatile data above) where I supposedly have drawn a nice 4th of a water metatile, so that is what is loaded to A at the end of the code. Now I can draw that to VRAM or do whatever else I wanted to do with it.

So using a single byte for a metatile number you can load up to 256 possible metatiles 0~255, and each metatile can use whatever BG characters you want.
If you should need more than 256 you could easily add another byte to use as a sort of bank number for switching the metatile table, and now you have more than you need (and possibly have space for).
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: More than 64 metatiles

Post by Dwedit »

Five tables:
* Upper Left tile number
* Upper Right tile number
* Lower Left tile number
* Lower Right tile number
* Palette number

Each table can be up to 256 bytes large, and can be addressed using ABS,X or ABS,Y addressing mode.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: More than 64 metatiles

Post by tokumaru »

You may also need an extra table depending on how you decide to handle collisions and interactions with metatiles. If you only use 2 bits for the palette, there'll be 6 bits left in the palette byte for other attributes, which you can use for solidity, destructibility, harmfulness, and so on. If 6 bits is not enough for everything that blocks can do, then you'll need another table.

Sometimes I hear about people using separate maps for collision, instead of assigning solidity properties to the metatiles themselves. That never seemed like a good option to me, because in addition to using much more space (each instance of a metatile needs its own copy of the collision properties, rather than just the original), it's also more work for the level designer, who'll be making 2 maps for each level instead of 1.
User avatar
Individualised
Posts: 310
Joined: Mon Sep 05, 2022 6:46 am

Re: More than 64 metatiles

Post by Individualised »

An advantage of having a separate collision map is that you don't have to make visually identical metatiles with different collision. Useful for games similar to Donkey Kong Country or Earthworm Jim where the fact that they're tile-based platformers is less obvious.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: More than 64 metatiles

Post by Dwedit »

Making two visually identical metatiles isn't really a problem because you have only 256 physical tiles to work with. You're not likely going to run out of metatiles because you had too many different kinds of fake walls.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: More than 64 metatiles

Post by tepples »

Full Quiet has numerous cases where it uses the same 16x16-pixel bit of graphics as a tree trunk that the player can pass in front of and that monkey-like enemies can climb behind, as a tree trunk that the player can pass behind and that monkey-like enemies can climb in front of, and as a tree trunk that stops the player. In part because of this, and in part because of aggressively hiding the tile grid, the game uses a separate collision map. Even with the separate collision map, we still had to make the artist rein in graphical complexity so as not to exceed the limit that I imposed of 256 distinct 16x16-pixel metatiles in a mapset.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: More than 64 metatiles

Post by tokumaru »

I generally prefer to have all collision and behaviors attached to the metatiles themselves... As a player, I expect things that look the same to also behave consistently, otherwise the gameplay experience may become frustrating.

I understand that in some cases, game maps have hidden layers behind the graphics we are able to see, and in those cases it can indeed be beneficial to model the world separately from its visual representation, but I see that as the exception in 2D games. In the majority of 2D platformers, the number of blocks that look the same but behave differently is not large enough to consume a significant number of metatile entries.

Programmers must be able to determine how different the structure of the game world is to the rendered graphics in each game in order to decide what the best approach is.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: More than 64 metatiles

Post by Pokun »

Yeah like those false floors/walls in Metroid and Zelda 2 or the rare unorthodox solutions to Eggerland puzzles. You need to be consistent before you can trick the player and you should probably think carefully when to trick the player if it's to be done at all.


I didn't mention it in my post above, but in the example code I posted, the attribute byte is used both for the tile color attribute (bit 0 and bit 1) and a solid flag (bit 2). Note that the solid flag is 1 on the wall and water tiles indicating that those are impassable tiles, and 0 on the void and grass tiles which are passable tiles. The tile color attribute bits would have to be shifted left up to 6 times to get into the right place in the attribute table in VRAM depending on where in the attribute block it is drawn on the screen.
Post Reply