Hello!
I have a task, to make an ARPG game work on multiplayer at work. Unfortunately the game was developed without considering the networking problems, so I'm in a bit hard situation. Please help me :(
As I said, the game is an ARPG, similar to diablo, there are a lot of moving units at the same time, who are finding paths for themselves, colliding with each other, and attacking the player, or each other.
The units communicate with the control with commands. Control can be AI or player input.
So, when the player clicks on an enemy, a command structure is created, holding the target unit ID, or the position/direction where the spell will be casted.
Looks like something like this:
struct SBattleCommand
{
ECommandType m_eType; // the type of the current command
DWORD m_dwUnitID; // the ID of the unit, who is performing this command
DWORD m_dwTargetID; // the target ID, may be invalid
D3DXVECTOR2 m_vTargetPosition;
D3DXVECTOR2 m_vTargetOrient;
};
Similar thing happens, when the AI decides to attack the player/cast a spell somewhere or on something.
Then the Unit receives this command, stores it, and executes in time.
The pathfinding works in a little tricky way( because there are many units ), it refreshes on a random timer( not really random, has a seed generated from it's ID, what decides when to update the path ). The path finding only looks for a certain depth in one tick, so the whole path may not be found in the frame the command is added.
Also, the units are trying to avoid each other when finding a path, also, if something happens, and they collide, they push each other out.
So this is it, this is what I have to synchronize between the server and up to 10 players( usually max 4, but there are game modes which can be played with 10 players ).
My approach was this:
When the player inputs a command, it is immediately executes, and when the server receives it, it broadcasts to everyone else.
The AI only runs on the server side, when it assigns a command to the unit, it is broadcasted to everyone. The commands are sent with reliable_unsequenced flag, meaning that it is guaranteed that it will arrive, but can arrive out of order, and I handle if one of the packets are too late, it will be dropped.
The path finding is done on every client side, because the target position, and the source position is known, and it would be a lot of data, synchronizing.
Also, when receiving a command on the client side, the program checks if there is too big difference between the current position of the unit, and the position what is sent with the command, and interpolates if neccessary.
The problem with this is that when there are a lot of units moving in the same direction( e.g. trying to attack the player ), they will collide with each other, and because the positions are not pin-point accurate, the pathfinding may give back different path. Like trying to get around of a group from left, when it's doing it from the right on the server side. Thus, it desynces easily, and the constant position lerping is really ugly.
Is my approach correct? Or should I do it in other way? Please help me!
Also, sorry for my English, I'm not native.
Thanks in advance!