playcanvas / playcanvas/engine

ESM scripts, execution order issues with attributes.

Open
#8,344 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
16.8k
Forks
2k
Avg merge
4h 32m
Merged PRs (30d)
222

Description

ESM scripts have unfortunately many issues, some conceptual, some functional.
One of the issue here, is that execution order for same conceptual thing "know when attribute changes", is different between classical and ESM scripts.
In example below, we simply want to change name of another entity, which we find in initialize. With classical script - very straight forward: find an entity, subscribe to attribute change, apply change on event.
With ESM, to react on attribute changes, we have to use set/get. But the setter will be executed before the initialize is executed, leading to friend to be undefined, because it is not yet found.

This very simple concept, and yet it is a hustle with ESM. What would be the suggestion here?

Here is a classic script:

var Test = pc.createScript('test');

Test.attributes.add('friendsName', { type: 'string', default: 'friend?' });

Test.prototype.initialize = function() {
    // 1
    this.friend = this.app.findByName('friend');

    this.on('attr:friendsName', () => {
        // 2
        this.friend.name = this.friendsName;
    });
};

And here is an ESM script

import { Script } from 'playcanvas';

export class Test extends Script {
    static scriptName = 'test';

    _friendsName = 'friend?';

    initialize() {
        // 2
        this.friend = this.app.findByName('friend');
    }

    /**
     * @attribute
     * @type {string}
     */
    set friendsName(value) {
        // 1
        this._friendsName = value;
        this.friend.name = this._friendsName; // exception here, friend is undefined!
    }

    get friendsName() {
        return this._friendsName;
    }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the ESM Script example and compare the friendsName setter with initialize() and the classic script's attribute-change handler. Trace when each lifecycle point runs and determine the intended execution-order contract. Done means the project has an agreed, documented behavior or implementation direction that prevents the setter from using an uninitialized friend.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
game-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.