proyecto26 / ion-phaser

A web component to use Phaser Framework with Angular, React, Vue, etc ๐ŸŽฎ
https://market.ionicframework.com/plugins/ionphaser
MIT License
251 stars 39 forks source link

Interested making it work with next.js #41

Closed OperationalFallacy closed 2 years ago

OperationalFallacy commented 2 years ago

Hi,

I've tried the package with next.js and couldn't make it work related issue was described here: https://github.com/proyecto26/ion-phaser/issues/36

yarn create next-app
cd phaser-demo
npm i phaser
npm install @ion-phaser/react --legacy-peer-deps
yarn dev

There are conflicts with react dependencies, hence --legacy-peer-deps option

npm install @ion-phaser/react

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: phaser-demo@0.1.0
npm ERR! Found: react@17.0.2
npm ERR! node_modules/react
npm ERR!   react@"17.0.2" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.7.0" from @ion-phaser/react@1.3.0
npm ERR! node_modules/@ion-phaser/react
npm ERR!   @ion-phaser/react@"^1.3.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/rn/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:

And with the page itself I'm getting navigator is not defined error. I've read some articles about using phaser with pre-rendering react frameworks and they all say "don't" :)

Curious to hear your opinion if it worth effort to get it working with next.js

jdnichollsc commented 2 years ago

Those articles are due to lack of experience, you can also connect both things with a simple hook :) https://stackblitz.com/edit/react-phaser?file=hooks%2FuseGame.ts

jdnichollsc commented 2 years ago

Your issue is a bit different, we're supporting React 16 right now and you're using React 17 as I can see :)

OperationalFallacy commented 2 years ago

next.js is using it ๐Ÿคท

In native react its all good. I tried your example react project from this repo (there is a small thing with react-scripts package update), it worked fine. I'll check hooks... but I can't even load library, because import('phaser') returns a promise and then whole component have to be async coded, I think.

jdnichollsc commented 2 years ago

Yeah, I know, the last version of NextJS is using that :)

Using my previous example with hooks, you can try this approach:

  useEffect(() => {
    if (!game && containerRef.current) {
      import('phaser').then(({ Game }) => {
        const newGame = new Game({ ...config, parent: containerRef.current })
        setGame(newGame)
      })
    }
    return () => {
      game?.destroy(true)
    }
  }, [config, containerRef, game])

Let me know if that works for you in the meantime ๐Ÿ‘

OperationalFallacy commented 2 years ago

Thanks for pointing in the right direction with useEffect!

Container with Phaser is loaded correctly, but it is just a black background.

I can't figure out how to pass gameConfig from outside of useEffect because it is using type: Phaser.AUTO in other examples, so I just omitted it for now.

My nextjs example is here https://stackblitz.com/edit/nextjs-tvtqzm?file=pages%2Fgame.js with the game link at https://nextjs-tvtqzm--3000.local.webcontainer.io/game

Do you see what's the problem with gameConfig?

jdnichollsc commented 2 years ago

Why are you using @ion-phaser/react with this other alternative using a custom hook?

OperationalFallacy commented 2 years ago

Not sure ๐Ÿค” I was looking at example here: https://github.com/proyecto26/ion-phaser/blob/develop/react/README.md

Do you mean with useEffect there is no need to use ion-phaser?

jdnichollsc commented 2 years ago

Do you mean with useEffect there is no need to use ion-phaser?

Exactly :)

jinglescode commented 2 years ago

Hi @OperationalFallacy, did you have a solution? I am having the same issue. I have also tried that hook @jdnichollsc suggested here https://stackblitz.com/edit/react-phaser?file=hooks%2FuseGame.ts

jdnichollsc commented 2 years ago

@jinglescode please share your logs here, and do you have a repository to be able to debug your issue?

jinglescode commented 2 years ago

@jinglescode please share your logs here, and do you have a repository to be able to debug your issue?

Here you go: https://github.com/jinglescode/debug

Error:

Server Error
ReferenceError: navigator is not defined
jdnichollsc commented 2 years ago

@jinglescode please share your logs here, and do you have a repository to be able to debug your issue?

Here you go: https://github.com/jinglescode/debug

Error:

Server Error
ReferenceError: navigator is not defined

Check this example: https://github.com/proyecto26/ion-phaser/issues/36#issuecomment-873391973

jinglescode commented 2 years ago

@jinglescode please share your logs here, and do you have a repository to be able to debug your issue?

Here you go: https://github.com/jinglescode/debug Error:

Server Error
ReferenceError: navigator is not defined

Check this example: #36 (comment)

Just wanna say to anyone who is facing this problem, that does not work either. See https://github.com/jinglescode/debug

ReferenceError: navigator is not defined
LZoog commented 2 years ago

@jinglescode I ran into the same thing. Based on this StackOverflow q/a, it looks like Phaser might be calling navigator under the hood with the assumption that it's in a browser context (where navigator would not be undefined).

I'm not sure how this will affect me later since while it seems like there's pros and cons to keeping the state synced to the server's state for my particular use, but in the meantime I solved this by using NextJS's dynamic import and setting the component to ssr: false. I'll share it here in case it helps since you recently commented.

in your game/index.tsx you can do:

const gameConfig: Types.Core.GameConfig = {
...
}

// you can place this in a different file if you prefer
const PhaserGame = () => {
  const parentEl = useRef<HTMLDivElement>(null)
  useGame(gameConfig, parentEl)

  return (
    <div className="container">
      <div ref={parentEl} />
    </div>
  )
}

export default PhaserGame

Then on the page you want it:

const PhaserGameNoSSR = dynamic(() => import('../game'), {
  ssr: false,
})
const PhaserGamePage: NextPage = () => <PhaserGameNoSSR />

I don't think you need ion-phaser as stated above. The useGame hook works without it.

jinglescode commented 2 years ago

Wow! Thanks @LZoog. I had something working too, but way more hackish, what you have suggested works and its very neat. So thank you. See https://github.com/jinglescode/debug

LZoog commented 2 years ago

@jinglescode You're welcome! For further reading, maybe look at this or this which I just found. I may end up trying one of these since I'm pretty sure I'm going to want a server-rendered version of the game to help with cheaters manipulating the client-side, and it seems like it could be nice anyway to help create an auto save that's not based on localStorage, but I'm new to Phaser so we'll see. ๐Ÿค”

jinglescode commented 2 years ago

server-rendered version

Exactly @LZoog. I'm also building a "server-rendered version". Inspired by this slides by unreal engine:

image

coopbri commented 2 years ago

Hey @LZoog and @jinglescode, thank you so much, your pointers helped me get on the right track! Thanks to you, I was able to get Phaser running well within a Next.js application. :smile:

I also got a working POC with a dedicated Express server split from the Next.js client instances (basically just running the business logic for connecting/disconnecting players on the server with Socket.io). Happy to share my demo once I clean it up if that would be useful, just mentioning this since you both are also interested in a server-oriented architecture. I am currently investigating ways to cleanly share render logic (and basically just minimize code duplication).

Did either of you see the note from the Phaser headless mode documentation here about use cases? It says "[...] not for running Phaser on the server, which is something you really shouldn't do." I thought this was a bit strange because 1) no reasoning is listed, and 2) this seems like a serious security concern if critical logic is not fixed to one authority/server as the single source of game truth.

See the Lance server, for example, which is also concentrated on browser-based games and promotes having the dedicated server (it's a feature). I feel like the note in the Phaser documentation is off-base, but would love to hear your thoughts.

btw @jinglescode, Cool to see the Unreal Network Compendium, I'm glad you shared a screenshot from it, haha! Tons of information, but super informative and useful. I absolutely love UE, Phaser is quite the change of pace!

LZoog commented 2 years ago

@coopbri Glad to help! I have to give @jdnichollsc credit for that useGame hook, though. ๐Ÿ™‚

That's an interesting find on the Phaser docs, thanks for posting it, both of the tutorials I linked recommend that approach and I hadn't dived in yet. I filed an issue in the Phaser repo to see what they say about this, @jinglescode or @coopbri please feel free to comment over there. I don't want to bloat this issue in the ion-phaser repo since the OP isn't active in conversation here. ๐Ÿ˜ฌ

Lance looks really interesting, thanks for linking it! SocketIO is a neat tool, I've used it before. Just curious, have you heard of Colyseus? I was going to choose between SocketIO and Colyseus when I got to the multi-player aspect, though I haven't used Colyseus myself yet. I'd definitely be interested in what you come up with, though our use-cases might be different. ๐Ÿ™‚

Are you both on Phaser's Discord? I joined recently but haven't really participated in chat. My username is the same over there, in case that's a better place to connect than GH.

coopbri commented 2 years ago

Ah of course, thanks @jdnichollsc!

Using knowledge from both of the guides you linked allowed me to make the client/server POC -- I don't see glaring issues with this set up, and appreciate you filing that issue -- I will keep an eye on that and hadn't seen the previous examples of the question being asked you linked in that issue!

I have not seen Colyseus, thanks for pointing that out -- taking a look right now :)

I was not on Phaser's Discord, but just joined today. Sweet, I will send you and Jingles a DM on Discord!