Movement eventually causes desync
If I do continuous movement, I eventually get desync'd somewhere between 60 and 600s. If I pause movement (1 sec here or there) or slow my speed a bit, it helps, but doesn't solve the problem. When comparing with packet dump of the flash client, my speed calculations are correct so I'm not sure what is causing my desync.
I setup a test cycle of moving in a pre-set pattern in the Nexus on 1.0 speed tiles to rule out other factors. I can stay connected indefinitely without movement, so it's definitely newtick/move related. I've tried calculating partial locations and filling in the location records to be as realistic as possible, but generally have better results without it.
Any ideas?
Code:
else if (packet.Type == PacketType.NEWTICK)
{
NewTickPacket nt = (NewTickPacket)packet;
PlayerData.Parse(nt);
m_lastTickId = nt.TickId;
foreach (var status in nt.Statuses)
{
if (Entities.ContainsKey(status.ObjectId))
{
Entities[status.ObjectId].Parse(status);
}
}
DateTime thisTick = DateTime.Now;
int deltaTick = nt.TickTime;
// Calculate our new position if we're moving
float speed = (4f + 5.6f * ((float)(PlayerData.Speed + PlayerData.SpeedBonus) / 75f));
var tile = Tiles[(int)PlayerData.Pos.X, (int)PlayerData.Pos.Y];
if (tile != null)
{
var t = Serializer.Tiles[tile.Type];
if (t != null)
{
speed *= t.Speed;
}
}
MovePacket mp = (MovePacket)Packet.Create(PacketType.MOVE);
CalculateMovement(deltaTick, speed);
mp.TickId = m_lastTickId;
mp.Time = (int)(thisTick - m_startTime).TotalMilliseconds;
mp.NewPosition = (Location)PlayerData.Pos.Clone();
mp.Records = new LocationRecord[0];
Send(mp);
m_lastTick = DateTime.Now;
}
private void CalculateMovement(int elapsed_, float speed_)
{
bool there = true;
if (PlayerData.Destination != null)
{
float diffX = PlayerData.Destination.X - PlayerData.Pos.X;
float diffY = PlayerData.Destination.Y - PlayerData.Pos.Y;
float tiles = speed_ * (elapsed_ / 1000f);
if (Math.Abs(diffX) > tiles * 0.707f && Math.Abs(diffY) > tiles * 0.707f)
{
// Moving in two directions
tiles *= 0.707f;
}
if (Math.Abs(diffX) < tiles)
{
// We're close enough to just move there.
PlayerData.Pos.X = PlayerData.Destination.X;
}
else
{
there = false;
if (diffX > 0f)
{
PlayerData.Pos.X += tiles;
}
else if (diffX < 0f)
{
PlayerData.Pos.X -= tiles;
}
}
if (Math.Abs(diffY) < tiles)
{
// We're close enough to just move there.
PlayerData.Pos.Y = PlayerData.Destination.Y;
}
else
{
there = false;
if (diffY > 0f)
{
PlayerData.Pos.Y += tiles;
}
else if (diffY < 0f)
{
PlayerData.Pos.Y -= tiles;
}
}
}
if (PlayerData.Destination != null && there)
{
//Log.Write("Reached destination.");
PlayerData.Destination = null;
}
}