I thought a little more about storage. I think uncompressed nametables might actually be okay, if I use all 16 UNROM banks.
Each nametable is 1024KB, or 4 pages. For each nametable (from here on, a
room) I need to store some metadata, so the total structure for each room can be:
Code: Select all
* Nametable data (960 bytes)
* Attribute data (64 bytes)
* Room ID (2 bytes)
* Object List: for (max_objects = 30):
* -->Object type (byte)
* -->Object data/flags (byte)
* -->Object X pos (byte)
* -->Object Y pos (byte)
* World Map X pos (byte)
* World Map Y pos (byte)
With this, each room is 1280 bytes. That means I can fit 25 rooms per UNROM bank, with 768 bytes to spare. So, that means I can dedicate a large chunk of UNROM banks to just storing level data. With 12 banks, I can fit 300 rooms.
Alternatively, I could store only 28 rows of a 30 row nametable. That would make me lose the top 2 rows of tiles, but I would be able to fit an entire level structure within 1024KB, which would allow my UNROM banks to be very neatly divided (32 rooms per bank). Losing the upper 16px isn't a big deal, as many TVs overscan most of it anyway. I may go with this in the end.
A 100% dense 20 x 15 room world map would be the max size, but many games of this type don't fill 100% of a square area. So, I think I can create a sufficiently large world this way using just uncompressed nametables. If I felt super-constrained, I could A) implement the most basic compression, or B) use UNROM_512 for 32 banks, like Battle Kid does. Bankable CHR could let me do some simple environmental animation without eating NMI time, which would be appealing.
I may be able to forego the Room ID, but as I plan on having over 256 rooms I'd like to ensure I can access rooms without relying on a lookup table.