Multiplayer for my simple game

Started by
11 comments, last by Cultura2H 16 years, 9 months ago
Ive managed to set up a basic two player multiplayer for my game but its very laggy so I think I need new approach. Its in c# and uses System.Net.Sockets for the net stuff, host uses TcpListener and client uses TcpClient. My game is still very basic and consists of each player having a tank which can rotate, move forward/back and shoot. At the moment both players use a StreamReader and StreamWriter to send each other move data every frame (SteamReader.ReadLine, StreamWriter.WriteLine). I figure to get smooth gameplay I want around 20 fps but im only getting about 6-10. Is it possible to get that kind of speed with this simple method or will I have to use another?
Advertisement
I don't see how you get such a low framerate. Using the sockets and stream reader / writer should have virtually no impact on speed.

Everything is better with Metal.

Using .NET you want to use asynchronous sockets with callbacks. And yes. Use the binaryWriter and binaryReader objects. Much easier on bandwidth :)

http://msdn2.microsoft.com/en-us/library/system.io.binarywriter.aspx
http://msdn2.microsoft.com/en-us/library/system.io.binaryreader.aspx

Have fun :) Also if you want further reading material as to how to use those objects here:
http://gpwiki.org/index.php/Binary_Packet
since you already have the objects it will help you to understand how they work I guess :/ Also it shows how to organize data.

However, your game shouldn't lag even with strings. How did you setup your server/client system.

clients send input like, I want to move forward, I want to turn left or right kind of stuff. Then you have the I want to fire command. Then the server on it's next game loop processes the input and applies it the next game tick and sends the data and velocities to the players.

Remember you should be simulating the stuff on the client like interpolating the tank movement given the server data. When your on the client and click forward or whatever the client shouldn't just be moving the tank. It should tell the server to move the tank then when it gets the info of the position and velocity it will apply those. (Applying the position when it's off by a certain amount). Both players will see the tanks move at the same time.

Is this a P2P system? If so make sure both the clients are using time modeled gameplay and sending updated to each other at a precise increment.

This might just be a simple interpolation problem though where your only updating the position and not the velocity.
Make sure to set myTcpClient.NoDelay = true;
Thanks for the replies

Im getting the message that it should be fast and im doing it wrong :)
Heres the exact code I use to setup my host and client:

if (bHost)            {                TcpListener tcpListener = new TcpListener(1234);                                tcpListener.Start();                  //Accepts a new connection...                Socket socketForClient = tcpListener.AcceptSocket();                socketForClient.NoDelay = true;                networkStream = new NetworkStream(socketForClient);                                netReader = new StreamReader(networkStream);                netWriter = new StreamWriter(networkStream);            }            else            {                Console.WriteLine("enter IP addr / host name");                string hostName = Console.ReadLine();                TcpClient myclient;                                try                {                    myclient = new TcpClient(hostName, 1234);                }                catch (Exception e)                {                    Console.WriteLine(e.Message);                    Console.WriteLine("Failed to connect to server at {0}:1234", hostName);                    while (Console.ReadKey().Key != ConsoleKey.Enter) ;                    return false;                }                myclient.NoDelay = true;                //get a Network stream from the server                networkStream = myclient.GetStream();                netReader = new StreamReader(networkStream);                netWriter = new StreamWriter(networkStream);            }            return true;


Each frame I use the following to read data:
line = netReader.ReadLine();netReader.DiscardBufferedData();

and to write data:
 netWriter.WriteLine(netMessage);netWriter.Flush();


Anything obviously wrong there?
Are you setting NoDelay to TRUE on the client, too?
enum Bool { True, False, FileNotFound };
yes
Is one or the other application stealing all the cpu? (use Thread.Sleep(0) in your app loops). Are you calculating your fps correctly?
I dont actually calculate the fps its just unplayably slow when its multiplayer. It's fast when I connect 2 of them together both on my pc.
You should take the listening and receiving part and put it in it's own function.

Then, at the start up program, multi-thread that function asynchronously so that it won't cause any lag to your actual CLIENT speed.

I recommend the pthread library, but it's for C++ and not C#, but both are damn similar so it shouldn't be much of a problem.

Example:

#include "pthread.h"int threadThis(){    //Do stuff    return 1;}int main(int argc, char* argv){    pthread_t tid;    pthread_create (&(tid), NULL, threadThis, NULL);    pthread_detach(tid);    while(1)    {        //Do stuff    }    return 0;}

This topic is closed to new replies.

Advertisement