Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm creating a multiplayer interface for a game in 2D some of my friends made, and I'm stuck with a huge latency or sync problem.

I started by adapting my game to the msdn xna network tutorial and right now when I join a SystemLink network session (1 host on PC and 1 client on Xbox) I can move two players, everything is ok, but few minutes later the two machines start being totally out of synchronization. When I move one player it takes 10 or 20 seconds (increasing with TIME) to take effect on the second machine.

I've tried to :

Create a thread which calls NetworkSession.Update() continuously as suggested on this forum, didn't worked.

Call the Send() method one frame on 10, and the receive() method at each frame, didn't worked either.

I've cleaned my code, flushed all buffers at each call and switched the host and client but the problem still remain...

I hope you have a solution because I'm running out of ideas...

Thanks

SendPackets() code :

    protected override void SendPackets()
    {
        if ((NetworkSessionState)m_networkSession.SessionState == NetworkSessionState.Playing) //Only while playing
        {
            //Write in the packet manager
            m_packetWriter.Write(m_packetManager.PacketToSend.ToArray(), 0, (int)m_packetManager.PacketToSend.Position);
            m_packetManager.ResetPacket(); //flush

            //Sends the packets to all remote gamers
            foreach (NetworkGamer l_netGamer in m_networkSession.RemoteGamers)
            {
                if (m_packetWriter.Length != 0)
                {
                    FirstLocalNetGamer.SendData(m_packetWriter, SendDataOptions.None, l_netGamer);
                }
                }
            m_packetWriter.Flush();//m
            m_packetWriter.Seek(0, 0);
        }
    }

ReceivePackets() code :

    public override void ReceivePackets()
    {
        base.ReceivePackets();

        if ((NetworkSessionState)m_networkSession.SessionState == NetworkSessionState.Playing) //Only while playing
        {
            if (m_networkSession.LocalGamers.Count > 0) //Verify that there's at least one local gamer
            {
                foreach (LocalNetworkGamer l_localGamer in m_networkSession.LocalGamers)
                { //every LocalNetworkGamer must read to flush their stream
                    // Keep reading while packets are available.
                    NetworkGamer l_oldSender = null;
                    while (l_localGamer.IsDataAvailable)
                    {
                        // Read a single packet, even if we are the host, we must read to clear the queue
                        NetworkGamer l_newSender;
                        l_localGamer.ReceiveData(m_packetReader, out l_newSender);
                        if (l_newSender != l_oldSender)
                        {
                            if ((!l_newSender.IsLocal) && (l_localGamer == FirstLocalNetGamer))
                            {
                                //Parsing PacketReader to MemoryStream

                                m_packetManager.Receive(new MemoryStream(m_packetReader.ReadBytes(m_packetReader.Length)));
                            }
                        }
                        l_oldSender = l_newSender;
                        m_packetReader.BaseStream.Flush();
                        m_packetReader.BaseStream.Seek(0, SeekOrigin.Begin);
                    }
                }
                m_packetManager.ParsePackets();
            }
        }
    }
share|improve this question
    
What FPS is your game running at when this happens? –  ashes999 Dec 27 '12 at 21:41
    
As far as I can tell this code shouldn't work for more than 1 vs 1. It says here (msdn.microsoft.com/en-us/library/bb975947.aspx) that sending the packet clears it. This does however means you can simplify the code a little to remove the (probably) superfluous flush and seek to zero –  Martin Dec 27 '12 at 23:27
add comment

1 Answer

I have a few suggestions :

  • Shouldn't you handle network updates on every frame ?
  • What's your status of GameTime.IsRunningSlowly ?
  • Did you try to profile your application ?

Here are some links for you :

The Indiefreaks Game Profiler for Xna is here! this one might be of interest

What Are Some Good .NET Profilers?

Plus, on Visual Studio you have Menu Analyze -> Launch Performance Wizard

share|improve this answer
2  
you definitely don't want to send network updates every frame. That's a fantastic way to overload router buffers and introduce massive latency. –  Martin Dec 27 '12 at 23:19
    
+1 : Yes you're certainly right. What would you do then, every N frames or something ? –  Aybe Dec 28 '12 at 20:50
    
@Martin While you don't want to send network updates every frame you should call Update() on your session every frame in XNA to keep your session in sync. –  dadoo Games Feb 25 '13 at 21:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.