Aoi server implementation

Source: Internet
Author: User

This is purely a collection. If any conversion is made, please mark the source as follows to show respect.

 

> Author's blog: Yunfeng's blog

 

Separate the AOI part

 

The question of AOI should have been discussed 2nd times on the blog, and it should be counted that the previous article was not published.

I just came back from a business trip yesterday and chatted with the server master of Datang in the evening. When I encountered the AOI issue, I proposed a solution to separate this module and record it here.

Aoi has two main functions: one is to broadcast messages to players in the vicinity of the game geography when the role (player or NPC) on the server acts. When there are not many players in the process, they can directly broadcast connections throughout the process. This process is the easiest. As the hardware improves, it may be the mainstream method in the future. However, to reduce the amount of data processed, especially the bandwidth, we usually need to cut some data in the AOI module.

Second, when a player approaches the NPC, the AOI module will send a message notification to the NPC once it enters the NPC's alert area, which is suitable for AI response.

There are many AOI implementation algorithms. We will not discuss them here. I am currently concerned about whether AOI can extract this module from an independent process if it is very important in the game (especially for the MMO scenario in the instant combat mode.

First, let's look at the first requirement. In fact, in games, most messages that need to be broadcasted are not sensitive in order. For example, it doesn't matter whether a moves first or B moves first. For example, whether an attack first attacks then moves, or whether it moves first and then attacks. I refer to the order in which the client receives messages. Whether or not the attack is started depends on the distance, but the server logic has verified validity before the attack command is sent. That is to say, the information sent from the server is legal, and the client does not need to care too much about the location change before or after the attack.

Then, we split AOI broadcast's responsibilities into independent processes, so we do not need to coordinate the packet sending order with the logical process. This is good news.

Design an AOI process so that the logic process sends a packet to inform the AOI process when any object changes its location. This means that the OIO process copies the Object Location status. Later, when an object needs to broadcast its state changes, it only needs to send the message to be broadcasted to the AOI process, and then the AOI process filters it out (screening out nearby objects, ).

Note that messages occur asynchronously. When the client receives the Object ID, it should filter out some expired ID numbers. The Logic Server may have deleted an object, but the AOI server later sent messages related to this object. (It is a bad idea to forward the deleted object messages to the AOI server, because this increases the responsibilities and complexity of the AOI server)

For AOI Message notification problems, the AOI server can send a message to the Logic Server when detecting that the object has intruded into another's warning zone. This message does not require real-time response. For example, the planning requires an NPC to have a 20-meter warning zone. In fact, it does not need to be triggered on the boundary where the player is just 20 meters. It doesn't matter if the delay is half a second. The larger the alert area, the longer the latency is allowed.

A separate AOI service can be sorted by priority based on the radius of the alert area. Then send the notifications one by one in an orderly manner.

Compared with the independent AOI module, the independent AOI process has a lower Coupling Degree. Protocol coupling rather than interface coupling. It is easier to maintain and optimize later. Not shared with the logic, reducing the possibility of bugs.

PS. I recently spoke to my new colleagues about a class. In fact, I didn't talk much about technical things. I only introduced the development history of the game industry, computer hardware, game evolution, and a little progress in software development.

I think that all history is being witnessed. Only by keeping things simple enough can we develop smoothly. If they are not concise enough, one day we will discard them or pay for them. Hope to give some inspiration to the students who have just graduated from learning.

The day before yesterday, I took the time to read the server code of Datang 2, which was newly operated for an hour. Find a hidden bug. It is said that this project has just been open to the outside world for the past few days, the situation is not very good, always act as a machine. Programmers should understand that it is not necessarily a lot of bugs, but it is enough for you.

The server of Datang 2 was very "exquisite", and C ++ and Lua had been around, and I was almost confused. Too complicated ......

 

Aoi server implementation

 

I have talked about the implementation of AOI (area of interest) many times before, because our games are still under development and modules need to be done one by one. When there are not many objects in the game world in the early stage, we can use an O (N ^ 2) algorithm to check the relative distance of the objects in two or two times. This is just a benefit. Over the past few days, I started to implement the independent AOI server I talked about on the blog some time ago.

Since it is an independent process, designing protocols is the most important. After some consideration, five protocols are required. Four are sent from the scene server to the AOI server (listed below), and one is sent back to the scene server by the AOI server.

  1. Create an AOI object and set its default AOI radius. Note: Each object has a default AOI radius. any other object that enters the Radius Range for the first time triggers the AOI message.

  2. Deleting an AOI object may also trigger the departure message from other AOI objects.

  3. Move an AOI object, set the new (2D/3d) coordinates, and give the suggested value of line speed.

  4. Set the radius of an AOI object relative to another AOI, and overwrite its default setting. Note: the AOI radius can be divided into two types: one is the entry radius and the other is the exit radius. Generally, at the beginning, each AOI object sets an entry radius for other objects. When a message is triggered, a exit radius is reset by the scene logic. For example, the default radius of an AOI object is 10 meters. After it is created and coordinates are specified, any object enters the 10 meters range, the AOI server will immediately send an AOI message, and the two will not automatically trigger the message. After receiving a message, the scene server can actively set a new AOI exit radius of 12 meters to the AOI server. When this object is far away from 12 meters, it is triggered to exit the message; next, reset the scene server to enter the radius.

This Protocol is relatively simple, can meet the general needs of the game, and hide the implementation details of the AOI service. All objects are transmitted in handle mode, and the Scenario Server ensures handle uniqueness. In this implementation, each AOI object can have only one AOI radius trigger at the same time, but the Protocol itself does not have this limit.

Next, let's take a look at the implementation details.

Generally, the AOI module has two implementation methods. The most common and concise method is to create a grid. Whether it is a small grid, a grid can only occupy one object, or a large grid (a grid is a large area, and the O (N ^ 2) algorithm is used in the area to compare one by one ), the implementation is clear and clear.

According to the kiss principle, we recommend that you use the lattice Algorithm without special requirements. Of course, there are also some shortcomings in the lattice algorithm, such as the memory consumption of the lattice itself, which is related to the scene size, but not to the object implementation. Sometimes, A large amount of memory will be wasted (independent processes can avoid this problem to some extent); for the variable AOI radius, the fixed unit long lattice solution also has a slight defect in efficiency.

Another idea is that I learned about it a few years ago when I chatted with my colleagues in the World Group. Create two or three dimensions of a line segment for each object, and insert and sort the line segment endpoint. I am not very interested in this algorithm.

I lie down early last night, and I couldn't sleep. I thought of a new idea to implement the AOI module.

The most kiss solution is to compare the distance between AOI objects one by one for each heartbeat. The time complexity is O (n ^ 2), which is the best solution in N hours. Because its implementation is very simple. Note that for objects a and B, a B and B A are two groups. This is because the AOI radius of A is likely to be different from that of B. Then for n objects, we need to compare N * (N-1) times. Unless players in the game are in small copies, and the number of replicas is small (or there is no need to do AOI between NPCS), it is unacceptable in large-scale scenarios.

BTW, the so-called passive blame, is the NPC that does not need to perform AOI processing. In many games, they are placed in large quantities. In addition to helping the mentally handicapped players quickly upgrade, they are also designed to save server resources. The NPC in WoW will also encounter and fight in the wild, and the NPC will call the design of friends together. In fact, it is a very test of the performance of the AOI module.

How can we improve the performance when n is large?

We do not need to detect the distance between distant objects from time to time. While most objects are separated far beyond the AOI radius of both sides. We only need to improve the algorithm from here, which may greatly improve the performance.

It is easy to think of using a timer. We can estimate the minimum encounter time based on the distance between two objects and the moving speed. This time often exceeded a heartbeat. At this time, put the AOI check in the timer queue.

I am doing this in implementation: the scenario server is required to send a suggested value of line speed when sending the object coordinates. I calculated the shortest time of an object's encounter by double this value and registered timer. You can ignore it as long as it is no more than twice the speed. Otherwise, re-calculate all target distances related to the object and adjust the positions of all corresponding timers in the timer queue (this requires a dedicated timer module to provide this function ).

There is still a problem with this optimization. It creates a timer node for each pair of objects. Therefore, the space complexity is O (n ^ 2), which may greatly exceed the memory budget (although the independent process can alleviate this problem, as long as you think about it, N may be tens of thousands, how serious the problem is ).

We need further optimization.

In the game, most of the objects are old and dead, because they are NPCs in different places. Only a very small number of NPCS in different locations will be migrated by script design. The number of players, who may have a large range of activities, is an order of magnitude less than the number of NPC players. We only need to remove unnecessary data in the memory.

Assuming that the 100-meter radius is a relatively large range in the game, the NPC will not go beyond the range of this activity, it usually takes some time for a player to run 100 meters (this takes several seconds, and the second is a long time unit for the CPU ).

We can set a 100 M activity range for all objects. If the linear distance between two objects is greater than 200 meters plus their maximum AOI radius, we can not record the relationship between the two objects (think they cannot meet ). Once an object leaves its original record origin more than 100 meters, it is considered to have migrated, immediately compare all the objects in the scenario (time complexity O (N). This operation is slow, but it is acceptable and does not happen frequently.

To sum up, it is a framework of the AOI service that I implemented this time. It takes two or three days to implement these functions.

 

About AOI server Optimization

 

Last year I wrote a few articles about AOI module design. The design of the AOI service independent has long been determined, and has been recognized by other project teams to a certain extent. (There are already several projects that are intended to be improved during internal communication)

Recently, I have been doing further work in this area. (Mainly implementation)

First, some unnecessary details of the original protocol are deleted based on kiss. For example, the AOI module is no longer notified about the object moving speed. Although the moving speed is meaningful for optimization, it is redundant data after all. To consider this, it is easy to fall into the trap of advance optimization.

Secondly, a protocol is added to set the default region of interest. This is out of practical consideration.

In the original consideration, I wanted the app to set an AOI message for each object as needed. However, when there are too many entities in the scene, a large amount of inter-process communication bandwidth will be wasted (the memory and processing speed can be optimized ). Generally, an AOI entity does not involve any other entity that is too far away. Therefore, a protocol can be added to reduce interaction between modules. That is, the messages between old and dead entities are directly filtered out.

In terms of implementation, I adopted the simplest tower of hope solution. If the application layer requires that each object care about other objects within a radius of 100, a tower object is set at an appropriate interval (for example, 100), and the tower notifies the object, what is nearby.

The tower is invisible to the application layer. It is just a specific implementation solution. However, this notification protocol only guarantees the omitted information. Only the notification object. The addition and deletion of objects nearby (not necessarily the strictly set radius, but must be greater than the range set by the application layer.

The Application Layer maintains a private set of visible messages based on this protocol, and then obtains precise AOI messages based on other AOI protocols.

How should we set the tower distribution?

First, I thought of a simple 2D grid distribution. However, this solution was rejected in less than 20 seconds, because intuition tells me that it is not optimal. Then I tried to find a better method. For example, staggered la S.

      __    __    __     /  /__/  /__/  /     /__/  /__/  /__/     /  /__/  /__/  /     /__/  /__/  /__/

After the painting, my colleague said, isn't this the cellular network used in mobile communication?

Yes, it is easy to prove that this is the optimal distribution scheme. Because each object only needs to be monitored by three observation towers, rather than four of the 2D rectangular mesh solutions. The area covered by the hexagonal circle (repeated area) is smaller than that of the square.

In implementation, we can generate multi-level cellular networks to meet different application layer requirements.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.