Action Cooldown/Time Taken

I was messing around with Ned Fulmer, thinking of doing a “chain” of actions (heartShield, time-travel, invisibility) to shave off time at the end of survival levels. Here’s the end of the code (I’m assuming this game is 60 fps):

while hero.time < 26.4:
hero.debug(hero.time) # 26.4
hero.debug(hero.time) # 26.4
hero.heartShield() # 122 frames?
hero.debug(hero.time) # 28.5333333 
hero.cast("time-travel", hero) # 32 frames?
hero.debug(hero.time) $ 29.066666
while hero.time < 32:
while hero.time < 34:
hero.debug(hero.time) # 34.2
hero.cast("invisibility", hero)
hero.debug(hero.time) # 34.733333
while hero.time < 38:
    hero.debug(hero.time) # Not listing the times, but they were consistently 32 frames apart
    hero.shield() # 32 frames?
hero.debug(hero.time) # 38.066666

When I was debugging however, I noticed a couple of things that were odd. For one, actions seemed to take 2 frames more than expected, and double checked that calling debug() wasn’t using a frame. Another odd thing is that Ned Fulmer’s heartShield appeared to apply its status immediately when called, whereas time-travel and invisibility appeared to have a delay of ~30 frames before they applied their status. What confused me about this is that heartShield says it takes 2 seconds, but the “time taken” is concurrent with the effect, whereas time-travel and invisibility said they took 0.5 seconds, and had roughly that much “time taken” (plus/minus a couple frames) before the effect was applied.
I have a couple of questions about this:

  • How are actions handled? Is it something like “check if action can be done, set cooldown, wait, apply effect” or something else?
  • Do the extra frames come before or after the effect of the action?

1 what is heart shield?

heart shield is the new character’s special ability it makes you invincible for 2 seconds. the cooldown is 5 I think?