Monday, November 27, 2017

Aww, no grapes? What a rip-off.

In the Gumball Machine bonus stage, each time the player rotates the handle, a new gumball object is spawned, with a random subtype. This is achieved by calling the Random_Number function, which produces pseudo-random longword values along a uniform distribution.


The code at sub_612A8 whittles this value down to its four lower bits, generating a random number between 0 and 15, which is then used as an index into a table containing the actual subtype values, which in turn range from 0 to 7:
byte_612E0:
    dc.b 0  ; 1-Up Ball
    dc.b 3  ; Clear
    dc.b 1  ; Replace Ball
    dc.b 4  ; Bumper
    dc.b 2  ; Ring Ball
    dc.b 4  ; Bumper
    dc.b 5  ; Flame Barrier
    dc.b 4  ; Bumper
    dc.b 6  ; Aqua Barrier
    dc.b 3  ; Clear
    dc.b 7  ; Thunder Barrier
    dc.b 4  ; Bumper
    dc.b 5  ; Flame Barrier
    dc.b 6  ; Aqua Barrier
    dc.b 7  ; Thunder Barrier
    dc.b 2  ; Ring Ball
This effectively converts the uniform distribution of the randomly-generated number into a weighted probability function: for instance, the Thunder Barrier appears twice in the table, so it's twice as likely as a Replace Ball, which only appears once. Meanwhile, it's only half as likely as a bumper, which appears four times in the table.


There's a trick, though. Whenever the resulting gumball is a 1-Up Ball, a RAM flag is set which causes any subsequent 1-Ups to be replaced with the fourth entry from the table, producing a bumper:
sub_612A8:
    jsr     (Random_Number).l
    andi.w  #$F,d0
    bne.s   loc_612C2
    movea.w $46(a0),a1
    bset    #7,$38(a1)
    beq.s   loc_612C2
    moveq   #3,d0

loc_612C2:
    move.b  byte_612E0(pc,d0.w),d0
    move.b  d0,$2C(a0)
    ...
As a result, only a single 1-Up Ball will ever spawn per bonus stage, and once it does, the random distribution becomes even more skewed toward bumpers. Here's all of this information compiled into a table, because people like tables:

Gumball TypeLikelyhood (before 1-up)Likelyhood (after 1-up)
1-Up Ball1/160/16
Replace Ball1/161/16
Ring Ball2/162/16
Clear2/162/16
Bumper4/165/16
Flame Barrier2/162/16
Aqua Barrier2/162/16
Thunder Barrier2/162/16

5 comments:

  1. Hi. Sorry to derail, but the last comment I left on an old post seemed to go unnoticed, so I don't know if you get notifications for these.

    https://s3unlocked.blogspot.co.uk/2017/10/knuckles-in-sonic-2-control-quirks.html

    I think the second behaviour quirk you mentioned in this post is the result of a bug. There's some code in S3K that isn't in KiS2, at loc_16E10 in the current S3K Git disasm. The equivalent label in KiS2's Git disasm is loc_315B04.

    What I think this new code does is handle floor collision, because Knuckles still seems to move briefly after the player stops pressing the D-Pad. The issue is, this new code overwrites d1 with the distance Knuckles is from the floor. d1 is checked immediately afterwards, has Knuckles's frame ID added to it, and is then used to calculate which frame Knuckles should display.

    d1 will always be a positive number, usually a large one depending on how far Knuckles is from the ground. This means, when Knuckles's frame ID is added to it, it goes well beyond the ceiling value of $BC, causing the game to reset it to $B7, making Knuckles display the first frame of his animation. Chances are the number could overflow, too, causing him to display his last frame instead.

    Safe to say, editing the code to properly back up d1 causes it to behave like KiS2 instead.

    ReplyDelete
    Replies
    1. Sorry that you felt your comment went unnoticed. I can assure you I read each and every comment, but often I don't have anything to add, and other times, they end up falling through the cracks.

      Admittedly, which is which isn't obvious from casual observation, so I'll try to improve on that front. In the future though, please bring up issues like this in the relevant post. Thanks.

      That being said, excellent work! I haven't looked at the code in question in the time being, so I'll take your word for it. Would you mind if I cobble up your analysis into a follow-up post sometime in the future?

      Delete
  2. Are the gum balls that are fully grey supposed to be black? (The ones inside of the machine) Every single gum ball is in the machine except for the bumpers. Also, what is that turquoise colored ball behind the rest supposed to be?

    ReplyDelete