Miscellaneous Forums > Scripting and Reverse Engineering

[FF7 PSX] ATB Recommended/Wait Pause Logic

(1/2) > >>

RoSoDude:
I have become rather obsessed with the intricacies of the Active Time Battle system in Final Fantasy games. In particular, I find it very interesting how and when the games decide to pause ATB; FF4, FF5, and FF8 all pause during battle animations, while FF6 and FF9 let ATB run in the background (to rather deleterious effects). FF7 is in the middle; in Active mode it works like FF6/9, while in Recommended/Wait mode it works more like FF4/5/8... but with some notable quirks.

The FF7 manual states the following for ATB Recommended: "For moderately skilled players. Time stops while the screen effects are displayed when using Magic and Items."

Yeah, turns out it's much, much more complicated than this. In an earlier post on the issue, Sega Chief theorized that animation sequences had "hooks" to tell the battle engine to pause ATB, but these hooks were getting missed somehow due to menus. This seemed like a plausible theory since I myself had noticed that ATB pausing was inconsistent; sometimes ATB would pause after the startup phase of a spell command, while sometimes it would keep running. Limit Breaks usually fail to pause ATB, but if ATB was already paused going into a limit break, it would stay paused. I decided to go into the debugger to work it out myself, and see if I could fix any "bugs" in the code. It turns out this theory about animation sequences is totally wrong, and ATB pausing is broken by design rather than by any coding bugs.

The basic conditions for ATB pausing are:


* ATB pauses during all summon animations (regardless of Active/Recommended/Wait)
* ATB pauses when Wait mode is selected and the user is in a submenu
* ATB pauses when Recommended/Wait is selected and the animation timer is 16,385 or greater
The animation timer is the tricky part here. First of all, the increment is determined by the Battle Speed, in particular Speed_mod = (65536/(2*(120+(480*Bat_Spd)/256)). Once each frame (at 60fps), this Speed_mod is added to the timer. For example, if the Battle Speed is 0 (fastest), the increment is 273 and so the timer takes 1 second to reach 16385; if Battle Speed is 128 (default), the increment is 91 and the timer takes 3 seconds; if Battle Speed is 255 (slowest), the increment is 54 and the timer takes 5 seconds. This is why you can sometimes see basic attacks pause ATB on the fastest Battle Speed, but you will never see this on slower settings.

More importantly, the timer only increments under specific conditions, and frequently resets before it can reach [1-5] seconds. Let's break it down further. The animation timer only ticks up if the variable I'm calling the "pause flag" is equal to 0x0003, and the timer is usually reset when the pause flag is changed. Here's how it works (the following applies only to Recommended/Wait mode)†:


* When no turns are being executed, the pause flag is set to 0x0000
* At the start of a command animation (excepting commands that jump the queue like counters and limit breaks), the pause flag is set as follows:

* If there are no commands waiting on the queue, the pause flag is set to 0x0001 and the timer is reset
* If there are commands waiting on the queue, the pause flag is set to 0x0003 and the timer is reset
* If any character has received full ATB, the pause flag is set to pause_flag = pause_flag OR 0x0002, and the timer is not reset. This bitwise OR has the following effects on existing values of the pause flag:

* pause_flag == 0x0000 becomes pause_flag == 0x0002
* pause_flag == 0x0001 becomes pause_flag == 0x0003
* pause_flag == 0x0002 becomes pause_flag == 0x0002
* pause_flag == 0x0003 becomes pause_flag == 0x0003
Taking it all together, we can explain some common scenarios with ATB (assuming default Battle Speed):

* Cloud casts Bolt when the queue is empty. The pause flag is set to 0x0001 but doesn't get bumped up to 0x0003 in time, so ATB never pauses during the attack
* Cloud casts Bolt right before Barret gets full ATB. The pause flag is then set to 0x0003 and ATB pauses 3 seconds into the animation
* Guard Scorpion queues Tail Laser during Cloud's attack, and then ATB is paused. ATB stays paused during Tail Laser
* Tail Laser gives Cloud and Barret full limit gauges. Cloud activates Braver, but since limit breaks do not update the pause flag it is stuck at 0x0000. The Guard Scorpion gets full ATB during Braver which updates the pause flag to 0x0002. Barrett activates Big Shot (since limit breaks jump the queue), but the pause flag is now stuck at 0x0002 and ATB never pauses
* Tail Laser gives Barret a full limit gauge. First, Cloud uses a potion, which sets the pause flag to 0x001. During the potion animation, the Guard Scorpion gets full ATB, updating the pause flag to 0x003. Barret activates Big Shot (since limit breaks jump the queue), and ATB pauses within 3 seconds of the animation
* Cloud and Barret both queue up attacks at the same time, so there is one extra move waiting on the queue. Barret does a basic attack which sets the pause flag to 0x0003, but the animation is done before 3 seconds elapse so ATB never pauses, and the timer resets
* There's nothing left on the queue. Cloud casts Bolt which sets the pause flag to 0x0001, and Barrett gets full ATB 3 seconds into the animation which sets the pause flag to 0x0003. However, the animation finishes before 3 more seconds can elapse, so ATB never pauses and the timer resets
We can glean several goals of this ATB design from the implementation. The primary goal is to keep the command queue from getting backlogged; if there are moves waiting, only a little bit of time will leak during the animation. A secondary goal is to maintain the flow of battle in contrast to the strict animation pausing of FF4/5/8; if the queue is empty, time will flow until at least one participant has full ATB. A final goal is to make this all scale with the Battle Speed setting, such that the ATB pauses more often at high Battle Speed but less often at low Battle Speed. However, despite these reasonable goals, the implementation is a bit of a failure in my view, since there are so many conditions that reset (or fail to set) the timer that the ATB pause ends up feeling random and unpredictable, which is not ideal for strategic gameplay.

I will be updating this thread later with commented MIPS disassembly that details the implementation. I already programmed a patch which simplifies the system; I removed the check for the queue position and set the pause flag on all attacks (whether player, enemy, or limit break) to 0x0001 always, and pause ATB as soon as the pause flag is updated to 0x0003 by a character getting full ATB. This puts a greater emphasis on the effect of Dexterity on character speed by pausing more consistently, while still letting ATB flow until the next move is ready to go onto the queue.

†I originally thought the pause flag was set to 0x01 if the player and enemy turn counters were equal, but it is actually based on the current and total queue length

leorasy:
Makes it easier to plan — especially useful for beginners or during complex boss fights.

javisanchez1234567:
This is very interesting. I'd love a mod for the Steam version that pauses the game on all animations.

The only problem would be that Haste and Slow would be too OP. Is there a way to make the speed +25% and -25% instead of doubling and dividing by two?

RoSoDude:

--- Quote from: javisanchez1234567 on 2025-06-26 09:39:41 ---This is very interesting. I'd love a mod for the Steam version that pauses the game on all animations.

The only problem would be that Haste and Slow would be too OP. Is there a way to make the speed +25% and -25% instead of doubling and dividing by two?

--- End quote ---

In my FF7 ATB hack for the PSX game I revised the system to pause ATB during animations as soon as anyone's turn comes up. This leads to less ATB "leaking" on faster battle speeds, so 2x haste does indeed become overpowered (0.5x slow is still pretty reasonable though). Thus I revised haste to 1.5x speed.

I don't know anything about modifying the PC version, so someone else would have to take a crack at it.

maruusa:
If you perform an attack when no other character has full ATB, the pause flag is simply set to 0x0001. At this point, the timer will not increase, and ATB will continue to run in the background.

Navigation

[0] Message Index

[#] Next page

Go to full version