If you've ever seen me talk, you've probably seen me say "west somaria". The basic concept of them is super simple: opening doors. West somarias are nowhere near as damaging as the other directions, but they are way cooler. Except for a couple oddities, the west somaria doesn't do much to break the game. In fact, most of what goes on only requires understanding vanilla routines to explain. Oh boy!
West somarias put the game into dungeon submodule $04
. This is the submodule used for unlocking key doors. Shutters doors are controlled with a different submodule. All that submodule does is call the routine UnlockKeyDoor
every frame. Here's what that routine does:
Y
to 2
. Y
will be used later for graphics.$0690
.$0690
and compare it to 4
.
4
, set the door's graphics to be half-open and play the door opening sound effect.Y
twice and compare $0690
to 12
If it is not 12
, then continue on.
12
:
$068E
into X
. This address currently holds the index into the graphics buffer of the door we're working with.X
to index the buffer at $7F:2000
and load the value into A
.A
with $0007
, double it, and transfer it to X
.X
to index a table at $00:98C0
. The value retrieved will be a single bit. That value is used to set that bit for addresses $068C
and $0400
, the latter of which is used to update save data when the next transition occurs.$0690
and compare it to 16
.
16
, exit the loop and continue the routine next frame.16
, continue on with the loop.0
.You should notice that the routine isn't what sets the initial values of $068E
or $0690
. This is the responsibility of the routine that set the game submodule. That makes sense. How would a loop running every frame know what step its on by itself?
The fun comes from the fact that we have very reliable ways to set these addresses ourselves.
$068E
This address is what's used to index the last tile map character used for door code. It's used in a few ways:
$0016
.$0016
.There are a couple notes to cover with the way $068E
is set.
Big key doors set $068E
irrespective of owning the big key because the logic simply does it before checking if you own the big key. I don't think it was actually necessary to do things in this order, but it doesn't have any negatives either.
Shutter doors use $068E
as a loop counter. That makes sense, because the routines are checking every door to see if they're a shutter when trying to open them. Shutter doors are controlled with submodule $05
, which counts from $0000
to $0016
in steps of 2. This is the same reason intraroom transitions give the same value. They may not be doing anything every time, but they are still checking for any shutter doors.
The thing that should stand out is how slashing can be used to set the value to whatever door we want. This is how the vines in Skull Woods and the curtains in Agahnim's Tower work. The tile's graphics are stored first just because. No reason for or against it, that's just when it happens.
$0690
Dollar six ninety is what the door routines use as a timer. Even though it doesn't need to be, it's a 16-bit timer, probably because everything else related to doors is 16-bit. It gets incremented before a comparison is made. For west somarias, the target is being equal to $0010
. Not greater than. Not greater than or equal. Just equal. Even if you don't think a timer will ever go over some value, maybe you should check for greater than as well. It doesn't cost you any cycles or ROM space.
The rules of the timer mean that unless you are pushing your crimson cube with a timer of 15 or less, you will be waiting a long time for those doors to open. How long? 65,536 frames to be precise. Just a little over 18 minutes.
Here are the rules for how $0690
is set:
4
.16
.16
.0
.0
. The key will also not be used.3
.1
.1
.1
.I'm not really sure what those last 3 use the value for... but they're sort of important to know if you're lifting a bunch of rocks after getting a workable value. Why are you lifting so many rocks?
That's everything vanilla that needs to be covered. Isn't it great how I explained how this glitch works just by dissecting vanilla routines working as intended? Now it's time to look at the stuff that isn't supposed to happen. Well, the stuff that definitely isn't supposed to happen. West somarias mostly make stuff that's supposed to happen at the wrong time. Let's look at the stuff that's not supposed to happen ever.
When rooms are loaded, every door checks the corresponding bit in memory to see if it should be opened. Normally, the logic for setting these "opened door" bits include a check for tile type, but that only prevents the bit from being set there. If the bit is already set, then the routine continues and allows it to stay open.
As per above, trap doors whose bits are set will remain open, but this causes another weird quirk. If a door is open, its current tile type is used to open the door on the other end. This can cause doors that are normally only shutters door on one half to become shutter doors (that are permanently open) on both halves. One such example being the door to the Misery Mire big chest.
If the object at the tile address just isn't a door, it will cause an erroneous change to the tile and collision maps. One such possibility results in a an entrance door tile being put at the top-left-most tile. You aren't able to reach this too easily, but if you could, the game would try to bring you to the overworld. If the current room has no entrance associated with it (EG1 only), then you just get stuck in an infinite loop while the game fails to find a matching entrance.
West somarias corrupt the game submodule to 4, which is used when opening a key door. The parameters to this submodule's routines are meant to be set on the previous frame, usually via intended methods such as touching a key door with a key. The parameters are changed in very predictable and manipulable ways, such as slashing a door or transitioning. This makes opening specific doors with a west somaria fairly easy, at least in theory.
Shutter doors will remain open because they are actually assigned door numbers that do indeed correspond to bits in SRAM. Because code is shared for this, they will use those bits to determine what to do when the room is loaded.