MMORPG development and server-side logic, updating all game objects?

I developed multiplayer games before, but now I wanted to create MMORPG Architecture for training / challenge purposes. I want to go as far as modeling hundreds (or a couple of thousand) simultaneous players on the same server.

So far so good, except that right now I ran into a problem to find a good way to update all game objects on the server as often and as quickly as possible.

By the objects of the game, I mean all the players, Mobs, Bullets.

The problem is that all players, Mobs, Bullets are stored in collections on server memory for faster processing and repeat all of them to check for collisions, update health, move updates, etc ... too long.

Suppose I have 1000 players and there are 10,000 mobs all over the world, and all players and creatures are responsible for creating 5 other game objects (no more no less), such as bullets.

This will give (1000 + 10000) * 5 = 55000 game objects in the collection.

Iterating over all objects, updating them, perform forever (a couple of minutes) on a dual-core HT i5 with 4-gigabyte RAM. It is not right.

When repeating the code, the code looks like this (pseudo):

for(int i = 0; i < gameobjects.Count; i++) { for(int j = 0; j < gameobjects.Count; j++) { // logic to verify if gameobjects[i] is in range of // gameobjects[j] } } 

As an optimization, I think about sharing my game objects in different zones and collections, but this will not solve the problem when I need to update all objects several times per second.

How can I switch to updating all game objects on the server side? I did a hard search to find interesting game design templates, but so far no results. :(

Thanks in advance!

+6
source share
3 answers

I would completely change the design and implement the design of the event base. This has many advantages, it is obvious that you only need to update the objects on which they actually interact. Since you will always have the majority of game objects in an MMO game without downtime or you will not see it at all.

There is no reason why you should calculate objects that are not visible on the screen of any player. This would be insane and require a server farm, which you most likely cannot afford. Instead, you can try to predict the movement. Or save a list of all objects that are currently not interacting and update them less frequently.

If the player cannot see the object, you can teleport the device over long distances instead of moving it smoothly. Essentially, the movement of the device occurs over vast distances within a limited area where the object can move. Make it look like the object is moving freely, even when the object is not displayed to the players. This is usually triggered as an event when a new player enters or leaves the zone.

You can achieve this by simply calculating the time since the last update and predict how far the object would travel, as if it were visible to the player. This is especially useful for objects or NPCs that have a given route, since it makes calculations much easier.

+4
source

Your code is slow, not only because it checks all N objects, but because it checks all possible interactions of objects, and this takes N ^ 2 calculations = 3,025,000,000 in your example.

One way to reduce this number of checks would be to place the object in the game world in a grid so that objects that are not in the same or aligned cells cannot interact with each other.

In addition, your current code double-checks each interaction, you can easily fix this by running the loop from self in your inner loop:

 for(int i = 0; i < gameobjects.Count; i++) for(int j = i; j < gameobjects.Count; j++) 
+2
source

Filling more than 55,000 objects should not be too slow. Obviously, you do too much on these objects and probably do things that should not always be done.

For example, if there are no players around the crowd, should this really be calculated? (if a tree falls into the forest and there is nobody there, does it really sound?)

In addition, many objects may not need to be updated in each cycle. Players, for example, can be left to the client to calculate and only "checked" once every 1-2 seconds. Dropping all collisions with the client will greatly simplify the processing of your server. The same goes for a player bullet or raycast. In turn, this also makes the game much more liquid for players.

Do I need to check mobs while passing the path to the collision or enough nodal paths?

Testing all objects to all other objects is terrible. Do I need to check all mobs against all other mobs, or do I need to check only a certain type or fraction? Can you divide your world into a smaller zone that will only check mobs inside it against objects in it?

There is a lot of work in the MMO server to make it work correctly. Performed optimizations are sometimes insane, but as long as they work.

0
source

Source: https://habr.com/ru/post/943819/


All Articles