The new version of my card game is tested since a few months now and I have the first bugs to solve
I am using an AnimationEvent to change the texture of the score table ‘on the fly’ to use it to prompt players with different game actions.
There was no error recorded, so as the texture change is happening on the frame 10 of an animation, triggered on an animation event, I was wondering, if… it could happen that a frame is skipped and the attached event not triggered… ?
thanks ! And of course, I cannot reproduce, this is so rare, that my question is to see if I have to investigate more this direction or if I should look somewhere else
okay, if for instance the cpu/gpu is kind of too busy, isn’t it possible that a frame is skipped to keep the animation synced ?
I was thinking I could add a second event on frame 15 that would check a flag to see if the frame 10 event happened, but if it has nothing to do with this
Ev happens in this order
ev at 3s is called
ev at 2s is called
ev at 1s is called
ev at 4s is called
ev at 5s is called
ev at 6s is called
ev at 7s is called
ev at 8s is called
ev at 9s is called
ev at 10s is called
(I believe ev get called in chronological order, but not really, see test #2)
Test #2
After opening the same PG, immediately switch to other browser tab,
after 10s, switch it back, open console.
The reason this happens is the way we add new events to the list and iterate them later. Here is a very quick fix, using unshift instead of push, make sure they are processed in the right order:
As @ycw wrotes the PG with a top down loop, using unshift instead of push simply reverse the order of the elements in the array.
You would achieve the same thing by doing a bottom up loop (without unshift):
for (let i = 0; i < 10; --i) {
const ev = new BABYLON.AnimationEvent(i, (f) => {
console.log(`ev ${i} is called`);
}, true);
anim.addEvent(ev);
}
I think the outcome to this is that the order in which the events are pushed in the array should not impact the runtime behaviour. At least, on a user point of view, it’s not easily understandable.
[EDIT] If the animation code expects that the animation event array is sorted by increasing frame number, I think it should either be stated in the doc (if not already) or the array should be sorted automatically when new actions are added [/EDIT]
I think that this is ok, if indeed you jumped from frame 4 to frame 15 (for whatever reason) between two calls to the animation engine.
What is less obvious is that the actions you may have attached to frames 5…14 will not be executed in this order (as the PG demonstrates when the actions are pushed in reverse order in the action array). Instead, you could have action of frame 7 called before action of frame 5, which could be a problem if you expected your actions to be called in the frame ascending order.
In fact, I realize the animation code is not working as I expect / I’m used to, so my comments above may not applied…
What I expected/was used to is:
frame 4 has been handled at time t
then there’s a delay of 1s (for whatever reason)
so the next time the animation code is called (time t+1s) it determines it must handle frame 15
then all actions registered for frames 5 to 15 (if any) are called in sequence and in order without any delay. Frames 5 to 14 have not been able to be displayed because of the stuttering, but the actions linked to them should still be executed. As we were not able to do it before frame 15, we do it when handling frame 15.
The order of the calls are 3/2/1 instead of being 1/2/3 after the stuttering simulation (the events are indeed all called at once, I missed that previously).
That’s because the events are processed in the order they have been pushed in the event array.
As you said, an update of the doc would be nice, and maybe adding a flag on an animation that would sort the event array each time a new event is added/modified could be worthwhile?
Babylon will sort underlying events list by {frame}. Such that pending frames will eventually get called in ascending order rather than in chronological order.