Phaser: Invalid Key Given When Loading Plugins in Phaser 3.7.1

Created on 9 May 2018  路  8Comments  路  Source: photonstorm/phaser

My plugin was working under Phaser 3.6.0. I am using webpack so I am not sure if this is related to getting rid of the raw loader or if this is a consequence of the updates to Phaser's loader. My code as follows:

const ControlPlugin = require('../plugins/control');

export default class BootScene extends Phaser.Scene {
  constructor() {
    super({
      key: 'BootScene'
    });
  }

  preload(){
    this.load.plugin('ControlPlugin', ControlPlugin);
  }

  create() {
    this.sys.install('ControlPlugin');
    this.scene.start('Stage');
  }
}

Now I get the console error:

Uncaught Error: Error calling 'Loader.false' invalid key provided. at PluginFile.File (phaser.js:3647) at new PluginFile (phaser.js:84119) at LoaderPlugin.eval [as plugin] (phaser.js:84218) at BootScene.preload (BootScene.ts:13) at SceneManager.bootScene (phaser.js:42685) at SceneManager.start (phaser.js:43292) at SceneManager.bootQueue (phaser.js:42448) at EventEmitter.emit (phaser.js:1889) at TextureManager.updatePending (phaser.js:37989) at TextureManager.emit (phaser.js:1870)

The line it is pointing to is this.load.plugin('ControlPlugin', ControlPlugin);. I'm not sure which key it is referring to, I'm guessing the path. I'm using Rich's example plugin which worked in previous versions of Phaser 3 so I don't think it's anything to do with that.

Thanks!

Most helpful comment

This is now fixed in the master branch and will be part of the 3.8.0 release. Please note though that I've completely revamped how plugins work in v3, they're seriously powerful now and there are lots of examples of how to use them in the labs. I'll update the plugin template repo shortly.

All 8 comments

Could you try this against the master branch please? because it's likely related to #3650 which I fixed earlier today.

Still the same problem. I just tried again using npm install. That's the master branch correct?

Ahh you have to build it too. If you've just done npm install then all you need to do is run webpack (or npm run dist if you prefer) and it'll build you a new version. Test against that file and I'm pretty sure it'll be fine.

OK. Cloned the master, built that, and using that output I get a totally different error (Not sure if you want me to post that as a separate issue).

Uncaught TypeError: Cannot read property 'responseText' of null at PluginFile.onProcess (phaser.js:84216) at LoaderPlugin.nextFile (phaser.js:123544) at PluginFile.load (phaser.js:3838) at LoaderPlugin.eval (phaser.js:123490) at Set.each (phaser.js:12579) at LoaderPlugin.checkLoadQueue (phaser.js:123475) at LoaderPlugin.start (phaser.js:123433) at SceneManager.bootScene (phaser.js:42716) at SceneManager.start (phaser.js:43309) at SceneManager.bootQueue (phaser.js:42465)

Ok, thanks - yeah it's assuming the plugin has come via xhr, but in your case, you passed it as an object. Would you mind posting the plugin source here? Or email it to me if it's private, so I can test against it.

Sure.

var ControlPlugin = function (scene)
{
    //  The Scene that owns this plugin
    this.scene = scene;

    this.systems = scene.sys;

    if (!scene.sys.settings.isBooted)
    {
        scene.sys.events.once('boot', this.boot, this);
    }
};

//  Static function called by the PluginFile Loader.
(ControlPlugin as any).register = function (PluginManager)
{
    //  Register this plugin with the PluginManager, so it can be added to Scenes.

    //  The first argument is the name this plugin will be known as in the PluginManager. It should not conflict with already registered plugins.
    //  The second argument is a reference to the plugin object, which will be instantiated by the PluginManager when the Scene boots.
    //  The third argument is the local mapping. This will make the plugin available under `this.sys.base` and also `this.base` from a Scene if
    //  it has an entry in the InjectionMap.
    PluginManager.register('ControlPlugin', ControlPlugin, 'control');
};

ControlPlugin.prototype = {

    //  Called when the Plugin is booted by the PluginManager.
    //  If you need to reference other systems in the Scene (like the Loader or DisplayList) then set-up those references now, not in the constructor.
    boot: function ()
    {
        var eventEmitter = this.systems.events;

        //  Listening to the following events is entirely optional, although we would recommend cleanly shutting down and destroying at least.
        //  If you don't need any of these events then remove the listeners and the relevant methods too.

        eventEmitter.on('start', this.start, this);

        eventEmitter.on('preupdate', this.preUpdate, this);
        eventEmitter.on('update', this.update, this);
        eventEmitter.on('postupdate', this.postUpdate, this);

        eventEmitter.on('pause', this.pause, this);
        eventEmitter.on('resume', this.resume, this);

        eventEmitter.on('sleep', this.sleep, this);
        eventEmitter.on('wake', this.wake, this);

        eventEmitter.on('shutdown', this.shutdown, this);
        eventEmitter.on('destroy', this.destroy, this);


        this.left  = this.scene.sys.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);
        this.right = this.scene.sys.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D);
        this.jump = this.scene.sys.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
        this.lantern = this.scene.sys.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.L);

    },

    //  A test method.
    test: function (name)
    {
        console.log('ControlPlugin says hello ' + name + '!');
    },

    //  Called when a Scene is started by the SceneManager. The Scene is now active, visible and running.
    start: function ()
    {
    },

    //  Called every Scene step - phase 1
    preUpdate: function (time, delta)
    {
    },

    //  Called every Scene step - phase 2
    update: function (time, delta)
    {
    },

    //  Called every Scene step - phase 3
    postUpdate: function (time, delta)
    {
    },

    //  Called when a Scene is paused. A paused scene doesn't have its Step run, but still renders.
    pause: function ()
    {
    },

    //  Called when a Scene is resumed from a paused state.
    resume: function ()
    {
    },

    //  Called when a Scene is put to sleep. A sleeping scene doesn't update or render, but isn't destroyed or shutdown. preUpdate events still fire.
    sleep: function ()
    {
    },

    //  Called when a Scene is woken from a sleeping state.
    wake: function ()
    {
    },

    openConsole() {
        this.scene.sys.input.keyboard.removeKey(Phaser.Input.Keyboard.KeyCodes.A);
        this.scene.sys.input.keyboard.removeKey(Phaser.Input.Keyboard.KeyCodes.D);
        this.scene.sys.input.keyboard.removeKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
        this.scene.sys.input.keyboard.removeKey(Phaser.Input.Keyboard.KeyCodes.L);

    },

    closeConsole() {
        this.left  = this.scene.sys.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);
        this.right = this.scene.sys.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D);
        this.jump = this.scene.sys.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
        this.lantern = this.scene.sys.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.L);
    },

    //  Called when a Scene shuts down, it may then come back again later (which will invoke the 'start' event) but should be considered dormant.
    shutdown: function ()
    {
    },

    //  Called when a Scene is destroyed by the Scene Manager. There is no coming back from a destroyed Scene, so clear up all resources here.
    destroy: function ()
    {
        this.shutdown();

        this.scene = undefined;
    }

};

ControlPlugin.prototype.constructor = ControlPlugin;

//  Make sure you export the plugin for webpack to expose

module.exports = ControlPlugin;

For me, this is fixed as of 4106f7e8. c9ea4dc1 causes chaos, but indeed you're just testing. :)

This is now fixed in the master branch and will be part of the 3.8.0 release. Please note though that I've completely revamped how plugins work in v3, they're seriously powerful now and there are lots of examples of how to use them in the labs. I'll update the plugin template repo shortly.

Was this page helpful?
0 / 5 - 0 ratings