What happens when the attack speed is not at an integer multiple of a logical frame?

Our game performs 10 logical frames per second, so let’s say a unit has an attack speed of 0.3 seconds to attack once, which is programmed to attack once in 3 logical frames.
If it eats an attack speed plus 100% bonus, then its attack speed becomes 1.5 logic frames for 1 attack, what happens at such times?

Would it turn its attack speed into 2 logic frames for 1 attack because it can’t round up?

Or would it become in a cycle of every 3 logic frames, attacking 1 time on the 2nd logic frame and 1 time on the 3rd logic frame, and so on? (No attack, attack, attack, no attack, attack, attack)

Rounding and throwing away the remainder or rounding and accumulating the remainders (the two examples you gave) are options.

Unclear what you are asking here, it’s your system so you are going to need to decide and implement it. And that is the answer to the question “what happens at such times?”, whatever you decide.

1 Like

What function should I decide it by? I want to accumulate

What we want to achieve is that it doesn’t just start logical frame 2 at 150ms just because the next thing that should be executed is located at 150ms, which would cause substantial game acceleration, and we don’t want that, we want it to jump 1 logical frame every 100ms no matter what happens, as long as there is enough arithmetic to do it, and not at 150ms because it needs to make a logical frame at 150ms, instead of jumping to logical frame 2 at 150ms because it needs to perform an action in a logical frame.

At the same time, it should make sure that each event is executed in full, it won’t change its attack rate to 1 time in 2 logical frames because it doesn’t have enough logical frames, it should attack at 150ms once, so it will attack once in both logical frames 2 and 3

What should I do? Thank you very much.

Hopefully there are still others out there who see this

Frame: A logical update, 100ms delta.
Action: A thing to do (e.g. attack)
Length: The number of frames it takes to complete one action, as a float because we want to support fractions (this is the 3 and buffed 1.5 from your example).

On Start New Action Type:

FramesToAction = Length;

Logical Frame:

FramesToAction -= 1;
if (FramesToAction <= 0) {
    DoAction();
    FramesToAction += Length;
}

This logic will give the behaviour you desire, might need to be careful Length always is >= 1.

Okay I got it, but is there a way to implement it with blueprints?

Where should this structure be used? Should it be the rules of the level? Or something more base?

The variables FramesToAction and Length need to be stored per unit, so the unit would be the logical place for them to reside (could be elsewhere as long as they are per unit, putting them in the unit avoids indirection and should be preferred unless you have good reason to put them somewhere else).

As to how to implement it in Blueprint (or C++ for that matter) it of course depends on how you are doing other things (the ‘actions’ in particular). While your first post suggested you had something implemented, I gather from the conversation since this is probably not the case, so instead of asking how that is implemented (because I’m guessing it’s not) I’ll just make assumptions.

The big assumption being that your actions are a bp class (or a class zoo with a common base class) containing a function that takes a Unit as parameter and has that unit perform whatever action it represents.

Start new action on Unit:

Logical Update of Unit:


[Oops… Warning: the last set above should be for Frames to Action, not Action Length]