Error when getting access to classes with BabylonJS and Colyseus

Hi! I’m currently doing a multiplayer game using BabylonJS with Colyseus.

The client runs with the BabylonEngine, the server runs with BabylonNullEngine and the communication between both is made via Colyseus. To avoid any cheaters, the server has to have the authority. To avoid any lags, the server is running in parallel and will overwrite any non desired data on the client side.

At the moment, I’m simply using BabylonEngine for the client and and Colyseus as the server authority. Everything works fine except that I would like to run the server with BabylonNullEngine instead of with Colyseus.

***The issue is that I can’t have any references to Babylon with Colyseus scripts. I’m simply trying to create a new class which imports elements from Colyseus and this issue occured : Error: require() of ES Module [...] to a dynamic import() which is available in all CommonJS modules.

I’ve already try to change the “node-fetch” version and to change the module type but it is not working.

My structure is based on that : GitHub - creationspirit/multiplayer-browser-game-boilerplate: Starter project for a realtime multiplayer 3D game in a browser environment

Screenshot 2022-09-07 121118
Screenshot 2022-09-07 121200

cc @RaananW our build GURU

I managed to fix the issue. Instead of using "@babylonjs/core", I should use “babylonjs” as imports… Seems like there is some packages issue under the hood. The error message was hard to figure out.

Hope that it will help some of you guys!

1 Like

That is because you were trying to consume ES modules as commonjs. The @babylon packages are es-module friendly. The babylon package is UMD, which supports commonjs out of the box.

If package size is not very important than using the UMD version makes perfect sense. it’s working, it’s importing everything, it populates the global namespace. But if package size must be as small as possible, you will need to load the esm packages as commonjs. there are ways of doing that, but that depends on the packer and how the packer consumes packages.

1 Like

Now that I was able to fix the issue, I realize that I duplicate my logic from the client (babylon) and the server (babylonNullEngine). Is there a way to share the game logic while knowing which one is the authority?

Thanks

1 Like

I am not sure I understand your question, sorry.

If you want both to be in sync, you need to duplicate at least some of the logic, to make sure both are running the same code. But that depends on your use case, of course. Want to explain a little further?

Yes ! In order the avoid any duplication from the server, I would like to call existing methods from the client which do the exact same logic.

To give a short example, I have a method in my class Player on the client side which allow my player to move at a specific position. At the moment, I have the exact same method in my class Player on the server. Since both methods are using the exact same logic, is there a way to re-use that exact same method while knowing if this method is called via the client or the server?

For smaller games, it is “ok” to duplicate the game logic. However, the bigger the game, the bigger the amount of systems. I would like to re-use game logic on both client and server in order to avoid any repetition.

I still don’t understand why you can’t do that?

You have a common library which contains the reusable code, and both client and server load it when needed. So the functionality is only written once and imported twice.

1 Like