Hi all,
I’m trying to develop a MMO type game in unity, it is part of a larger game, but to make it as simple as possible I have just created a level that involves a floor and 2 cubes to make sure I really understand the problem.
Player controls the main cube, cube sends X + Z coordinates to a background C# socket server (VS2008).
A second cube will request for the first cube’s coordinates via the C# socket server and translate accordingly, (cube1.X +2 and cube1.Z + 2), this way the cube will always be diagonally left of the main cube.
There’s no problems whatsoever when playing from localhost(>1ms), but the moment I try to induce lag (200ms) by sleeping the server or trying to connect to it over the WAN it stutters and framerates drop to very low levels to the point it is a slideshow (4.5fps)
It seems to be waiting for the tcp reply from the server before it continues in execution, is it a thread issue?
Perhaps its a simple solution, perplexed…
Thanks!
No, not a thread issue, but an error in your code as you likely wrote it to force wait until there is a response / data from server instead of checking if there is data (a full packet of information at least), if there is then read and handle and then continue, if there isn’t just skip read and continue
Hi dreamora,
Thanks for your reply, maybe you could help see my code and see if there’s the symptoms you mentioned?
MainControl.js
function Update()
{
playerPosX = playerChar.position.x;
playerPosZ = playerChar.position.z;
TCP.talk("001;" + playerChar.position.x +";" + playerChar.position.z +";");
}
TCP.cs
public string talk(string theLine) {
NetworkStream clientStream = client.GetStream();
byte[] buffer = encoder.GetBytes(theLine);
bytesRead = 0;
clientStream.Write(buffer, 0, buffer.Length);
try
{
if (clientStream.CanRead == true)
{
bytesRead = clientStream.Read(message, 0, 4096);
}
}
catch (Exception e)
{
Console.WriteLine(e);
//a socket error has occured
}
return encoder.GetString(message, 0, bytesRead);
}
Hi,
First of all, we don’t have a very good experience with NetworkStream / TcpClient with Unity since it skip some packet due to internal buffer cleanup when there is new data. I suggest to you to use directly Sockets instead far better for a MMO.
Second thing, you might not send directly data from Unity Thread since it will drop your framerate. Create a packet class and put your packets into a list who will be sent by another thread.
For reading same thing, create a thread who will read network data, so if there is a blocking read call your game wouldn’t be affected. Be aware that you can’t directly call game code like transforms etc directly into another thread, for our MMO we create anonymous delegates who content the game code into a list and a class named GameMgr execute them synchronously after.
like that :
public delegate void NetworkCallback();
public List<NetworkCallback> cbList;
public void ExecuteSync(NetworkCallback cb)
{
cbList.Add(cb);
}
public void DoCallbacks()
{
lock(cbList)
{
foreach(NetworkCallback cb in cbList)
cb.Invoke();
cbList.Clear();
}
}
with that you can for example do into your network code who is located into another thread
void mytransformpackethandler())
{
... do stuff
ExecuteSync(() => { transform.position .... }); // This would be executed later in unity thread
}
you just have to call DoCallbacks() somewhere into Unity Thread (like in a Update() on a gameobject
it’s a little bit hard to understand but with that you may have a perfectly smooth MMO.
Sry for bad english, i’m french.
ghos,
If you find that you are having trouble working with your custom solution you should consider using a 3rd party option like ElectroServer. It is thread friendly. The data is read without impacting frame rate, and then events are dispatched to the single Unity thread that your code is running in.