Jump to content

BabylonJS + Multiplayer code


Threedy
 Share

Recommended Posts

Hi,

This is more of a theoretical/conceptual question and it is more related to server programming than BabylonJS itself. But I'd like to have tips on dealing with these problems:

Let's say a wall is in the middle of 2 players. The players have to go around this wall to see eachother. Now, the problem is that an evil player can ''disable'' the phyics/collision of this wall and go through it to catch the other player. In fact, he can just change his position and there he is, at the other side.

Now server wise, I believe I would deal with this by checking whether he didn't collide with the wall (e.g. his position intersects the wall). But if I have a more complex geometry, this would be hard to do without having BabylonJS on the server so I could use the ''intersectsMesh'' function for instance... So I thought, well, say that the other non-evil player can also perform checks to see if that player intersects with the wall.. And if so, it will trigger something on the server.. But that wouldn't be fair since he may be evil too..

I don't know how to approach this. Especially since my game will use physics where players can just modify values like impulse.

Thanks!:)

Link to comment
Share on other sites

Hi Threedy,

working with client side intersects would not prevent cheating.

What we need is some kind of babylon light wich runs server side to simulate the physics.
Im still a babylon noob and dont know much details about how the physics world communicates with the scene.
But some months back we tried to run cannon.js on a node.js server wich was more or less working.

So maybe you could have a server side physics world running cannon and just stream the player matrix to the game.

Since im even working on some MMO, i would be more than happy to collaborate finding a solution.
 

Cheers

Hen

 

 

Link to comment
Share on other sites

Hi guys,

I have been working on some multiplayer stuff too. In my frist atempt I just didnt check server side at all and just updated position of objects all the time. But I am now planning on finding a solution to that exact problem you stated. 
I havent had much time lately :/, but what I was planning to try was running babylon.js on node.js by using a "fake" canvas with the node-canvas lib (https://github.com/Automattic/node-canvas). 
Keep us updated if anybody has some solutions for server side physics checks.

Link to comment
Share on other sites

Hey guys,

 

Nice thread :-)

Running the code on the server side won't do you no good. As long as the JavaScript code can be manipulated by the user (which is always the case), the user can manipulate his actions. You calculate movements on the server? The user ignores it. You check the user's location? The user can mock it. You encrypt? The encryption key must be visible in the code.

Web assembly might be a solution. Obfuscation is sometimes a solution, but not when you use a known framework.

 

Link to comment
Share on other sites

34 minutes ago, RaananW said:

Running the code on the server side won't do you no good. As long as the JavaScript code can be manipulated by the user (which is always the case), the user can manipulate his actions. You calculate movements on the server? The user ignores it. You check the user's location? The user can mock it. You encrypt? The encryption key must be visible in the code.

 

I don't think this is really true... 

Sure the client can change his position on his own computer, that can't be helped. But if the server is responsible for broadcasting the actions to other players, he can only lie to himself. The server won't tell anyone else about the new position if it's invalid,  and won't allow any attack actions to be stored in the server-side game state, so whilst he can hack it so that he went through a wall and killed everyone, everyone else will just see him standing in the corner looking like a noob and play as normal without him :)
That's not really any different to any multiplayer game - sure it's easier to hack the JS code, but then it's not really that hard to intercept the network packets even for a C++ compiled game. That's why there are bots and emulators for most big online games these days.

I think any multiplayer game has to be built assuming people CAN and WILL cheat on the client side... you just have to take actions to minimize the effect of that.

 

 

Link to comment
Share on other sites

Thank you all for the replies.

2 hours ago, Dal said:

I don't think this is really true... 

Sure the client can change his position on his own computer, that can't be helped. But if the server is responsible for broadcasting the actions to other players, he can only lie to himself.

 

This is what I was also thinking. The server would only receive input and deal with the physics applied on the objects and send back the position to the clients. But in this case it needs to also know about the (babylon) mesh and the way it is put. The only challenge is running this entire thing on the server. :ph34r:

Edit #1: Although running physics on the server alone may not be really smooth. So both client and server side?:wacko:

Edit #2: What about this idea:

If you are with 4 players, you run the physics only on the client side. If one player disables a wall and goes ''through'' an object, the other 3 will see this as invalid, marking it an invalid move. 3>1 = 1 back to the position of where the other 3 are (on average) at.

So by only sending the input, rather than position.. It can be calculated on all clients. Hence, if an evil player is modifying his positions, it wouldn't do anything for the server since the other clients are still seeing him at his old position.

Does that make sense?:wacko:

Link to comment
Share on other sites

This is not directly connected to Babylon.js. But if you want to have a really nice read about fast paced online multiplayer game concepts you should read through this blog series: http://www.gabrielgambetta.com/fpm1.html

So I think this would be quite hard to accomplish with node.js and a javascript physics engine.

Link to comment
Share on other sites

very interesting article
I don't think that having BJS running on the server with a headless library would be the right solution because of the heavy webgl part.

I will check if there is a way to set the BJS engine to make it NOT to render anything (so just to skip every WebGL orders). I guess the current code is well with different layers, so maybe it would as easy as not calling the drawing layer... maybe setting a time interval instead of the RAF callback also.

This would make the first 3D framework able to run in headless mode. ;-)

Implementing then a server game logic and the communication layer (fortunately the browser takes already in charge the network layer) will still be very complex imho.

 

 

Link to comment
Share on other sites

After having read a little the scene and engine, it seems that it's not that easy to do either, but doable imho.
I think that I will have to ask many things to DK to do it well. 
It's on my todo list ... considering that it won't be too complex to do and not that intrusive in the engine.

 

 

[EDIT] : maybe just by removing all the stuff after this line  https://github.com/BabylonJS/Babylon.js/blob/master/src/babylon.scene.ts#L1620

Link to comment
Share on other sites

 

2 hours ago, Threedy said:

That would be great indeed. I have spent all day looking for a solution to handle physics serverside without any luck unfortunately.

This is surprisingly harder than I thought.

 

This is not really that hard. You can run a physics world using cannon.js on the server.
With physics world I mean a pure cannon world, no babylon scene or canvas.

That world should be updated with the same frequency your websocket connection is using and have some good interpolation client side.
All physical game objects should be simulated and streamed from there.

Getting it done to this point is easy.

My headache is more about how many clients you could serve that way.
Our current babylon world setup supports 30 concurrents per scene. But as example just 1 physical sphere that constantly changes the matrix would decrease it by one.

Cheers 

Hen

Link to comment
Share on other sites

4 hours ago, hen said:

 

 

This is not really that hard. You can run a physics world using cannon.js on the server.
With physics world I mean a pure cannon world, no babylon scene or canvas.

That world should be updated with the same frequency your websocket connection is using and have some good interpolation client side.
All physical game objects should be simulated and streamed from there.

Getting it done to this point is easy.

My headache is more about how many clients you could serve that way.
Our current babylon world setup supports 30 concurrents per scene. But as example just 1 physical sphere that constantly changes the matrix would decrease it by one.

Cheers 

Hen

Ah, good tip, thank you, I will try that out! Do you use cannon yourself? I thought Oimo was the preferred one for BabylonJS now. But I assume Oimo can be also used on the serverside.

I assume you are running the physics on the client side as well and compare them with the server? Or are you only sending the positions from the server back to the clients?

Link to comment
Share on other sites

3 hours ago, Threedy said:

Ah, good tip, thank you, I will try that out! Do you use cannon yourself? I thought Oimo was the preferred one for BabylonJS now.

I assume you are running the physics on the client side as well and compare them with the server? Or are you only sending the positions from the server back to the clients?

Oimo seems really to be the better one, i wish i could use it.
But our levels do use terrain and there is no heightfield collisions in Oimo (or maybe i missed something).

With the approach i explained, you do not need to run any physics on the client anymore.
All positions/rotations is calculated server side and just streamed to the clients.

If you plan to run cannon on node.js you cant use requestAnimationFrame.
But a simple loop calling physicsWorld.step(time) makes it work.



 

Link to comment
Share on other sites

As stated, most viable option seems to be having an authoritative server and client side interpolation. (Selective broadcasting / Voronoi diagrams might help as well)

Although it is an 2D/isometric engine, Isogenic Engine's multiplayer was praised by some (I didn't check code) at the time. It was said to be inspired by Valve's Source Engine ( https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking ) . Good thing is it is open source now so can give some idea as well perhaps.

Link to comment
Share on other sites

  • 4 weeks later...
On 16.1.2016 at 4:01 PM, jerome said:

I will check if there is a way to set the BJS engine to make it NOT to render anything (so just to skip every WebGL orders). I guess the current code is well with different layers, so maybe it would as easy as not calling the drawing layer... maybe setting a time interval instead of the RAF callback also.

This would make the first 3D framework able to run in headless mode. ;-)

Have you been able to create meshes that way?

I did try something similar but having issues with the canvas webgl contexts.

Link to comment
Share on other sites

Hey,

Seriously guys, running BJS server side doesn't seem like a proper solution to me. To have decent multiplayer interactions you need to reduce your server code to the barest minimum and only do the precise computations you need. BJS is first and foremost a render engine, so running it on a server by skipping the webgl part seems odd. As stated above, there are libraries on npm that will do a very good job at physics and general math computations (ie vectors).

Writing a multiplayer code requires changing the way we think about things. Basically:

  • All the actual game logic runs on the server
  • Clients renders only what the server allows them to, and interpolates and guesses as much as possible between server messages

BJS and its physics system can be used to interpolate between game states on the client side (ie avoid choppy movements), and simulate non-critical entities, for example puff of smokes or debris after an explosion. On the other hand, character movements and actions, visibility lists, collisions, player input, all these things must be handled by the server code.

For the example given in the OP, the player may very well try to force its position manually and cross the wall, this would simply have no effect at all since the server would only register a "request to move in X direction", register a collision with the wall and prevent the player from moving further. Thus, no change on the visibility list, and no way to interact with the player on the other side. Players can still completely break the way the game renders on their screen (as with every JS application), but they won't be able to mess with the game logic.

(sorry, I'm mainly rewriting things that have already been said!)

As for handling many users, in my opinion it's all just a matter of optimization. Here are some thoughts that may be useful:

  1. reduce the amount of data sent back and forth. Your entities can only rotate on the Y axis? do not send 3 rotation values. Only send simplified input data to the server, i.e. : walk towards X+. Combine data with bitmasks if possible. Buffer data and send them in batch instead of sending too many messages. Do not send data to clients for things that are out of sight or unimportant. An object is moving/rotating regularly and in a predictable way? only broadcast its movement pattern and speed, and update if necessary. Do not send an update for an object if nothing about it has changed since the last time (ie do not resend all entities for every server update).
  2. reduce physics computation to the minimum. Use simplified colliders and octrees for spatial subdivision. Your entities are walking on an uneven ground but that is irrelevant to the game logic? just simulate a flat plane and let the clients render entities at the correct height.

Not sure if my post helped, but I find this topic very interesting and felt compelled to contribute :) Also I can't wait to see a true multiplayer game done with BJS!!

Link to comment
Share on other sites

Actually, after some studies about the possibility to skip the webGL part, it seems quite complex in this current state.

So it's not a good idea.

So now, two options :

1) get BJS as it is, run it server-side in a headless module if you can, add your own communication layer... if this is enough for you, well, right :-)

2) as Jahow said, code a dedicated server running the specific logic and the communication layer. You could then reuse the class Maths from BJS to quickly implement all the complex stuff (transformation matrix, etc).

 

The ideal thing would be that a volunteer team starts a project to code a BJS compliant server module : maths, transformations, collision, physics if any, all integrated + a communication layer, a kind of protocol (move mesh granted, rotate mesh granted, etc) and a formatted data structure (representation of meshes, movements, etc) + obviously the related client module

 

 

Link to comment
Share on other sites

I know we are talking theory, but in practice, just because someone can cheat does not mean that they will.

 

What I mean by that is that the other option is do your best to get a working architecture and take actions for users that cheat (ban, etc), if it even happens. You could also map out the risk/failure modes of possible cheats and try to guard them server side if they have a higher risk/failure. Let the server be an authority. For example if there is an ammo count, and you know the rate at which the weapon can shoot, let the server grant permission for the action to happen (to all clients), same with player position and max speed vs actual client recorded speed. Many of nuances, but I would start simple and then extend it out as it's built, given that the groundwork has been laid.

 

Link to comment
Share on other sites

hey guys i also am working on a online game so this is also a problem for me a few ideas i have are

1) not 100% sure if this can be done as i have not tested it yet
but i'm using socket.io and socket.io allows objects to be sent and a function is just a object correct so cant we just send the client functions
when they first login and these functions will allow the client to interact with the server.
but i still think this would be hackable but not sure?

2) another option would be to:
server asks for the length from line a to line b of the clients
a and b would be random or some kind of algorithm that make sure its asked for different lines every time
then the client would respond with the correct length this check can be done a few time until the hole document is checked if all the lengths match up correctly we now know the code has not been changed and allow them access if the user knows this it could be hackable but would be hard they would need a dummy file that is the original and make the code check the dummy file

Link to comment
Share on other sites

  • 1 month later...

Sorry to bump my own thread again.

I have managed to follow Hen's advice and implemented CannonJS on the server (BabylonJS on the front-end which I have only used for the rendering, not it's CannonJS integration, which I implemented separately on the client like the server, and NodeJS/SocketIO). 

It seems that my current way of implementing cannonjs is the bottleneck so far (and I don't think there is a better Javascript 3D physics engine performance wise at the moment). It works fine for a few objects. But unfortunately, adding +- 400 boxes floating in the air, I would notice quite some lag for only 1 player at 1 game. Now imagine this for 4 game instances with 8 players on a single server. It would be impossible.

Perhaps a 3D multiplayer physics browser game is a bit too ambitious at this time. Anyway, I would like to hear any other stories.

Link to comment
Share on other sites

Good point. However, I tried running it only on the client with 240 static CannonJS boxes which is also slow. Most likely I am still doing something wrong though, since I have seen it perform better than that given some example demo's.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...