Server and world organisation

eah exacty my point, I only use one main tread that manipulates the entities, cause that way I can get the fastest speed without any further synchronisation. Complex taks like sql querys are done via a threadpool in the background and if finished enqued in the main thread with a Callable like object for doing the entity modifications.

re: “fastest speed without any further synchronisation”



But that is a sort of double-edged sword because you also can’t scale beyond one CPU for the most critical part.



None of my performance code has any “synchronized” keywords in it and yet much of it is still multi-threaded. Then again, I’ve been doing, reading about, and taking apart Java threading for more than a decade so there are things that don’t scare me as much these days. I remember Doug Leah’s concurrency stuff when it was just required reading for all top-devs, before they rolled it into the JDK.



I have a single command queue to resolve world state but that’s less about threading and more about easy consistency. If I cared about scaling up to MMO levels (which for these kinds of games, I think is a non-starter for indie development but that’s another conversation) then I could split this command queue based on zones without additional threading issues. But I’d be hit with bigger problems than that since an MMO requires a farm of servers.



Our comfortable little game loops shudder at that thought. :slight_smile:

Well thats the trick I have zones that are independent, actually can even be on different servers, one node is designed to be able to handle 300 players at most. Also I can run multiple zones on one server, so whenever I reach those 300 player limit a split would be done. And best of all i can dynamically move complete zones to different Servers without any problems. (Also my game loop is really a bit more complex but always have one synchronize point each tick, everything more complex then setting values is done in tasks n background threads. So untill I reach the limit of values one thread can set i’m pretty save.

Hi, people

Can’t hold from adding my point of view. For MMO game very important moment is scaling ability, creating for every new player new thread is total waste of game potential, and machine resourse. I’d like to think about server side like about something Godlike creature :stuck_out_tongue: All from his world contains only in his head(no matter it one-head or four-head) Client send to server request for change it location, and serv kindly remember new location of player. When client doesn’t do anything server has a time for requests from other players.

Client draw world for player, and listen it input(just regular pressing of key). Server listen clients and, when they ask, write changes in states of different objects(Game logic). Server doesn’t have to care about how client draw world from his head, important only that world was drawn from his head. So all people playing game, see and line in one world.



In most simple case MMO-Game is database that contain player position and logic to change it. Threads used only to process requests from client side. Thousands change in seconds is lot enough for server to not feel itself lonely.

Sorry for long and abstract post :slight_smile:



p.s. in my game loading terrain is doing in next kind. Simply load 8 terrains quad around quad were player stay. They have size equal to distance view. Distance view i found with a series of experiments :), so that doesn’t stress machine performance and have a pretty look. For optimization i try to separate objects to different layers such as: draw trees not far then 10units from player, buildings 30u, players 20u…

So thank you for the feedback. So I have now a picture how it could work on server-side.



@pspeed

After your post I had a look at entity systems and read some interesting articles on t-machine.org. It sounds very handy. So I will play around with it.

I saw you are still using it on Mythruna, so you have some useful hints.

And I will think about what you and “mpirePhoenix” sad with the threading and synchronisation.



@EmpirePhoenix

So you use a central instance (I will call it instance maybe there is a better word for it) which represents the database access (for entity manipulation and access in the database). All your areas / zones are communicating with that instance?

Well I have a space game with sectors, whenever you travel trough a jumpgate you will be connected to another server application in background while you see the travel. This has the advantage of no overlapping Zones.

There is one central Databaseserver, however no central commandserver so far(there will be later for high level world and god AI systems). The Entites are Java objects, that only write on important changes (like a larger trade process, rare items, disconnect, ect) the changes to the database in background.

Since each entity can only be in one Zone, I usually don’t have any problems that different Zones have inconsitent data. (on a transmit all data regarding a player is saved, then the transmit is initiated, so ensure the other zone only load correct data). Also it is possible to find out where(host + port) a Zone is located over the Database, and query it directly from another Zone, if the data in the Database would be insufficient. (Like for chat messages). Again this runs non blocking in the background.

risor said:
So thank you for the feedback. So I have now a picture how it could work on server-side.

@pspeed
After your post I had a look at entity systems and read some interesting articles on t-machine.org. It sounds very handy. So I will play around with it.
I saw you are still using it on Mythruna, so you have some useful hints.


Did you see this article and subsequent discussion:
http://t-machine.org/index.php/2011/06/24/using-an-entity-system-with-jmonkeyengine-mythruna/

Or just the post I did here on the JME forums?

Since I'm not writing an MMO, I was able to optimize the performance of my entity system queries a lot. I'm not sure how well it transfers to MMO-scale systems but I guess the interface and calling sequence that I use is still useful. It presumes that their might be some way of more efficiently knowing that an entity set has changed... and I think that even in a server farm setup there would be cross-machine cache synching going on that could still provide optimizations in that model.

Other than that, I think it will depend on how you approach it. I will say that I ended up creating a client-side view of the entity system but that it is read-only. So the client has the ability to read and watch the entities but can't change them directly... and the server can further filter what the client is allowed to see. The real entities live on the server. Any changes the client does to entities are done as commands that are sent to the server. There are a few benefits to the this approach: 1) it closes about a million opportunities for cheating that you might never catch all of, 2) since commands usually make several changes to the entities at once then these operations are now more atomic than individual component changes would be... thus you get away from having to worry about actual transactions.

When you get hot and heavy into entity systems then I may be able to answer more questions. Until then it's probably all confusing noise. :)

Yep, same for me, I replicate a subset of all entities to the client, however the client can only send requests (like input binding request forward, it#s complelty up to the server if how that data is handled then. The only exception is camera turning, since a small delay there (even 10ms or less) are really fellable, whiel walking with a 50ms delay is not recognized by many persons at all)

Yeah, rotation is fully predicted for me and always will be for the same reason. Even when physics is finally pushing the user all over the place, I will lock orientation to the client camera because otherwise you make the user sick. :slight_smile:



To further expand on the potential for cheating if the client has direct access to the entity system, let’s take the example of picking up an item from the world in my RPG-style game. An entity has a Position component when its sitting in the world somewhere and it has an InContainer component (pointing to the player) when it is in a player’s inventory. It would have been really easy code-wise just to let the client directly manipulate these components but then a hacked client would be able to add any item anywhere to their inventory if they just knew the ID… or move items from one player to another. Also, the separate client->server messages necessary to change two components potentially leaves the world in an inconsistent state.



So, instead there is a “pick up” command (entity action is what I call them). The client sends the ID of the action and the ID of the entity upon which to perform the action and the server runs the command (usually a piece of groovy script these days) which in addition to other checks can add the InContainer component and remove the Position component. The client just sees the changes (or not) when they come back through.



It’s very clean and very safe. Only the commands themselves need to be locked down. And the server can more reliably filter what components and entities are even visible to the client. (For example, the paranoid in me has a custom EntityId serializer that makes sure player entity IDs are turned into client IDs on the fly… so one client will never be able to see that real entity ID value of another online player. While I can’t think of specific attack vector that information might allow, it just felt safer to keep it server-side only.)

Well I have temporary networkids, taht have nothing to do with the real entityid, so that info is kinda useless in my case, as it changes from time to time, you cannot determine with the id what awaits you

Yeah. In my case, I persist a whole bunch of state about users and other entities… and it just seemed better if the clients could never specifically get the real ID of another player. The temporary network IDs in this case are just the client IDs that SpiderMonkey gives connections.