Hello again,
I have a question about networking with an entity system: Sometimes you want certain events to be applied instantly, for example the rotation / looking direction of the own character. There is no need for the server to “calculate” this. The view direction of the character should be sent to the server. But I read that EntityData on Client side is read-only. How would implement this in this case?
EDIT:
One solution would be to send a ViewDirection message containing the new view direction to the server which sends this update to all other clients.
After all, there are only a few message types like this that allow you to ask the server for a change.
Yes, you can not edit entities component from client side, it’s read only.
You should use RMI services to contact with server.
See PlayerMovementState
It calls server to send movement information to server .
It uses RMI service for contacting from client to server. Suggest to take some tutorial about Java RMI to understand the logic. You can find some nice tutorials on YouTube.
For setting up an RMI service you need to have an interface,
an implementation of the interface on client side which actually calls to the server
It can be useful for concepts but do note that this RMI has little to do with Java’s built in RMI.
Edit: also note: RMI is convenient but not necessary. One could just as easily write custom messages, listeners, etc… I just personally find that I write much less boiler plate with SpiderMonkey’s RMI implementation when doing simple calls.
Okay, first of all, thank you @pspeed and @Ali_RS for your answers!
When I understand it correctly I can’t just set the new rotations of the player on client side, because it will be replaced with the old one in the next frame by the entity system. (well, the es doesn’t do this actually, but rather the systems)
How exactly would that work? Sorry if this a noob question but I really have problems understanding the whole thing? By the way, I have never used RMI or something like that, neither I heard about it …
Thanks @Ali_RS for that respose! I just had a look at it again and what earlier was total confusing for me, now is starting to make sense! I will follow your recommendations in regards of RMI.
However, depending on what feels easier to me, I will either chose RMI or custom messages.
This issue of this topic also seems to has the same origin:
Then you know how to create a message to send information to the server (for example view direction). You will soon realize that you sometimes have to write a lot of code to achieve simple things. For sending the view direction you have to write a message class, add listeners to the server and send the message. Then you ask yourself if there is a method to do it faster. It would be nice to call a method on the client which is executed on the server. setViewDirection() would be a nice method. Here RMI (“remote method invocation”) is helpful. It is a feature of SpiderMonkey which allows to define those useful methods. As mentioned before you shouldn’t mix it up with java’s RMI service. Those are different things. Even if you think RMI is the way I recommend that wiki entry to you to learn the basics.
Now I want to drop my thoughts about your concrete request (setting the view direction). Personally I think it is a very bad idea to send the mouse input to the server, let it change the component, receive the new component and then set the view. Lots of network latency will slow down the progress and maybe the changes of the components won’t be instant sent. You will notice the lag if you move the mouse even in a local network.
A better way is to ask yourself: Why do I need the view direction?
to change the camera direction:
In this case it is really only a matter of the view and not the component in your MVC. → update the camera on mouse move
to update game data. eg. the shoot direction:
In this case send the view direction to the server and apply it to the components. But use 1) for the camera.
Maybe a bit late but I hope I could give you some incentive to think about your MVC.
However, I have a first person game so the camera direction is defining the view direction of my player who has a BetterCharacterControl which in turn creates the rotation for the player. But the rotation is defined in a component which I am not allowed to modify.
The second approach is actually doable. But I guess you will notice the lag when you turn right but your character follows slowly (after a delay). Do you think this will be notable?
First yes it will be noticeable. Mouse moving is very sensitive.
Let’s start with MVC. Its a design pattern often used in games: model-view-controller
The model is your entitydata only relevant data for the game state. The view handles how things a drawn. And the controller handles the logic. Think of a player entity. It has a position and maybe a definition for its physics shape (a capsule). The logic moves it (If key up is pressed change the position component). Then you have a spatial. (I use the term spatial and not model to not confuse you with the design pattern model which is only data). But who cares about the spatial? Only the view. It uses the position to put the spatial at the right place in the scenegraph. No need to set the spatial on the server.
Now let’s come to the view direction. Of course you want to turn the character if you move the mouse. But who cares about this? The model doesn’t because a capsule looks always the same. You can’t turn it. Only the spatial (or camera direction) should be turned.
Hey it’s a shooter and I want to shoot at a certain direction! The logic which processes the shoot (raycast, lower health component, raise score component,…) should run on the server. No problem in this case you separate the view direction from the view. Keep updating the camera as described above but additionally call setViewDirectionComponentOnServer() to update the entity data. This call could be less frequent and doesn’t need to be instant because the view direction component is never used by the client. It is only used by the server( which handles the game logic) to process the shoot logic. It is ok to have lag between the input and the shoot logic because in most cases it doesn’t matter if you get a point 200ms later. But it does matter if it needs 200ms to turn your head.
Fast paced network games are difficult because you have to think about the lag. There are multiple techniques to enhance the feeling of the game but most of them have their downside. You will have a hard time getting them right but be comforted even big commercial games have their issues with multiplayer.
Edit: I just saw that you use a better character control
I don’t know how it is connected to your entity system and I’m not that sure how it uses the view direction but I can explain how I do the movement.
I calculate a movement vector based on the view direction and the pressed keys on the client and send this vector to the server. This vector could be used to move your character control. And then the resulting position could be set as component and send to the client via ZayES networking. I think pspeed has some special components for positions. They should be used in the examples. As you see I wouldn’t use the view direction on the server for movement.
Edit2:
That’s the reason why I would update the camera without asking the server (see point 1). And the logic is allowed to be delayed.
The server sends this updated view direction to all other clients.
WOW, it’s so easy actually. But as always I just think to complicated…
Movement is not the problem. However, that is exactly what I am doing right now! But same here, I don’t want the player to “wait” before the player actually starts walking. I do the calculation like you described and apply it locally. But I also send the calculated vector to the server who does the same thing actually and only if there is inconsistency, the position on client side will be corrected.
For real time “fast paced” networking, you should really look at SimEthereal if you haven’t already. It takes sort of Valve’s approach to real time networking.
…and it’s what’s used by the sim-eth-es example that I already linked.
Don’t push yourself too hard
For me it took a few weeks to familiarize myself with it.
I first took sim-eth-basic (non ES) example to understand those RMI services and SimEthereal after that I came to study the ES version. And off-course the Zay-ES Case Studies did help a lot thanks to @ia97lies
Edit:
And when ever I was sticking at some point understanding Zay-ES, SimEthereal, and examples, I asked them on forum. It might be helpful to take a look at them.
Hey @pspeed even with this library I would send my movement to the server where it is used to apply the new position. But it still does not apply locally first, right? I have to wait until the server responses, or not? Wouldn’t that cause notable lags for players with a “bad”(slow) connection?
I create custom messages like “hey, here is my new camera direction, go and create the new player rotation”. The server applies this in the entity system and the clients will get notified. In the end, the camera rotates instantly but the player itself needs a little bit of time to follow. But isn’t it in most games that the player also instantly moves with the camera rotation?
…or you could actually LOOK at what I’ve already posted and ask more informed questions after that.
Or you could just try to run it to see how laggy it feels.
Or, since extrapolation/prediction is actually super-duper-duper-pooper-duper-super hard to do… you could use the already written code in SimEthereal until it’s a problem and then point your team of developers at the problem, spending all of your mad game $$$ you earned up until that point.
These two things are not mutually exclusive. The sim-eth-es example uses a custom message (through RMI) to send player orientation and thrust to the server constantly. SimEthereal is responsible for sending out position/orientation update for the objects in your surrounding view space.
Though I have to feel like all of this is apparent if you take apart the code in the sim-eth-es example.
Okay … I will look at it.
Is this faster than just sending “normal” messages?
Actually I don’t have any problems to try out your library. I am glad that something like this exists, furthermore developed by a smart guy like you. (yes, what you have already contributed to jme is incredible! Respect!) Anyway, I just wanted to be aware of the options I have.
Something different, do you think client side prediction would work here as well? Furthermore, how would client side prediction be implemented? I know you run the same code as the server and correct if they are “conflicts”. But the thing I am not allowed to edit entity data on client side, so I’d have to make my Position/Rotation component mutable, right?