T
TomLaVachette
Guest
Hello,
I've been trying to fix a synchronization problem with my multiplayer characters for more than a week.
The time between sending the movement information and processing the information for all clients is so high that the character teleports back with each movement, which is very embarrassing.
I started looking for the culprit, assuming in the first place that my server in C# was taking too long to process the information received and then send it back to everyone. Unfortunately, after a few tests, the server does not take more than 2000 ticks (0.2 ms) to do its job.
Then I thought to myself that the TCP protocol was not adapted, and that it was too long (a little surprising for just two packets, but nvm...). I created a GMS2 light project for movements with the same C# server. As a result, the movements are impeccable.
By elimination, only the client remains. I discovered the amazing profiling tool that allows me to know the execution time. Unfortunately, the execution time is very low, and should not cause such significant desynchronizations.
The way the movements work is as follows: at each change of direction, I send the x and y coordinates to the server as well as the direction (in int). The server sends this information to all players on the map. In short, for a movement, there are only 2 TCP packets: the first to start the movement, the second to stop it.
oClient - Async Networking
oCharacter - Step
I don't have any other ideas about my problem, so I hope you'll have something to suggest to me. ^^''
Thanks.
I've been trying to fix a synchronization problem with my multiplayer characters for more than a week.
The time between sending the movement information and processing the information for all clients is so high that the character teleports back with each movement, which is very embarrassing.
I started looking for the culprit, assuming in the first place that my server in C# was taking too long to process the information received and then send it back to everyone. Unfortunately, after a few tests, the server does not take more than 2000 ticks (0.2 ms) to do its job.
Then I thought to myself that the TCP protocol was not adapted, and that it was too long (a little surprising for just two packets, but nvm...). I created a GMS2 light project for movements with the same C# server. As a result, the movements are impeccable.
By elimination, only the client remains. I discovered the amazing profiling tool that allows me to know the execution time. Unfortunately, the execution time is very low, and should not cause such significant desynchronizations.
The way the movements work is as follows: at each change of direction, I send the x and y coordinates to the server as well as the direction (in int). The server sends this information to all players on the map. In short, for a movement, there are only 2 TCP packets: the first to start the movement, the second to stop it.
oClient - Async Networking
Code:
var read_buffer = ds_map_find_value(async_load, "buffer");
var constant = buffer_read(read_buffer, buffer_u16);
switch (constant)
{
// Player Movement Message
case 3002:
{
var tempUID = buffer_read(read_buffer, buffer_u32);
var dir = buffer_read(read_buffer, buffer_u32);
var tempX = buffer_read(read_buffer, buffer_u32);
var tempY = buffer_read(read_buffer, buffer_u32);
oCharacter.dir = dir;
oCharacter.x = tempX;
oCharacter.y = tempY;
break;
}
.........
oCharacter - Step
Code:
if (!animInProgress)
{
if (dir == 1 && !place_meeting(x, y - walkSpeed, oCollision))
{
y -= walkSpeed;
}
else if (dir == 2 && !place_meeting(x, y + walkSpeed, oCollision))
{
y += walkSpeed;
}
else if (dir == 3 && !place_meeting(x + walkSpeed, y, oCollision))
{
x += walkSpeed;
}
else if (dir == 4 && !place_meeting(x - walkSpeed, y, oCollision))
{
x -= walkSpeed;
}
else if (dir == 5)
{
animInProgress = true;
oldSprite = sprite_index;
image_speed = walkSpeed / 1.5;
image_index = 0;
sprite_index = spriteAnim;
}
//Animation
if (dir != 5 && dir != olderDir)
{
image_speed = walkSpeed / 3;
switch (dir)
{
case 0: inMovement = false; image_speed = 0; image_index = 0; break;
case 1: inMovement = true; sprite_index = SMAdvTop; spriteAnim = SMAdvTopSword; break;
case 2: inMovement = true; sprite_index = SMAdvBottom; spriteAnim = SMAdvBottomSword; break;
case 3: inMovement = true; sprite_index = SMAdvRight; spriteAnim = SMAdvRightSword; break;
case 4: inMovement = true; sprite_index = SMAdvLeft; spriteAnim = SMAdvLeftSword; break;
}
}
}
olderDir = dir;
I don't have any other ideas about my problem, so I hope you'll have something to suggest to me. ^^''
Thanks.