Difference between revisions of "Zelda II: The Adventure of Link/Luck Manipulation"

From Red Candle
Jump to: navigation, search
 
(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.
  
Anyway, here's a bucket of FCEUX for a small drop:
+
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 Mystery Value into X.  It's 4 here
+
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  ; Mystery value is 4 again
+
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.
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 "mystery value" decides both which address should receive the drop and which address should be read to decide the drop.  When I kept killing enemies, the mystery value would change.  I don't know anything about the Zelda 1 RNG, so maybe that's normal, but it might be necessary to look into the RNG algorithm a bit more to account for this behavior.  If it is normal, then we just need to determine how the mystery value is set.  If there's a Zelda 1 mystery value with known behavior, then fantastic.
+
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.

zelda2-droprate-movingaverage.png

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.