phaserjs / phaserjs/phaser

Global plugins are properly registered to scenes when the game is hot-reloaded

Open
#7,151 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
40.3k
Forks
7.2k
PR merge metrics
No merged PRs in 30d

Description

Version

  • Phaser Version: 3.88.2
  • Operating system: Windows
  • Browser: Chrome

Description

When adding a global plugin through the game config, the plugin is automatically added to scenes.

However, if you're using hot-reloading (by default, I'm using the Svelte game template, which has this), re-adding the plugin doesn't work (Plugin key in use) as it's already there.

Image

Because of this, however, re-registering with scenes doesn't work, and you need to do it manually in the Boot scene or whatever

init() {
  const localisation = this.game.plugins.get(localisationPluginMapping) as LocalisationPlugin;
  this.game.scene.getScenes(false).forEach((scene) => {
    scene.l10n = localisation;
  });
}

I think it's because of this code in PluginManager.js where it returns null instead of the plugin.

Example Test Code

Create a basic plugin:

export class LocalisationPlugin extends Phaser.Plugins.BasePlugin {
	constructor(pluginManager: Phaser.Plugins.PluginManager) {
		super(pluginManager);
	}
...
}

export const LocalisationPluginConfig: Phaser.Types.Core.PluginObjectItem = {
	key: 'l10n',
	plugin: LocalisationPlugin,
	mapping: 'l10n'
};

Add the plugin to your config

const config: Phaser.Types.Core.GameConfig = {
	type: AUTO,
	width: Math.min(1024, window.innerWidth),
	height: Math.min(768, window.innerHeight),
	parent: 'game-container',
	backgroundColor: '#028af8',
	scene: [Boot, Preloader, MainMenu, MainGame],
	scale: {
		mode: Phaser.Scale.FIT,
		autoCenter: Phaser.Scale.CENTER_BOTH
	},
	plugins: {
		global: [LocalisationPluginConfig]
	}
};

In one of your scenes, access the plugin

create() {
	this.instructionsText = this.add
		.text(
			this.cameras.main.width / 2,
			this.cameras.main.height - 100,
			this.l10n.translateClickToStart().toUpperCase(),
			{
				fontFamily: 'Arial',
				fontSize: 15,
				color: '#ffffff',
				stroke: '#000000',
				strokeThickness: 3,
				align: 'center'
			}
		)
		.setOrigin(0.5);
}

Perform some action where hot-reloading is necessary. You should see the warning message Plugin key in use: l10n and the call to translateClickToStart will fail as l10n is undefined

Additional Information

I have very little experience with the code, but I think we could either:

  • Properly remove global plugins (scene plugins may also suffer, I haven't tested) so they can be re-added as normal
  • Gracefully handle the plugin already existing so it can still be re-registered with scenes (return the plugin rather than null)
  • Use this.game.plugins.get('l10n') rather than the return of registering the plugin (which is what I'm assuming it's using)

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 src/plugins/PluginManager.js at the linked lines 444-448, then reproduce the issue using the global plugin configuration and scene access shown in the report. Check the hot-reload path and confirm that reloading no longer produces “Plugin key in use: l10n” and that the scene mapping remains available.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.