Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Scene.js to clarify that scene properties are undefined in constructor #7039

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ospira
Copy link
Contributor

@ospira ospira commented Feb 11, 2025

This PR

  • Updates the Documentation

Describe the changes below:

When one is extending a scene, one might expect to be able to do something like the following (based on current docs):

export class MainScene extends Phaser.Scene {
  somethingYouWantFromTheRegistry: any;

  // other custom properties
  systems: Array<
    new (scene: BaseScene, key: string, ...args: any) => BaseSystem
  >;
  //...

  constructor() {
    super("MainScene"); // you might reasonably expect Phaser.Scene properties to be set at this point

    // set custom properties
    this.systems = [PathFindingSystem, EmoteSystem];
    const registry = this.registry;
    console.log({ registry }); // !returns undefined unexpectedly
    this.somethingYouWantFromTheRegistry = this.registry.get("blah blah blah"); // ! causes error and user to go... why!?
  }
  create() {
    const registry = this.registry; // but down here it actually returns the game registry (even though user didn't do anything)
    this.somethingYouWantFromTheRegistry = this.registry.get("blah blah blah"); // so it "just works" down here
  }
}

The reason for this is understandable once you dive into the source code, which uses a custom class implementation instead of default ES6 classes/extend, although most users will be using the default classes in their code. Based on my understanding of this code, the reason for properties like registry not being available in the constructor is because the Scene class relies on the SceneManager.add() to actually fill these properties, once the Scene has already been instantiated.

However, if you're just a dev consuming this API, that isn't clear in the current documentation. To figure out why the above works relies on navigating the Phaser source code, understanding the custom class/inheritance implementation and then looking at SceneManager which as mentioned in its own docs should usually not be interacted with directly at all.

Furthermore, the current docs might muddle the matter because they mention property unavailability in reference to the Scene Injection Map, which might cause a developer to try to figure out what that is, when that has nothing to do with this constructor issue.

All in all this is a minor doc addendum, but hopefully one that seems worthy of accepting, if only to save the next poor sap from getting very derailed by this 😅 (and questioning their basic understanding of how classes work in javascript or what the scene injection map is before realizing what was actually going on here 😵).

Thanks! :D

@samme
Copy link
Contributor

samme commented Feb 12, 2025

It might be better to say when they are defined, e.g.,

This is set only after the Scene is booted by the Scene Manager.

Because if you never add the scene, the properties will be null everywhere, not just the constructor. 🙂

@ospira
Copy link
Contributor Author

ospira commented Feb 12, 2025

It might be better to say when they are defined, e.g.,

This is set only after the Scene is booted by the Scene Manager.

Because if you never add the scene, the properties will be null everywhere, not just the constructor. 🙂

That's true although the counter to that is probably if the user runs it anywhere else (like anything including or after the init() hook, preload, create, .etc) it will have been booted by that point, thus not likely to run into the issue. I'm trying to think of another situation besides the constructor where it would both be reasonable to expect they would be set and they are also undefined, and I'm not sure an additional case like that really exists.

I guess another way to put this is for these very public/surface level properties I would suggest the briefer the hint/comment the better.

If you prefer though happy to defer to your judgement and edit it. I could also mention init() as the right place to set custom properties that rely on these scene properties if that makes sense to you, as I believe that is the right way in this setup.

Could also do it as a comment on the Scene class itself so that it makes the docs without being too verbose in the comments of every property.

Thanks for the feedback, lmk what you think about this and I will update the PR based on that.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants