» Tutorials » Special Reference: Shiny Hunting

Special Reference: Shiny Hunting

Due to the newly risen discussion about the so-called Shiny Hunting and the postulation of some people to prove the validity of 'Shiny Hunting', I now post a reference about this concern.

Since all these doubting people want a 'technical statement', the following won't be easy to understand if you don't like numbers, probabilities and computer-terms. So if you are just another pokemon player who tries to find 'the final answer' to why-the-hell-don't-i-get-any-single-shiny-with-this-tactic (which is btw 42, as you all know) then quit reading here.

Warning: After reading this document some people will have to accept a 'uncomfortable' truth. Don't go on if you can't live with the existence of 'Shiny Hunting'. (Yes, I'm a little bit sarcastic atm. -.-)

Okay. And here it comes. This is the routine which is responsible for the decision if the pokemon is a Shiny: (I added some comments for you...)

ROM:0205E40C SpecialShinyHandler                     ; CODE XREF: CheateChainSet+5Cp
ROM:0205E40C                 PUSH    {R3-R5,LR}       ; r0 == chainsize
ROM:0205E40E                 CMP     R0, #0           ; if equal 0 then no special shiny handling  
ROM:0205E40E                                            - the normal 1 out of 8192 chance is used
ROM:0205E410                 BNE     loc_205E416
ROM:0205E412                 MOV     R0, #0
ROM:0205E414                 POP     {R3-R5,PC}      ; exit in case of chainsize == 0
ROM:0205E416 ; ---------------------------------------------------------------------------
ROM:0205E416 loc_205E416
ROM:0205E416                 ADD     R2, R0, #0      ; r2 = r0 = chainsize
ROM:0205E418                 MOV     R1, #0xC8       ; r1 = 0xC8 = 200
ROM:0205E41A                 LDR     R0, =0x2008     ; r0 = 0x2008 = 8200
ROM:0205E41C                 MUL     R2, R1          ; r2 = chainsize * 200
ROM:0205E41E                 SUB     R5, R0, R2      ; r5 = 8200 - r2
ROM:0205E420                 CMP     R5, #0xC8
ROM:0205E422                 BGE     loc_205E426
ROM:0205E424                 ADD     R5, R1, #0      ; prevent negative value if chainsize
ROM:0205E424                                           is bigger than 40
ROM:0205E426 loc_205E426
ROM:0205E426                 LSL     R0, R5, #0x10
ROM:0205E428                 LSR     R0, R0, #0x10   ; overflow secure
ROM:0205E42A                 BNE     loc_205E430
ROM:0205E42C                 BL      IgnoreMe        ; never executed
ROM:0205E430 loc_205E430
ROM:0205E430                 LSL     R0, R5, #0x10
ROM:0205E432                 LSR     R0, R0, #0x10   ; prevent overflow
ROM:0205E434                 CMP     R0, #1
ROM:0205E436                 BHI     loc_205E43C     ; r0 is always > 1, so jump
ROM:0205E438                 MOV     R4, #0
ROM:0205E43A                 B       loc_205E46A
ROM:0205E43C ; ---------------------------------------------------------------------------
ROM:0205E43C loc_205E43C
ROM:0205E43C                 BL      get_random_val  ; Get a randomized value between 0 and 65535
ROM:0205E440                 ADD     R4, R0, #0      ; r4 == rand
ROM:0205E442                 LSL     R1, R5, #0x10
ROM:0205E444                 LDR     R0, =0xFFFF     ; r0 == 0xFFFF == 65535
ROM:0205E446                 LSR     R1, R1, #0x10
ROM:0205E448                 BLX     div_r0_r1       ; 65535 / (8200 - chainsize * 200)
ROM:0205E44C                 ADD     R1, R0, #0
ROM:0205E44E                 ADD     R1, R1, #1      ; (65535 / (8200 - chainsize * 200)) + 1
ROM:0205E450                 LSL     R1, R1, #0x10
ROM:0205E452                 ADD     R0, R4, #0      ; r0 = rand
ROM:0205E454                 LSR     R1, R1, #0x10
ROM:0205E456                 BLX     div_r0_r1       ; rand / (65535 / (8200 - chainsize * 200)) + 1
ROM:0205E45A                 LSL     R0, R0, #0x10
ROM:0205E45C                 LSR     R4, R0, #0x10   ; r4 = r0 (r0 == lastresult)
ROM:0205E45E                 LSL     R0, R5, #0x10   
ROM:0205E460                 LSR     R0, R0, #0x10   ; r0 = (65535 / (8200 - chainsize * 200)) + 1
ROM:0205E462                 CMP     R4, R0
ROM:0205E464                 BCC     loc_205E46A     ; if r4 < r0 then jump
ROM:0205E466                 BL      IgnoreMe        ; this time it is executed but it doesn't
ROM:0205E466                                           change r4 so ignore it once again
ROM:0205E46A loc_205E46A
ROM:0205E46A                 CMP     R4, #0          ; last test. If r4 == 0 Then...
ROM:0205E46C                 BNE     loc_205E472
ROM:0205E46E                 MOV     R0, #1          ; ... make it SHINY!
ROM:0205E470                 POP     {R3-R5,PC}      ; return
ROM:0205E472 ; ---------------------------------------------------------------------------
ROM:0205E472 loc_205E472
ROM:0205E472                 MOV     R0, #0         ; ... else: no shiny
ROM:0205E474                 POP     {R3-R5,PC}     
ROM:0205E474 ; End of function SpecialShinyHandler
ROM:0205E474 ; ---------------------------------------------------------------------------
ROM:0205E476                 ALIGN 4
ROM:0205E478 dword_205E478   DCD 0x2008              ; DATA XREF: SpecialShinyHandler+Er
ROM:0205E47C dword_205E47C   DCD 0xFFFF              ; DATA XREF: SpecialShinyHandler+38r
ROM:0205E480 ; ---------------------------------------------------------------------------

Okay. That's the technical part. Let's analyze it the mathematical way. The basic formula is this one: (n is the chainsize)

It works for all cases of n between 0 and 40. If n is bigger than 40 the denominator is always 200.

After calculating this, a function, which returns a random number between 0 and 65535, is called. The random number (r) is divided by Z and afterwards the result has to be lower than 1. (It's a math.floor operation, so anything < 1 returns 0.)

Because r can be anything between 0 and 65535 the probality P is:

So, for the last time: NO, shiny hunting isn't a bug as many people state and YES, shiny hunting depends on the 'length' of your shiny chain.


"Pokémon" ist ein eingetragenes Warenzeichen der Firma Nintendo
"Action Replay" ist ein eingetragenes Warenzeichen von Datel Interact.
© by Mastermind_X
© 2006 - 2008