Zay-ES-Net

Hi i have some questions about the Net Library

  1. How am i supposed to send Data from the client to the server, (other way i got) over the normal Monkey Zone?
  2. How do i Catch them? normal Monkey Zone Listener or AbstractMessageDelegator?
  3. Do i have to Serialize all the Component Classes or is this done by the Framework.

I think i will later have some other questions, but this is it for now.

Linard

Answers in reverse…

  1. The components that you want to send over the wire (probably most/all of them) will need to be marked with the SpiderMonkey @Serializable annotation. Those classes will also have to be registered with the Serializer.

  2. You listen for messages in the conventional way. You can register a MessageListener as needed on the Client or the Server. None of this has anything to do with Monkey Zone which isn’t Zay-ES related at all.

  3. Messages that you need to send will have to be @Serializable as above and you will have to send and receive them. Often with Zay-ES Net you won’t need to if you are clever about how you use your entities. Often, a proper ES design avoids a lot of these messages. (some will always be required)

If you haven’t already, you can look at MonkeyTrap which is the example I created for developing Zay-ES Net. It sends a minimal number of non-ES messages. All of the ES messaging is done automatically for you.

More detailed answers may depend on the type of game that you are writing.

1 Like

First thank you for the fast response. I made a little mistake in my Question :stuck_out_tongue: all the Monkey Zone should be SpiderMonkey xD

  1. ok thats clear, thx allot.

  2. of course Monkey Zone has nothing to do with this sorry :stuck_out_tongue: , so I use the normal MessageListener of SpiderMonkey to catch Components or entites?

  3. Ok that point is not so clear for me.
    I understand how i can automatically sync server and client with the RemoteEntityData and the HostedEntityData but as far as i can see this just syncs all the entities from Server to Client. When my Player now moves, how do i change the entity on the server now? Is there a way to automatically sync the client to the server? Or is this just done with a normale Message with SpiderMonkey?

@linardschwendener10 said: First thank you for the fast response. I made a little mistake in my Question :P all the Monkey Zone should be SpiderMonkey xD
  1. ok thats clear, thx allot.

  2. of course Monkey Zone has nothing to do with this sorry :stuck_out_tongue: , so I use the normal MessageListener of SpiderMonkey to catch Components or entites?

No. The components are transferred automatically.

@linardschwendener10 said: 1) Ok that point is not so clear for me. I understand how i can automatically sync server and client with the RemoteEntityData and the HostedEntityData but as far as i can see this just syncs all the entities from Server to Client. When my Player now moves, how do i change the entity on the server now? Is there a way to automatically sync the client to the server? Or is this just done with a normale Message with SpiderMonkey?

Ah, yes. The client will have to send messages to the server. These are usually higher level commands since you never want the client directly manipulating the entities. So if it’s an RPG like game, you might send a MovePlayer() message or AttackThisThing() message. The server will receive those and do whatever is appropriate to manipulate the entities and make that happen.

…this is where it’s difficult to provide more specific advice without knowing what kind of game it is. Turn-based RTS, RPG, real-time FPS, etc… these will all be handled a little differently.

1 Like

Monkey Trap is one of the Zay-ES examples and I think is linked from one of these Zay-ES posts… it has networking if you want to look at it.

1 Like

it schould be something like rpg (little diffrent but to explain thats ok)

So i understand now how to update the Entitys on the Server, but one question is still in my mind.
In many games i know, as an example WoW if you disconnect, you can still move around an the player moves himself, so there must be a kind of entity in the client wich gets moved.

How would you do this? or would you not allow this?

My Problem with it ist, I could Copy the RemoteEntityData and just Display the Copy, and “manipulate” the copy and in the Same Time send an command to the server that the player wants to move. Then i could update the “Local” Data with the Remote data sometimes. But i’m not sure if this is a good idea, because with that the hole RemoteEntityData System gets a little unusfull. A other problem wich appears in my head is that often if the “Local” data gets updatet the Player will move a little back, because the remote would be never on the same state due of the fact that the whole information has get updatet to the server and from there back to the client.

How would you solve this?

If the view can move regardless of what the real data is doing then (aside from the fact that I’d call that a bug) I would not consider that part of the entity system at all. It speaks more to how they predictively handle input.

For example, if could be that player/camera movement is allowed to run independent of what the entity system is saying and then get reconciled later. It’s one way to deal with lag. This is not really an entity system problem The entity system is still saying “go here” periodically but you are just choosing to do something different with that information.

I don’t know if I’m making sense. I definitely wouldn’t try to saddle the ES with representing fake state, though. Too complicated.

1 Like

Ok i alsow got that, thank you :slight_smile:

Now i have some other Problems :stuck_out_tongue:

  1. Class has not been registered:class com.simsilica.es.net.GetEntitySetMessage
    I Think this is because i have to “move” some Files to SpiderMonkey, (thats written in the ClassSerializer and ClassFieldSerializer) But i have no idea what “Needs to be moved to SpiderMonkey.” exactly means. Do i have to replace files? could you explain what i have to do with them?

  2. How should i store the Geometrys in the Client? If a entity has a Gemotery there must be a connection between them, i would use the ID of the Entity, but how do i store them so i can easy find the Geom with … Id? I tought about Arrays, like
    geoms[entityId.inInt()] but because of the fakt that the IDs are Random and could get verry large (if i dindt missunderstand something) then this is not very clever. Whats your advice to store them?

Thanks :slight_smile:

@linardschwendener10 said: Ok i alsow got that, thank you :)

Now i have some other Problems :stuck_out_tongue:

  1. Class has not been registered:class com.simsilica.es.net.GetEntitySetMessage
    I Think this is because i have to “move” some Files to SpiderMonkey, (thats written in the ClassSerializer and ClassFieldSerializer) But i have no idea what “Needs to be moved to SpiderMonkey.” exactly means. Do i have to replace files? could you explain what i have to do with them?

Somewhere in both your client and your server you need to call EntitySerializers.initialize(). In MonkeyTrap you can see this in ConnectionState on the client and in GameServer on the server.

@linardschwendener10 said: 2. How should i store the Geometrys in the Client? If a entity has a Gemotery there must be a connection between them, i would use the ID of the Entity, but how do i store them so i can easy find the Geom with ... Id? I tought about Arrays, like geoms[entityId.inInt()] but because of the fakt that the IDs are Random and could get verry large (if i dindt missunderstand something) then this is not very clever. Whats your advice to store them?

Thanks :slight_smile:

A HashMap<EntityId, Geometry> I guess. Are you familiar with the java collections classes?

1 Like

OK thanks again for your answer works :slight_smile:

Now i have a other problem :stuck_out_tongue:

The RemoteEntityData gets updated when a Entity is added on the Server but is not updatet when the server delets a entity.

Example

Entity 1 gets added on Server, Client gets it
Entity 2 gets added on Server, Client gets it
Entity 1 gets deleted on Server, Client says the Entity 1 is still in RemoteEntityData.

If i connect with a second Client to the Server he just gets Entity 2 in the RemoteEntityData.

How can this be?? do i need to set a special listener for delted Entitys?

Sorry i have no idea what the problem is there :S

@linardschwendener10 said: OK thanks again for your answer works :)

Now i have a other problem :stuck_out_tongue:

The RemoteEntityData gets updated when a Entity is added on the Server but is not updatet when the server delets a entity.

Example

Entity 1 gets added on Server, Client gets it
Entity 2 gets added on Server, Client gets it
Entity 1 gets deleted on Server, Client says the Entity 1 is still in RemoteEntityData.

If i connect with a second Client to the Server he just gets Entity 2 in the RemoteEntityData.

How can this be?? do i need to set a special listener for delted Entitys?

Sorry i have no idea what the problem is there :S

“Client says the Entity 1 is still in the RemoteEntityData”… what does this mean exactly?

Is it part of an EntitySet? Did you update the EntitySet? Did you check for removed objects on the EntitySet?

@pspeed said: "Client says the Entity 1 is still in the RemoteEntityData".... what does this mean exactly?

Is it part of an EntitySet? Did you update the EntitySet? Did you check for removed objects on the EntitySet?

I have a com.simsilica.es.server.EntityDataHostService on the server
and a com.simsilica.es.client.RemoteEntityData on the client.

if i add a entity to the EntityData wich is connected to the EntityDataHostService on the server and sendUpdates() then the added Entity alsow appears in the RemoteEntityData on the client.
But if i delete a entity int the EntityData on the Server and then sendUpdates() the RemoteEntityData on the client still contains the Entity. (i was using a EntitySet on the client but when i saw that EntityRemoved wasnt called i was looking where the “problem” appears, and yes i used applyChanges() then i checked if the entity is still in the RemoteEntityData and it was)

I have no idea why the automatic Client Server connection of Zay-ES-Net can add but cant remove Entitys :S

I hoppe you understand now :slight_smile:

Entities can never be “removed” because they never exist except as a number. The number 6 can still exist after the entity’s components are removed, for example.

Deleting an entity removes all of its components. Those component removals should have been sent to the client if that client had an EntitySet containing the entity.

Hmm ok i see, you are right entity is still there, but if i try to get the Components i get a NullPointerException.
But why is the getRemovedEntities() empty then? Here are some code pieces:

In the SimpleInitApp:
[java]remoteEntityData = new RemoteEntityData(myClient, 0);
playersSet = remoteEntityData.getEntities(CPosition.class, CClient.class);[/java]

In the SimpleUpdate:
[java]if(playersSet.applyChanges()) {
createPlayer(playersSet.getAddedEntities());
updatePlayer(playersSet.getChangedEntities());
removePlayer(playersSet.getRemovedEntities());
}[/java]

getAddedEntites() gives back the added Entities so it cant be the server connection or the Entity Set, and the CClient and the CPosition Components are 100% deleted. So why does getRemovedEntities() gives nothing back ?

@linardschwendener10 said: Hmm ok i see, you are right entity is still there, but if i try to get the Components i get a NullPointerException. But why is the getRemovedEntities() empty then? Here are some code pieces:

In the SimpleInitApp:
[java]remoteEntityData = new RemoteEntityData(myClient, 0);
playersSet = remoteEntityData.getEntities(CPosition.class, CClient.class);[/java]

In the SimpleUpdate:
[java]if(playersSet.applyChanges()) {
createPlayer(playersSet.getAddedEntities());
updatePlayer(playersSet.getChangedEntities());
removePlayer(playersSet.getRemovedEntities());
}[/java]

getAddedEntites() gives back the added Entities so it cant be the server connection or the Entity Set, and the CClient and the CPosition Components are 100% deleted. So why does getRemovedEntities() gives nothing back ?

I don’t know. I do this exact same sort of thing in the networked version of Monkey Trap and it seems to work fine and I see the deletions.

How are you determining that getRemovedEntities() is always empty?

[java] private void removePlayer(Set<Entity> entitySet) {
Iterator<Entity> iterator = entitySet.iterator();
while(iterator.hasNext()) {
System.out.println(“Test”);
Entity temp = iterator.next();
gameObjects.get(temp.getId().getId()).remove();
gameObjects.remove(temp.getId().getId());
System.out.println("Removed ID: "+iterator.next().getId().getId());
}
}[/java]
The while gets never executed :S

BTW:
i’m not totally sure if im using some Methods correctly.
EntityData.getEntity(EntityId, XXXXXXXXXXXXXXX)
What am i supposed to write instead of the X? i know its a class but wich and why? The class of a component of this entity?

Same thing with:
EntityData.findEntity(Filter, XXXX)
is X the class wich is given as the parameter at evaluate() in the Filter?

At the moment, it works but im unsure if that could cause any trouble :S

@linardschwendener10 said: [java] private void removePlayer(Set<Entity> entitySet) { Iterator<Entity> iterator = entitySet.iterator(); while(iterator.hasNext()) { System.out.println("Test"); Entity temp = iterator.next(); gameObjects.get(temp.getId().getId()).remove(); gameObjects.remove(temp.getId().getId()); System.out.println("Removed ID: "+iterator.next().getId().getId()); } }[/java] The while gets never executed :S

BTW:
i’m not totally sure if im using some Methods correctly.
EntityData.getEntity(EntityId, XXXXXXXXXXXXXXX)
What am i supposed to write instead of the X? i know its a class but wich and why? The class of a component of this entity?

Same thing with:
EntityData.findEntity(Filter, XXXX)
is X the class wich is given as the parameter at evaluate() in the Filter?

At the moment, it works but im unsure if that could cause any trouble :S

Regarding your first issue, I’m still not sure what’s happening. It (apparently) works in Monkey Trap or at least did the last time I ran it.

Regarding the other stuff…

First some clarification on terms.

“entity” (with a little ‘e’) is a concept. It’s an ID and a bunch of components.

Entity (with a big ‘e’) is the class Entity which is a view of a subset of an entity’s components. A snapshot of when it was requested or last updated.

So EntityData.getEntity(EntityId, XXXXXXXXXXXXXXX)
…the XXXXX should be the components you want to get in the entity view: Entity

Find is similar. I should probably see about changing the parameter list to Class<? extends EntityComponent> or something to make that clearer.

1 Like

Ok then i used them correct.
One little other question :stuck_out_tongue:
[java]playersSet = remoteEntityData.getEntities(CPosition.class, CClient.class);[/java]

Is this a AND or a OR connection at the Parameter? Does that mean that Cposition and CClient must be a componnent of the entity, or that just one of them, so it’s part of the EntitySet? (i tought it was AND :S)

For the problem i’m experiencing, could i have the uncompiled EntitySet class so i can debug where the problem is? :S

Thanks again for your great and extremly fast help :slight_smile:

It’s AND. The entity set should only contain entities with both of those components.

All of the source code is here:
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/zay-es#zay-es%2Fextensions%2FZay-ES-Net