Difference between revisions of "Zelda II: The Adventure of Link/Luck Manipulation"
(5 intermediate revisions by the same user not shown) | |||
Line 10: | Line 10: | ||
For the P Bag drop, the two key windows are the ones at about 1600 frames, and at about 1920 frames. Hit either of those windows reliably, and P Bag drops go from the usual 1/8 chance, to much higher. | For the P Bag drop, the two key windows are the ones at about 1600 frames, and at about 1920 frames. Hit either of those windows reliably, and P Bag drops go from the usual 1/8 chance, to much higher. | ||
+ | |||
+ | = Practical Consequences = | ||
+ | |||
+ | There are a few known ways of getting a PBag that are much better than random at getting the drop. | ||
+ | |||
+ | [http://www.twitch.tv/error72/c/6027800 Error72 has a strategy that is fast and effective], however the "low beam" techniques used in the strategy make it difficult to execute. | ||
+ | |||
+ | [http://www.twitch.tv/simpoldood/c/6127759 Simpoldood has a variant of that visible at the start of this PB run] that is easier to do, but has some hitches and timing that make it less reliable. | ||
+ | |||
+ | [https://www.youtube.com/watch?v=rWTt6pSBP5U My strategy exists] and I've had a lot of success with it. It's slower by about 2 seconds than Error's, and it has a timed hit, but I've personally had the best success with it because I hate low beams. It also sometimes gives a bad encounter pattern on the way to Rauru, requiring a slight hesitation on the way out of the cave, to avoid that. | ||
= Technical details = | = Technical details = | ||
Line 15: | Line 25: | ||
The following comes courtesy of __sdfg on the SDA forums, with permission. | The following comes courtesy of __sdfg on the SDA forums, with permission. | ||
− | + | Here's a bucket of FCEUX for a small drop: | |
<pre> | <pre> | ||
Line 24: | Line 34: | ||
003612: A:06 X:01 Y:01 S:EF P:nvUBdIZC $E8A3:A9 00 LDA #$00 ; It is! Zero the counter for next time | 003612: A:06 X:01 Y:01 S:EF P:nvUBdIZC $E8A3:A9 00 LDA #$00 ; It is! Zero the counter for next time | ||
003612: A:00 X:01 Y:01 S:EF P:nvUBdIZC $E8A5:9D DE 05 STA $05DE,X @ $05DF = #$06 | 003612: A:00 X:01 Y:01 S:EF P:nvUBdIZC $E8A5:9D DE 05 STA $05DE,X @ $05DF = #$06 | ||
− | 003612: A:00 X:01 Y:01 S:EF P:nvUBdIZC $E8A8:A6 10 LDX $0010 = #$04 ; Load | + | 003612: A:00 X:01 Y:01 S:EF P:nvUBdIZC $E8A8:A6 10 LDX $0010 = #$04 ; Load Memory Table Index into X. It's 4 here |
003612: A:00 X:04 Y:01 S:EF P:nvUBdIzC $E8AA:7E 14 04 ROR $0414,X @ $0418 = #$01 ; ??? | 003612: A:00 X:04 Y:01 S:EF P:nvUBdIzC $E8AA:7E 14 04 ROR $0414,X @ $0418 = #$01 ; ??? | ||
003612: A:00 X:04 Y:01 S:EF P:NvUBdIzC $E8AD:BD 1B 05 LDA $051B,X @ $051F = #$82 ; Read RNG byte 4 | 003612: A:00 X:04 Y:01 S:EF P:NvUBdIzC $E8AD:BD 1B 05 LDA $051B,X @ $051F = #$82 ; Read RNG byte 4 | ||
Line 45: | Line 55: | ||
029149: A:06 X:02 Y:02 S:F1 P:nvUBdIZC $E8A3:A9 00 LDA #$00 ; So we zero it | 029149: A:06 X:02 Y:02 S:F1 P:nvUBdIZC $E8A3:A9 00 LDA #$00 ; So we zero it | ||
029149: A:00 X:02 Y:02 S:F1 P:nvUBdIZC $E8A5:9D DE 05 STA $05DE,X @ $05E0 = #$06 | 029149: A:00 X:02 Y:02 S:F1 P:nvUBdIZC $E8A5:9D DE 05 STA $05DE,X @ $05E0 = #$06 | ||
− | 029149: A:00 X:02 Y:02 S:F1 P:nvUBdIZC $E8A8:A6 10 LDX $0010 = #$04 ; | + | 029149: A:00 X:02 Y:02 S:F1 P:nvUBdIZC $E8A8:A6 10 LDX $0010 = #$04 ; Enemy Table Index value is 4 again |
029149: A:00 X:04 Y:02 S:F1 P:nvUBdIzC $E8AA:7E 14 04 ROR $0414,X @ $0418 = #$07 | 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIzC $E8AA:7E 14 04 ROR $0414,X @ $0418 = #$07 | ||
029149: A:00 X:04 Y:02 S:F1 P:NvUBdIzC $E8AD:BD 1B 05 LDA $051B,X @ $051F = #$D0 ; The low 3 RNG bits are 0 | 029149: A:00 X:04 Y:02 S:F1 P:NvUBdIzC $E8AD:BD 1B 05 LDA $051B,X @ $051F = #$D0 ; The low 3 RNG bits are 0 | ||
Line 72: | Line 82: | ||
</pre> | </pre> | ||
− | I made a spreadsheet using the RNG table that powerofthepowerofthe posted (Editor's note: Here are [[Zelda II: The Adventure of Link/RNG Tables|RNG output tables]] | + | I made a spreadsheet using the RNG table that powerofthepowerofthe posted (Editor's note: Here are [[Zelda II: The Adventure of Link/RNG Tables|RNG output tables]] created by powerofthepowerofthe). It seemed to work pretty well: I'd check for updates to $0492, and on the frame I saw the update, I could use the RNG value to check which drop I'd get. |
− | |||
− | Then I started fighting a bunch of bots in a weak encounter over and over and noticed that the drops weren't going into $0492 anymore. It seems the RNG is bigger than two bytes, and the | + | Then I started fighting a bunch of bots in a weak encounter over and over and noticed that the drops weren't going into $0492 anymore. It seems the RNG is bigger than two bytes, and the enemy table index decides both which address should receive the drop and which address should be read to decide the drop. When I kept killing enemies, the enemy table index would change. |
The RNG does update on every frame, so I don't think this will help you manipulate anything unless there's some clump of good drops that you can target by playing at a specific speed. It does teach us that the P-bag probabilities are 1/8 and 1/2, though, unless the sequence for some of the RNG bytes is really wack. Maybe knowing that is enough. | The RNG does update on every frame, so I don't think this will help you manipulate anything unless there's some clump of good drops that you can target by playing at a specific speed. It does teach us that the P-bag probabilities are 1/8 and 1/2, though, unless the sequence for some of the RNG bytes is really wack. Maybe knowing that is enough. |
Latest revision as of 18:10, 8 May 2015
Summary
The Zelda II RNG changes with every frame. In the NES version, the counter starts when SDA timing starts. Generally that doesn't matter, since things will never happen at the same time, but the one key exception is that in any category where the North Palace Magic Container is done first, a 50 point bag can be manipulated.
Opening 50 PBag
Here is a chart of the Zelda II RNG at the start of the game, with a 10 frame moving average. Each bar represents the numbered frame, and the 9 frames preceding.
For the P Bag drop, the two key windows are the ones at about 1600 frames, and at about 1920 frames. Hit either of those windows reliably, and P Bag drops go from the usual 1/8 chance, to much higher.
Practical Consequences
There are a few known ways of getting a PBag that are much better than random at getting the drop.
Error72 has a strategy that is fast and effective, however the "low beam" techniques used in the strategy make it difficult to execute.
Simpoldood has a variant of that visible at the start of this PB run that is easier to do, but has some hitches and timing that make it less reliable.
My strategy exists and I've had a lot of success with it. It's slower by about 2 seconds than Error's, and it has a timed hit, but I've personally had the best success with it because I hate low beams. It also sometimes gives a bad encounter pattern on the way to Rauru, requiring a slight hesitation on the way out of the cave, to avoid that.
Technical details
The following comes courtesy of __sdfg on the SDA forums, with permission.
Here's a bucket of FCEUX for a small drop:
003612: A:01 X:01 Y:01 S:EF P:nvUBdIzc $E899:FE DE 05 INC $05DE,X @ $05DF = #$05 ; Increment 6-count, this time for a small drop 003612: A:01 X:01 Y:01 S:EF P:nvUBdIzc $E89C:BD DE 05 LDA $05DE,X @ $05DF = #$06 ; And then load that value 003612: A:06 X:01 Y:01 S:EF P:nvUBdIzc $E89F:C9 06 CMP #$06 ; And see if it's 6 yet 003612: A:06 X:01 Y:01 S:EF P:nvUBdIZC $E8A1:D0 1C BNE $E8BF 003612: A:06 X:01 Y:01 S:EF P:nvUBdIZC $E8A3:A9 00 LDA #$00 ; It is! Zero the counter for next time 003612: A:00 X:01 Y:01 S:EF P:nvUBdIZC $E8A5:9D DE 05 STA $05DE,X @ $05DF = #$06 003612: A:00 X:01 Y:01 S:EF P:nvUBdIZC $E8A8:A6 10 LDX $0010 = #$04 ; Load Memory Table Index into X. It's 4 here 003612: A:00 X:04 Y:01 S:EF P:nvUBdIzC $E8AA:7E 14 04 ROR $0414,X @ $0418 = #$01 ; ??? 003612: A:00 X:04 Y:01 S:EF P:NvUBdIzC $E8AD:BD 1B 05 LDA $051B,X @ $051F = #$82 ; Read RNG byte 4 003612: A:82 X:04 Y:01 S:EF P:NvUBdIzC $E8B0:29 07 AND #$07 ; Actually, we just need the 3 low bits 003612: A:02 X:04 Y:01 S:EF P:nvUBdIzC $E8B2:C0 02 CPY #$02 ; This is a small drop, so skip to E8B8 003612: A:02 X:04 Y:01 S:EF P:NvUBdIzc $E8B4:D0 02 BNE $E8B8 003612: A:02 X:04 Y:01 S:EF P:NvUBdIzc $E8B8:A8 TAY ; Load the drop at position 2 this time (A=2) 003612: A:02 X:04 Y:02 S:EF P:nvUBdIzc $E8B9:B9 70 E8 LDA $E870,Y @ $E872 = #$8A ; 8A = 50-bag. Nice! 003612: A:8A X:04 Y:02 S:EF P:NvUBdIzc $E8BC:9D 8E 04 STA $048E,X @ $0492 = #$00 003612: A:8A X:04 Y:02 S:EF P:NvUBdIzc $E8BF:A6 10 LDX $0010 = #$04 ; And now we're past the drop code
And for a large drop:
029149: A:02 X:02 Y:02 S:F1 P:nvUBdIzc $E899:FE DE 05 INC $05DE,X @ $05E0 = #$05 ; Increment large 6-count 029149: A:02 X:02 Y:02 S:F1 P:nvUBdIzc $E89C:BD DE 05 LDA $05DE,X @ $05E0 = #$06 029149: A:06 X:02 Y:02 S:F1 P:nvUBdIzc $E89F:C9 06 CMP #$06 ; Which is a 6 029149: A:06 X:02 Y:02 S:F1 P:nvUBdIZC $E8A1:D0 1C BNE $E8BF 029149: A:06 X:02 Y:02 S:F1 P:nvUBdIZC $E8A3:A9 00 LDA #$00 ; So we zero it 029149: A:00 X:02 Y:02 S:F1 P:nvUBdIZC $E8A5:9D DE 05 STA $05DE,X @ $05E0 = #$06 029149: A:00 X:02 Y:02 S:F1 P:nvUBdIZC $E8A8:A6 10 LDX $0010 = #$04 ; Enemy Table Index value is 4 again 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIzC $E8AA:7E 14 04 ROR $0414,X @ $0418 = #$07 029149: A:00 X:04 Y:02 S:F1 P:NvUBdIzC $E8AD:BD 1B 05 LDA $051B,X @ $051F = #$D0 ; The low 3 RNG bits are 0 029149: A:D0 X:04 Y:02 S:F1 P:NvUBdIzC $E8B0:29 07 AND #$07 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIZC $E8B2:C0 02 CPY #$02 ; This is a large drop, so we skip the branch... 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIZC $E8B4:D0 02 BNE $E8B8 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIZC $E8B6:69 07 ADC #$07 ; ...and add 8 (carry is set) to use a different array 029149: A:08 X:04 Y:02 S:F1 P:nvUBdIzc $E8B8:A8 TAY 029149: A:08 X:04 Y:08 S:F1 P:nvUBdIzc $E8B9:B9 70 E8 LDA $E870,Y @ $E878 = #$91 ; Item 0 in that array is a red jar 029149: A:91 X:04 Y:08 S:F1 P:NvUBdIzc $E8BC:9D 8E 04 STA $048E,X @ $0492 = #$00 029149: A:91 X:04 Y:08 S:F1 P:NvUBdIzc $E8BF:A6 10 LDX $0010 = #$04
If X is 1 entering this block of code, you get a small drop. If it's 2, you get a large drop. I think it's skipped entirely if the enemy's not supposed to drop something. I haven't looked into the code preceding it much.
As noted above, 3 bits from the RNG are used as an index into a drop array. In a standard NES ROM with a 16-byte header, you can find the small drop array at offset 1e880 and the large array at 1e888. Here they are:
Small = 9090 8a90 9090 9090 Large = 918c 918c 8c91 8c91 8a = 50-point bag 9c = 200-point bag 90 = Blue jar 91 = Red jar
I made a spreadsheet using the RNG table that powerofthepowerofthe posted (Editor's note: Here are RNG output tables created by powerofthepowerofthe). It seemed to work pretty well: I'd check for updates to $0492, and on the frame I saw the update, I could use the RNG value to check which drop I'd get.
Then I started fighting a bunch of bots in a weak encounter over and over and noticed that the drops weren't going into $0492 anymore. It seems the RNG is bigger than two bytes, and the enemy table index decides both which address should receive the drop and which address should be read to decide the drop. When I kept killing enemies, the enemy table index would change.
The RNG does update on every frame, so I don't think this will help you manipulate anything unless there's some clump of good drops that you can target by playing at a specific speed. It does teach us that the P-bag probabilities are 1/8 and 1/2, though, unless the sequence for some of the RNG bytes is really wack. Maybe knowing that is enough.