[SOLVED] Zay-Es Networking Client Side Changes

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.

Is this okay, so far?

You could look at the actual example that does this very thing…

It uses sim-ethereal to keep the clients in sync with the server but the principle is the same. The camera rotation is independent of any entity.

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

and an implementation on server side:

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.

1 Like

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 …

Fork @pspeed’s project, then

  1. Break it
  2. Fix it.

Repeat 1 and 2 until you understand the messaging and entity system :slight_smile:

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:

Or you read the wiki entry about networking:

https://jmonkeyengine.github.io/wiki/jme3/advanced/networking.html#creating-message-types

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?

  1. 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

  2. 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.

Hey @asser_fahrenholz thanks fory your answer.

It’s rather 2.

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?

By the way, what is MVC ???

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.

1 Like

Well, that’s good to hear :smile:

That’s it! You are so right! Holy shit, how did I not see that :scream:

I can just apply the view direction, it’s just related to the “view”. Oh my god…
It’s done with calling

characterControl.setViewDirection(cam.getDirection());

After that I frequently send updates about my view direction to the server.

client.send(new ViewDirectionUpdateMessage(viewDir));

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… :unamused:

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.

Again, thanks to all, love you! :heart:

This topic is closed / solved.

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.

1 Like

I will look at it and give it a try, I promise! I will tell you how it is working in a day or two!

Don’t push yourself too hard :wink:
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?

Correct. Which is why you decouple the camera rotation from the player’s object rotation so they don’t get sick.

There is no way around it, really. Either they teleport all over the place (prediction) or they have lag (interpolation).

Still, the lag may not be as bad as you think except for connections that are probably too slow to play anyway.

Edit: added the prediction and interpolation words to signify that two basic approaches to networking. SimEthereal uses 100% interpolation.

Okay. So I have two options:

  1. I could use your library

  2. 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?

Same for the movement.

How would you know?

Then Valve is lying.

https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization

…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. :slight_smile:

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. :slight_smile:
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?

This is just one of the aspects of why it’s super-duper-etc hard to do. You will end up writing almost twice as much code, really.

1 Like