How to manage Phaser.Game instance in React?

I’ve been working on it using Paser 3 for a few days, but it’s hard to manage the ‘Paser.Game’ instance.

Now I’m using React state. I put new Paser.Game(config) in the state and renamed the player using ‘useEffect’, which detects when the state changes.

As a result, there was a problem trying to access the game scene before it was fully loaded.
I make setPlayerNameUntilLoaded function as a temporary measure, but I know this is the wrong approach. I’m worried that I should check that GameObject is loaded whenever I want to update it.

I have two questions.

  1. How do I know if the Game Scene is fully loaded?
  2. How do I manage the Paser.Game instance in React?

Below is the code for the part I’m curious about.

import { config } from "@/phaserGame.js";
import React, {useEffect, useState} from "react";
import Phaser from "phaser";
import { useRecoilState, useRecoilValue } from "recoil";
import {characterNameAtom, phaserGameAtom} from "@/recoil/atom.js";
import { Chat } from "@/components/Chat/Chat.js";
import {Player} from "@/characters/player";

export function Town() {
  const [game, setGame] = useState(null);
  const [recoilGame, setRecoilGame] = useRecoilState(phaserGameAtom);

  const characterName = useRecoilValue(characterNameAtom);

  useEffect(()=>{
    setGame(new Phaser.Game(config));
    //setRecoilGame(new Phaser.Game(config));
  },[]);

  useEffect(()=>{
    if(game !== null) {
      //setRecoilGame(game);
      setPlayerNameUntilLoaded();
      //gameScene.add.text(0, 0, characterName, {fontSize: 100, fontFamily: 'Line Seed Sans Bd, sans serif'});
    }
  },[game]) ;

  function setPlayerNameUntilLoaded(){
    const gameScene = game.scene.keys.game.scene.scene ;
    if(gameScene.myPlayer === null){
      setTimeout(() => {
        setPlayerNameUntilLoaded();
      },300);
      return ;
    }
    gameScene.myPlayer.setPlayerName(characterName) ;
  }

  return (
    <>
      <Chat/>
    </>
  )
}

I am not sure if this is the best approach or the right approach, maybe others can chime in on this. But for communication from Phaser and React and other tools or ultility managers we use the Phaser Event system.

const eventsCenter = new Phaser.Events.EventEmitter()

we import into our react components and into our phaser scene files.

In useEffect register your listener.
In Phaser once you get to a state you want to notify, emit the event.

If you want to trigger say a scene change from React
register the listener for that event in Phaser
and again, emit an event from React and Phaser will pick it up…
as long as your listeners are registered at the right time of course :slight_smile: and managing removing listeners if you want them say in 1 scene and not another… always clean up.

1 Like
const gameScene = game.scene.getScene('game')
1 Like