Question about a S3k's collision bug

Discussion in 'Discussion & Q&A' started by FireRat, Apr 19, 2018.

  1. FireRat

    FireRat "The grand imitator..." Member

    Joined:
    Oct 31, 2009
    Messages:
    526
    Hello.

    It has come to my knowledge, many years ago, that S3k engine has a bug in collision detection. If I remember correctly, said bug had something to do with Sonic getting through chunks and/or doing dead-stops at slopes?
    All caused because collision code checks for a wrong bit... ?

    What's the nature of this bug? Is it indeed a wrong bit getting checked? If so, what's the mistake in itself?
     
  2. Pacguy

    Pacguy :3 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,092
    Location:
    Twinleaf Town
    I swear I've seen something like this in both Sonic 1 and 2. In the Sonic 2 GitHub disassembly, it's here:
    Code:
    ObjCheckLeftWallDist:
        add.w    x_pos(a0),d3
        move.w    y_pos(a0),d2
        ; Engine bug: colliding with left walls is erratic with this function.
        ; The cause is this: a missing instruction to flip collision on the found
        ; 16x16 block; this one:
        ;eori.w    #$F,d3
        lea    (Primary_Angle).w,a4
        move.b    #0,(a4)
        movea.w    #-$10,a3
        move.w    #$400,d6
        moveq    #$D,d5
        bsr.w    FindWall
        move.b    (Primary_Angle).w,d3
        btst    #0,d3
        beq.s    +
        move.b    #$40,d3
    +
        rts
    
    Since it's in both Sonic 1 and 2, its' possible it slipped into S3K. Of course, I could also be completely wrong; I'm going out on a limb here. Hope it helps...
     
    vladikcomper and FireRat like this.
  3. Clownacy

    Clownacy UP - ON - CPU Staff

    Joined:
    Aug 15, 2014
    Messages:
    819
    Location:
    Englandland
    That was fixed in S3K:

    Code:
    ObjCheckLeftWallDist:
           add.w    $10(a0),d3
           eori.w    #$F,d3    ; this was not here in S1/S2, resulting in a bug
    ; sub_FE44:
    ObjCheckLeftWallDist_Part2:
           move.w    $14(a0),d2
           lea    (Primary_Angle).w,a4
           move.b    #0,(a4)
           movea.w    #-$10,a3
           move.w    #$400,d6
           moveq    #$D,d5
           bsr.w    FindWall
           move.b    (Primary_Angle).w,d3
           btst    #0,d3
           beq.s    locret_FE6C
           move.b    #$40,d3
    
    locret_FE6C:
           rts
    ; End of function ObjCheckLeftWallDist_Part2
    The whole 'stopping dead at a slope' thing just sounds like Sonic going so fast that the game fetches a collision height too far into the block, which winds up being too steep compared to the last height fetched, causing the game to assume it's a wall.

    The only 'checking the wrong bit' bug I know of is debatably not even a bug. It's the one where, in order for Sonic to be able to run up a wall, its blocks need to be solid on the top as well as the side, since it checks for that bit exclusively.
     
    Last edited: Apr 20, 2018
    nineko and Pacguy like this.