Chaining tweens using this.add.timeline()

I would like to chain tweens using timeline().
My understanding is that when adding items to the timeline() they are run in order. However, when using tween: in Phaser.Types.Time.TimelineEventConfig, the duration of the tween is not taken into account.

Here is an example:

class MainScene extends Phaser.Scene {

    constructor() {
        super({ key: "MainScene" });
    }

    preload() {
        this.load.image("earth", "https://cdn.phaser.io/sandbox/square-earth.png");
    }

    create() {
        this.timeline = this.add.timeline();
        this.timeline.play();
        this.earth = this.add.image(400, 350, "earth");

        this.input.keyboard.on("keydown-D", () => {
            this.timeline.add({
                tween: {
                    targets: this.earth,
                    alpha: 0.2,
                    duration: 500,
                },
            })
        });
        this.input.keyboard.on("keydown-F", () => {
            this.timeline.add({
                tween: {
                    targets: this.earth,
                    alpha: 1.0,
                    duration: 0,
                },
            })
        });
    }

    update(time) {
        
    }

}

const game = new Phaser.Game({
    type: Phaser.AUTO,
    width: 800,
    height: 800,
    backgroundColor: '#111111',
    scale: {
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH
    },
    scene: [ MainScene ]
})

What I expect:

  • If I press D the image will fade out, if I press F it will wait for alpha: 0.2 to complete before setting alpha: 1.0.

What happens instead:

  • when alpha: 1.0 is added to the timeline, it executes immediately.

You can also see this on the sandbox tween chain Phaser Sandbox Entry (v3.87)

I can accomplish what I want with this.tweens.chain however timeline() would work much better as I would like to add tween events dynamically from an external source.

:waving_hand:

Timeline events can’t be chained because they have no defined duration. And they execute in order of time coordinate, not add-order. If you add an event without a time value (at, from, or in), the event receives the default at: 0 and so executes immediately, since the timeline has already played past 0. tween.duration is used by the Tween Manager only.

If you know the duration of the last-index event in the timeline, you can add the next event with, e.g., from: 500.

thanks that is what i thought, it would be nice if duration was used by timeline() as well. I’m not sure how else I can create a timeline on the fly.

thinking for the case of having events arriving over a websocket and queuing those events into a timeline.