# Is AnimationEvent 100% reliable?

**URL:** <https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381>\
**Category:** Questions\
**Created:** [June 2, 2020, 9:32pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381 "2020-06-02T21:32:35Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fenryll](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/fenryll/32/2677_2.png) [@Fenryll](https://forum.babylonjs.com/u/Fenryll)\
**Post date:** [June 2, 2020, 9:32pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/1 "2020-06-02T21:32:36Z")

</div>

Hello everybody,

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.

This is the correct behaviour:

 ![Yass.ch-standard](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/6/60fb8e4549808b3a0481d1f13b617a78ae9b27c4.jpeg)

I was reported this bug by a friend who is used to have a look at the js console when something weird is happening to capture errors

 ![yass-issue](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/7/7725e9b7a279d8f74198c28f24bdcf07f4aa0cd3.jpeg)

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… ?

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [June 2, 2020, 10:51pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/2 "2020-06-02T22:51:09Z")

</div>

Can you repro? (Beautiful game btw, this is so rad!)

---

<div class="post-metadata">

**Author:** ![Fenryll](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/fenryll/32/2677_2.png) [@Fenryll](https://forum.babylonjs.com/u/Fenryll)\
**Post date:** [June 3, 2020, 6:56am UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/3 "2020-06-03T06:56:53Z")

</div>

> [@Deltakosh](#):
>
> Beautiful game btw, this is so rad

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 🙂

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [June 3, 2020, 12:42pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/4 "2020-06-03T12:42:45Z")

</div>

Looking into the code I am not seeing a lot of possibilities on the animations to go wrong. It might be smthg different.

---

<div class="post-metadata">

**Author:** ![Fenryll](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/fenryll/32/2677_2.png) [@Fenryll](https://forum.babylonjs.com/u/Fenryll)\
**Post date:** [June 3, 2020, 2:33pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/5 "2020-06-03T14:33:29Z")

</div>

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 😛

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [June 3, 2020, 2:40pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/6 "2020-06-03T14:40:17Z")

</div>

In your case it might be simpler to rely on time event then ? @RaananW just introduced a nice addition for those 🙂

---

<div class="post-metadata">

**Author:** ![Fenryll](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/fenryll/32/2677_2.png) [@Fenryll](https://forum.babylonjs.com/u/Fenryll)\
**Post date:** [June 3, 2020, 3:09pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/7 "2020-06-03T15:09:25Z")

</div>

time event, you mean this BABYLON.setTimerAndStart ?

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [June 3, 2020, 3:13pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/8 "2020-06-03T15:13:59Z")

</div>

@RaananW any pointers to your new time observable ?

---

<div class="post-metadata">

**Author:** ![RaananW](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/raananw/32/28955_2.png) [@RaananW](https://forum.babylonjs.com/u/RaananW)\
**Post date:** [June 3, 2020, 3:51pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/9 "2020-06-03T15:51:34Z")

</div>

Fully documented here - [Handle Events with Observables - Babylon.js Documentation](https://doc.babylonjs.com/how_to/observables#settimerandstart) , if anything is not working or missing, please let me know

---

<div class="post-metadata">

**Author:** ![ycw](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/ycw/32/4315_2.png) [@ycw](https://forum.babylonjs.com/u/ycw)\
**Post date:** [June 3, 2020, 3:53pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/10 "2020-06-03T15:53:53Z")

</div>

Test #1

1. Create an Animation
2. Reg AnimationEvents in descending order at 10s 9s 8s … 1s
3. Block runtime for 3.5s

[https://playground.babylonjs.com/#WUCYZ9](https://playground.babylonjs.com/#WUCYZ9)

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 ordering is somehting like that

![a](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/8/835c57a38b93d6bef9c73321a332535e9743781f.png)

---

<div class="post-metadata">

**Author:** ![RaananW](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/raananw/32/28955_2.png) [@RaananW](https://forum.babylonjs.com/u/RaananW)\
**Post date:** [June 3, 2020, 5:48pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/11 "2020-06-03T17:48:34Z")

</div>

Super interesting 🙂

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:

[https://playground.babylonjs.com/#WUCYZ9#2](https://playground.babylonjs.com/#WUCYZ9#2)

![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/a/a287bfe91af62fd22ecd66735d4f09a7f55c1ff4.png)

I think it’s worth pushing this to the framework, thou it is more of a nice-to-have fix. I’ll make sure to update that on my next PR.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [June 3, 2020, 6:09pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/12 "2020-06-03T18:09:10Z")

</div>

I don’t quite understand the fix?

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):

```auto
    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]

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [June 3, 2020, 6:19pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/13 "2020-06-03T18:19:54Z")

</div>

Well this is expected as the code checking if the event needs to be run is doing it by checking if:

- event was not run yet
- we are over the event.frame

Here is the relevant code:

```auto
 const events = this._events;
        if (range > 0 && this.currentFrame > currentFrame ||
            range < 0 && this.currentFrame < currentFrame) {
            this._onLoop();

            // Need to reset animation events
            if (events.length) {
                for (var index = 0; index < events.length; index++) {
                    if (!events[index].onlyOnce) {
                        // reset event, the animation is looping
                        events[index].isDone = false;
                    }
                }
            }
        }

```

from: [Babylon.js/runtimeAnimation.ts at master · BabylonJS/Babylon.js · GitHub](https://github.com/BabylonJS/Babylon.js/blob/master/src/Animations/runtimeAnimation.ts#L592)

so if you block the thread, the animation frame will continue and when the thread will get back to life it will run a lot of events in a row

Maybe we can explain that more in the doc I agree (cc @PirateJC)

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [June 3, 2020, 6:36pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/14 "2020-06-03T18:36:18Z")

</div>

> [@Deltakosh](#):
>
> it will run a lot of events in a row

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.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [June 3, 2020, 6:51pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/15 "2020-06-03T18:51:31Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [June 3, 2020, 7:07pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/16 "2020-06-03T19:07:17Z")

</div>

Well by reading what you expect I think this is correct. What is not done the way you think it was?

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [June 3, 2020, 7:11pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/17 "2020-06-03T19:11:53Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![ycw](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/ycw/32/4315_2.png) [@ycw](https://forum.babylonjs.com/u/ycw)\
**Post date:** [June 3, 2020, 7:29pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/18 "2020-06-03T19:29:28Z")

</div>

In short, i expected that when

`anim.addEvent(new AnimationEvent(frame, ..))`,

Babylon will sort underlying events list by {frame}. Such that pending frames will eventually get called in ascending order rather than in chronological order.

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [June 3, 2020, 7:44pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/20 "2020-06-03T19:44:25Z")

</div>

I’m fine with that!  
Do you mind sending a PR?

---

<div class="post-metadata">

**Author:** ![RaananW](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/raananw/32/28955_2.png) [@RaananW](https://forum.babylonjs.com/u/RaananW)\
**Post date:** [June 3, 2020, 7:48pm UTC](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381/21 "2020-06-03T19:48:21Z")

</div>

Ignore my post, I missed something crucial 🙂 Will support any method of event ordering

[Next page](https://forum.babylonjs.com/t/is-animationevent-100-reliable/11381.md?page=2)
