If you've been keeping up with all my posts on things (I don't blame you if you haven't. Most of them are pretty technical) then you know I've been reversing the animation scripts in the AB files. I'd provide links to these, but I'll just re-provide relevant info here.
So, about the VMG:
WHAT IS IT?
There's an entire article on
Final Fantasy wikia about it. Basically, if Vincent performs a Mug with the Shortbarrel, Winchester, Long Barrel R, Sniper CR, or Death Penalty equipped then the next action's effects are entirely skipped, but the action will still take place and do damage/heal. This includes items, summons, magics, enemy attacks, damage indicators, et al. This is so well known that it's a legitimate speed running tactic for skipping summons like Ultimate End.
WHY IS IT?
This is a three-fold explanation.
First of all it's important to understand that Vincent has three battle models. Yep, three. One for shotguns, one for pistols, and one for rifles. It's the rifle one that's bugged so we'll focus on that. Each of these has an animation file associated with it. The glitched one is SHAB. These AB files have pointers to animation scripts that tell the engine how to act (I'll get to that in part two). This particular one has a single byte different in its mug script compared to the others. For reference, this is script 36 in 0-based decimal. They each have different arguments to their F7 code and this one is set to 18 decimal.
Secondly, let's talk about what animation code F7 does. Each AB script code gets run in "chunks" between the animations. Valid codes start at a value of 8Eh and any value below that is considered an animation index (not to be confused with animation
script index). This particular function tells the game to queue the damage indicator (how much damage has been done), the 2D strike effect, and the sound associated with the action to play in X frames.
Finally, let's talk about thread. More specifically, how the game handles all these effects. As some of you may know from my previous posts, there are thread queues for 2D and 3D effects in battle. Their handlers are queued when the effect starts and they are self-terminating (they remove themselves from the queue when they are done). the damage indicator is actually a 2D effect that runs for 11 frames. While this script is running the "animation thread indicator" is set to active because there are still effects in the queue. Once the animation is complete it marks the thread as complete and the effect queue as empty for the next animation to come around.
HOW IS IT?
Have you spotted the problem yet? If not, don't blame yourself. The QA team at Square didn't either. Here it is: The animation finishes before the effect starts. In fact, the animation ends on the same frame that the effect gets added to the queue. This is a problem. If the effect had started before the animation finishes then it would be cleaned up at the end of the animation. Because animation frames (and by extention, scripts) are handled BEFORE effect handlers this effect doesn't get correctly associated with the animation script. The animation script thread is marked as complete and ready to accept the next animation, but the effect queue is still marked as in-use. When the next animation comes it runs the script, but can't queue anything because it's not granted access to queue anything. All the mechanics still run in the background though so enemies are marked as dead, poisoned, or whatever. And at the "end" of the animation script (that doesn't actually do any animating) everything is correctly marked as empty/complete.
SOLUTION:
There are actually several solutions to this. By far the easiest is to DECREASE the delay the F7 creates (as mentioned above). Even decreasing this by
one frame is enough to prevent this glitch. The following solution works for all PC versions of the game:
1. Open the ff7/battle/battle.lgp file in a hex editor.
2. Search for the case-sensitive ascii string "SHAB" without quotes.
3. Search for the byte sequence 17h 1Ch from the point you found the SHAB.
4. The byte preceding the 17h should be 12h. My mostly-unaltered battle.lgp file has this at address 0x3A7D7F2.
5. Change this 12h to something less. I tried 0Ch and it looks nice.
Problem solved! The effect is queued before the animation completes and the animation correctly associates the damage indicator with the animation script. Now everything gets cleared correctly and the summons can no longer be skipped.