Plugins getting destroyed on game create and hot reload
I have been trying to use a plugin with this template but it just gets destroyed, minimal example can be found at https://github.com/KlutzyBubbles/phaser-react-plugin
However is only gets destroyed when a browser refresh or hot reload of phaser related files happens, but works fine when react files are hot reloaded.
Below is an image where 1 is a browser refresh, 2 is a hot reload from a react file and 3 is a hot reload from a scene file.
The only spot i can see the game being destroyed which could trigger the plugin destroying is https://github.com/phaserjs/template-react/blob/db8c134eb6328ba5d08eb4ef77270f38e2e0b9b9/src/game/PhaserGame.jsx#L11C4-L32C15 but i don't know what to do to fix it. Any help or pointers would be greatly appreciated.
This can also be replicated in the typescript version of this template
There seem to be an issue with the template indeed. Your plugin is stored inside the PluginCache manager that is global to the page, since the Game.destroy() method is an async process (it waits for the next animation frame), the PluginCache is cleaned after the second game is started.
If we log it before the new game creation:
const StartGame = (parent) => {
console.log(Phaser.Plugins.PluginCache.getCustom("ExamplePlugin"));
return new Phaser.Game({ ...config, parent });
};
We can see that it is undefinedwhen the first game is created, but it is already instantiated when the second game is created.
[vite] connecting... client:495:9
[vite] connected. client:614:15
Download the React DevTools for a better development experience: https://reactjs.org/link/react-devtools react-dom_client.js:21551:25
undefined main.js:36:13
Un AudioContext n’a pas pu démarrer automatiquement. Il doit être créé ou repris après un geste de l’utilisateur sur la page. phaser.js:116368:30
Phaser v3.88.2 (WebGL | Web Audio) https://phaser.io/v388 phaser.js:8456:33
ExamplePlugin init ExamplePlugin.js:12:17
ExamplePlugin start ExamplePlugin.js:17:17
Object { plugin: class ExamplePlugin, mapping: null, data: null }
main.js:36:13
Un AudioContext n’a pas pu démarrer automatiquement. Il doit être créé ou repris après un geste de l’utilisateur sur la page. phaser.js:116368:30
Phaser v3.88.2 (WebGL | Web Audio) https://phaser.io/v388 phaser.js:8456:33
Plugin key in use: ExamplePlugin phaser.js:95031:31
ExamplePlugin destroy ExamplePlugin.js:27:17
Un AudioContext n’a pas pu démarrer automatiquement. Il doit être créé ou repris après un geste de l’utilisateur sur la page. phaser.js:116343:33
Note that the double game rendering is visible as well if the animation frame is slowed down a bit:
Yes, the problem is because of the strict React mode.
In the file: PhaserGame.jsx you could comment out the lines responsible for destroying the Game:
return () => {
if (game.current)
{
// game.current.destroy(true);
// game.current = undefined;
}
}
Yes, the problem is because of the strict React mode.
In the file: PhaserGame.jsx you could comment out the lines responsible for destroying the Game:
return () => { if (game.current) { // game.current.destroy(true); // game.current = undefined; } }
Would this not leave extra game instances open if the game-container were to be unmounted and then remounted, as the previous game would not be destroyed but another would be created?
I am currently doing this for the time being but with a big comment reminding myself to find a proper fix before actually shipping the game, as i don't want there to be a possibility for multiple game instances to just linger until the process is closed.
The references we added at the beginning should prevent multiple instances.
The issue is that destroying the game is not a synchronous process, since it needs to wait on the next animation frame from the browser. So the double canvas may happen if this animation frame is slow.