Monday, October 30, 2017

The transformation glitch

A while ago, I mentioned how you can go through the rising lava in Lava Reef Zone 1 by transforming into Super Sonic right before you land on it. More generally, characters go through all solid objects while they're hanging in the air during their transformation sequence. In his glitches and oversights series, GoldS dubbed this the "transformation glitch".


So what's special about the transformation sequence that causes you to phase through solid objects? Something which I glossed over back when I talked about the Super monitor is how as part of the sequence, the object_control attribute at offset $2E of the player's SST is set to a particular value:
Sonic_Transform:
    move.b  #1,(Super_Hyper_palette_status).w   ; set Super/Hyper palette status to 'fading'
    move.b  #$F,(Palette_timer).w
    move.w  #60,(Super_Hyper_frame_count).w
    move.l  #Map_SuperSonic,mappings(a0)
    move.b  #$81,object_control(a0)
    move.b  #$1F,anim(a0)                       ; enter 'transformation' animation
    ...
The object_control attribute is a bitfield, whose flags instruct the player object to skip key routines such as movement, collision and animation. They're typically set when another object is controlling the player, hence the attribute's name.

In this case, a value of $81 means that bits 7 and 0 are set. Bit 7 causes object collision to be skipped, while bit 0 skips over the player's movement routines, removing the effects of gravity. This is different from the "standing on object" flag, which also essentially disables gravity, but leaves players in full control of their movement.


When the player's movement routines don't run, level collision effectively becomes disabled, due to the assumption that the player can't touch the level unless they're traveling toward it. This quirk is actually quite important, because it allows objects to pull the player straight through solid ground, such as the hooks and teacups in Launch Base Zone.


Okay, so the transformation sequence temporarily disables gravity by setting bit 0 of the object_control bitfield, so that the player hangs in the air a bit while the animation plays. But why does it also disable object collision by setting bit 7?

Because the alternative is worse.


When bit 0 is set, the player object assumes that it must be completely stationary, so it doesn't bother checking for level collisions. However, unless bit 7 is also set, other objects may break this assumption by pushing the player themselves, which will then send the player straight through solid ground.

Better safe than sorry.

No comments:

Post a Comment