I'm starting a new thread to discuss/document strategy for the Any% Damageless category. Feel free to add whatever you like!
To start, here's a guide on how to do the long route of Level 2-4 (no wall clipping required). My method is 2 minutes slower, but once you learn each room, I think it is much easier than the wall clip route:
In the video I point out a bug that significantly reduces the entropy in the randomness of the swarm rooms (to the extent of entirely removing several movement patterns). Here are all the possible spawn locations (for EVERY Level 2-4 swarm room) and what they imply about the direction the enemies will take:
It didn't happen in the guide when I recorded it, but there is a 1/5 chance that you will have to deal with a spawn like this one in the first swarm room:
You have to deal with this room no matter which route you take, so I think it's worth learning to react to that pattern.
Technical information:
There is a random number (at $26) that changes multiple times per frame in a routine at $EB21. The routine goes like this:
LDA $26 ROR A ROR A CLC ADC #3 CLC ADC #$20 STA $26 RTS
Something unusual about this is that the state of the carry bit at the start of the routine is factored into the randomness (via ROR). In C, this would look something like:
uint8_t rand; void rotate(uint8_t carry_bit) { rand = (rand >> 2) | (rand << 7) | (carry_bit << 6); rand += 0x23; }
But what is interesting is that the carry bit is almost always unset. In fact, I think in maze levels it will always be unset. I'm not familiar enough with the code flow yet to be 100% sure (there is a lot going on lol), but this has always been the case for me.
Assuming this is reliably true: The random number ends up cycling through the same 5 values over and over. It starts at 0 (because most of the zero page gets wiped when you start the maze level), and then the cycle goes 00 -> 23 -> AB -> CD -> D6 -> 58 -> 39 -> B1 -> CF -> D6 (and then it keeps looping those last five values).
Anyway, when an enemy in the swarm room is spawned, it does something like this in $8800 (bank 6) to set the position/direction of that enemy:
x = fixed_position_x + (rand >> 4) y = fixed_position_y + (rand & 0x3C) >> 2 movement = fixed_movements[rand % 8];
But because rand can only be 5 values, this means:
- We don't get to see all the swarm movements (there is a vertical one!)
- We know which way an enemy is going to move based on its position, before it starts moving. In practice it's difficult for me to consistently distinguish between the down-left and left spawns, but the others are noticeably different. (This is relevant for the first swarm room as shown in the clip)
There is a 1/5 chance that an enemy will move left, a 1/5 chance they will move down-left, and a 3/5 chance they will move some kind of down-right
I thought that was pretty cool so I wanted to share it! :D
Thanks for this info and congrats on your damageless run! I'm hoping to catch some of your streams soon.
This is great research. A deep understanding of these rooms can be helpful for every category. Even if we can't fully manipulate the RNG, it's helpful to know the odds (like 1/5). I think you're the first person to detail the RNG routine in this way.