No. Really. Some rocks on the overworld do, in fact, behave like chests. The caveat is that they only behave like chests for the hammer and guard search probes. What is going on?
First, we need to understand how underworld collision works. In the underworld, one room is loaded at a time and its tilemap exists in its entirety in memory at $7E2000 through to $7E5FFF. Each tile is a 16-bit word with a 10-bit tile name that dictates its graphics. That 10-bit tile name is used to look up a tile type in a dynamic table stored in WRAM at $7EFE00 and then stored in a collision map held in memory at $7F2000 through to $7F3FFF.
The underworld's tilemap and collision loading is simple, because only two 64-by-64 maps are loaded at a time—the upper and lower layers. That works out to 4096 tiles—$1000 in hexadecimal—the exact size of your collision map buffers.
The overworld, however, loads 8 times as many tiles! The smaller overworld screens are already 64-by-64, and four of those are loaded at once, even when loading a small screen. How does it have space for that?
Compression.
Instead of storing tilemaps directly, overworld screens are built with metatiles of 2-by-2 tiles which we will call "map16 objects". On the overworld, the memory at $7E2000 is repurposed to hold 8128 of these objects. There are 3744 defined map16 objects stored in a table at $0F8000. Each entry consists of four 16-bit words which constitute the tilemap value of each of the tiles within the map16 object. This table is referenced whenever the overworld needs drawing or updating, or whenever Link, or a sprite, or whatever needs to handle collision.
So which of these definitions works as a chest?
None of them.
While it is true that the vast majority of things look deeper into a map16 object to obtain the tile or tiles it needs, there are several exceptions to this:
First, any interaction that manipulates the overworld, such as cutting bushes or grass, hammering a peg, or bonking a pile of rocks, has a map16 object ID hardcoded into the test logic. For example, the code below is how the shovel checks for diggability:
The next exception is entrances, where tables at $1BB8BF list all the map16 objects that can be used as a valid entrance tile. Without them, entrances cannot even be used. Additionally, the closed door objects that can be opened by touching them are hardcoded as map16 object IDs in the entrance logic routine; although, maybe that falls under the previous category.
The final exception—and this is the oddball—is the routine ReadOverworldTileType, which uses the gigantic OverworldTileTypeTable at $1BF110. This table contains a single byte for every map16 object that dictates a behavior for the entire metatile.
First off, why do the manipulability checks not use this table? Bushes, rocks, and diggable ground, and actually every interaction that has a hardcoded check already has an existing tile interaction type. Except doors, but those could easily be given one! This could have been much cleaner and more expandable.
Next, why does this table exist? It is only used by two things: the hammer for spawning a splash, and search probes for detecting collision. This table embodies an extremely odd and heavy hitting solution to these problems. Search probes could use the existing overworld tile checks that every other sprite uses. They already use the same routines as everything else for underworld tiles. Why are they different here? As for the hammer, it'd be slightly less efficient, but there's no reason it can't just check 4 tiles at once for being water. Why does it need to check map16 objects specifically?
| Map16 ID | Image |
|---|---|
| $02BA | |
| $02C0 | |
| $02F8 | |
| $02FA | |
| $0309 | |
| $0310 | |
| $0502 | |
| $069E | |
| $0D0E | |
| $0D17 | |
| $0D21 |
For some reason, inside OverworldTileTypeTable, there are 11 map16 objects that are given the value of $5C, which corresponds to chest #4. Hammers then test this value for equality to $08 (deep water) and $09 (shallow water), and search probes use it to index a table at $0DB971, which in turn gives the value $00. Really, that value should be $01 for collision, or $02 for short collision, if we're being generous.
So, unfortunately, we can't actually open any chest rocks in the overworld, because they're never considered a chest in that context. But they really are considered chests by the hammer. It just means nothing; they might as well be a wall.
Why is the table like this? I have no clue. I'm not even going to try to guess. I also don't know if there are any other oddities. No other blatantly nonsense values exist in the table, but it could very well be the case that a handful of IDs are associated with something contradicting their graphics. There are just too many to check for me to care.
So what if you wanna hit your own chest rock? Well you can! I have gone ahead and annotated the chest rocks on every screen they appear. Enjoy!