Phaser headless not working

I have the following code (simplified):

import Phaser from 'phaser'

const config = {
  type: Phaser.HEADLESS,
  width: 1024,
  height: 640,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: {
        y: 980
      },
      debug: true
    }
  },
  scene: {
    preload: () => { console.log('server preload') },
    create: () => { console.log('server create') },
    update: () => { console.log('server update') }
  },
  title: 'Phaser server app',
  backgroundColor: '#06C6F8',
  transparent: true,
  disableContextMenu: true
}

class Game {
  static initialize () {
    console.log('initializing server game');
    (() => new Phaser.Game(config))()
  }
}

export default Game

I trigger this by writing Game.initialize().

In the node devtools console, the “initializing server game” text shows up.
So does “Phaser server app / Phaser v3.22.0-FB (Headless | HTML5 Audio)”.

However, the actual app itself is not running since the preload, create & update methods do not seem to work (their respective outputs are not visible in the console).

What am I doing wrong?

I just tested it in node v10.19.0.
The setup below works :slight_smile:

require('@geckos.io/phaser-on-nodejs')
const Phaser = require('phaser')

const config = {
  type: Phaser.HEADLESS,
  width: 1024,
  height: 640,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: {
        y: 980
      },
      debug: true
    }
  },
  // disable audio
  audio: {
    noAudio: true
  },
  scene: {
    preload: () => {
      console.log('server preload')
    },
    create: () => {
      console.log('server create')
    },
    update: () => {
      // console.log('server update')
    }
  },
  title: 'Phaser server app',
  backgroundColor: '#06C6F8',
  transparent: true,
  disableContextMenu: true
}

class Game {
  static initialize() {
    console.log('initializing server game')
    ;(() => new Phaser.Game(config))()
  }
}

Game.initialize()

1 Like

I am doing the same thing. :sob:

Is something wrong with my implementation of JSDOM?

server.js

require('@babel/register')({
  presets: ['@babel/preset-env']
})

const { JSDOM } = require('jsdom')
require('canvas')

const jsdom = new JSDOM('<!doctype html><html><body></body></html>')
const { window } = jsdom

function copyProps (src, target) {
  Object.defineProperties(target, {
    ...Object.getOwnPropertyDescriptors(src),
    ...Object.getOwnPropertyDescriptors(target)
  })
}

global.window = window
global.document = window.document
global.navigator = {
  userAgent: 'node.js'
}
global.requestAnimationFrame = function (callback) {
  return setTimeout(callback, 0)
}
global.cancelAnimationFrame = function (id) {
  clearTimeout(id)
}
copyProps(window, global)

module.exports = require('app.js')

app.js -

import express from 'express'
import Game from 'Game.js'

// code... use express

Game.initialize() // start phaser app

Most of the original code (i.e., in the question) was part of Game.js.

Lastly, I start the server using node server.js.

My Github repo (with actual code) -

server.js (starting point)

app.js

Game.js

node server.js

I installed your forum_question branch.

I do not know what you did wrong, but when I add import '@geckos.io/phaser-on-nodejs' on top of Game.js and run npm run server:start, it works.

1 Like

Thank you so much for going through the trouble. I really appreciate it. :slight_smile: :slight_smile:

Your Github repo solved my problem!

I went through your code here - https://github.com/geckosio/phaser-on-nodejs/blob/master/src/index.ts

I found the line that I had missed - global.Image = Canvas.Image.

Now my preload, create & update methods are being called as expected.

Once again, thank you so much!! :slight_smile: :slight_smile: :slight_smile:

P.S. I am not sure why the lack of Image was preventing the 3 methods from being called.

Phaser uses new Image() to load the default textures, and it can’t finish booting until they load.

I did think something similar might be happening; however, I don’t understand why no error showed up in the console.