Server - client question
David Sopala

Ok so to make a game run smoothly there needs to be latency right? As in the server waits two ticks to actually do command x or something is this the right way of thinking about it?

Also what is the best way to make characters "see" each other without sending the position of everyone on the server? It would seem that running a function to generate a list of people to tell a specific person hey these people are nearby would be costly in terms of time right and since you can't be gauranteed that say X can see Y and Z you can't say Y can see Z since they might be out of range of each other.

I am thinking a smaller server 255 or less people could be done with allocating a byte for each player like a quick update, but this structure won't work with larger amounts of people. What advice can you all give me to make a server that won't lagg horribly with just a couple people logged in and make for a good gameplay?

What I have right now is a server that will accept incoming connections and allow players to create and login. Working on coding shoot and pushing bullets/projectiles to a stack.

The server is written as follows I realize it may not be perfect and inefficent in some places:

Server.h

#SelectExpand
1#ifndef SERVER_H 2#define SERVER_H 3 4#include "mysocket.h" 5#include "serverdatatypes.h" 6#include "string" 7 8using namespace std; 9 10 11class Server 12{ 13 public: 14 Server(); 15 Server(int MAX_CON); 16 Server(int MAX_CON,int COMMAND_BUFFER); //Max number of connections the server will handle before rejecting incoming 17 //connections and how many commands it will buffer before sending CMD_FAIL back to the client 18 void Initalize(short); //Calls mysocket::startupand starts listening on a socket for incoming connections. 19 bool Push_Command(My_Command *str); 20 My_Command* Get_Command(); //Shall return a string containing a command or NULL if there are no commands to execute. 21 void Die(); //Sends signal to start killing threads and closing connections 22 bool Dead(); //Are all connections closed, threads terminated, and ready to release memory? 23 //STRING BASED SENDING 24 void SendToAll(string); //Sends to everyone on the server announcements and update data. 25 bool SendToPlayer(int, string); //Sends to a certain player. Returns true for sent false for error. 26 void SendToList(int,int *,string); //Sends to a list only can be a group or a zone. 27 //CHAR * BASED SENDING - UPDATE PACKETS ETC 28 void c_SendToAll(char *); //Sends to everyone on the server announcements and update data. 29 bool c_SendToPlayer(int, char *); //Sends to a certain player. Returns true for sent false for error. 30 void c_SendToList(int,int *,char *); //Sends to a list only can be a group or a zone. 31 ~Server(); 32 static void Check_Connections(void *); //Checks connections for data pushes commands onto the stack to be executed later. 33 static void Listen(void *); 34 35 private: 36 short Port; 37 bool TimeToDie; 38 bool oktodie[2]; 39 int MAX_CONNECTIONS; 40 int MAX_COMMANDS; 41 mysocket Listener; 42 mysocket** Connections; 43 My_Command** Command_List; 44 int* CONNECT_TIMES; 45 46}; 47#endif

Server.cpp

#SelectExpand
1#include "server.h" 2#include "serverdatatypes.h" 3#include <iostream> 4#include <winsock2.h> 5#include <windows.h> 6#include <process.h> 7#include <time.h> 8 9 10 11using namespace std; 12 Server::Server() 13{ 14 MAX_CONNECTIONS = 50; 15 MAX_COMMANDS = 250; 16 Connections = new mysocket*[MAX_CONNECTIONS]; 17 Command_List = new My_Command*[MAX_COMMANDS]; 18 CONNECT_TIMES = new int[MAX_CONNECTIONS]; 19 for(int f = 0; f < MAX_CONNECTIONS; f++) 20 { 21 Connections[f] = NULL; 22 } 23 for(int ff = 0;ff < MAX_COMMANDS;ff++) 24 { 25 Command_List[ff] = NULL; 26 } 27 cout<<"Server created with "<<MAX_CONNECTIONS<<" connections and "<<MAX_COMMANDS<<" commands"<<endl<<endl; 28} 29 30 31 Server::Server(int MAX_CON) 32{ 33 MAX_CONNECTIONS = MAX_CON; 34 MAX_COMMANDS = MAX_CON*5; 35 Connections = new mysocket*[MAX_CONNECTIONS]; 36 Command_List = new My_Command*[MAX_CONNECTIONS*5]; 37 CONNECT_TIMES = new int[MAX_CONNECTIONS]; 38 for(int f = 0; f < MAX_CONNECTIONS; f++) 39 { 40 Connections[f] = NULL; 41 } 42 for(int ff = 0;ff < MAX_COMMANDS;ff++) 43 { 44 Command_List[ff] = NULL; 45 } 46 cout<<"Server created with "<<MAX_CONNECTIONS<<" connections and "<<MAX_COMMANDS<<" commands"<<endl<<endl; 47} 48 49//Max number of connections the server will handle before rejecting incoming 50//connections and how many commands it will buffer before sending CMD_FAIL back to the client 51 Server::Server(int MAX_CON,int COMMAND_BUFFER) 52{ 53 MAX_CONNECTIONS = MAX_CON; 54 MAX_COMMANDS = COMMAND_BUFFER; 55 Connections = new mysocket*[MAX_CONNECTIONS]; 56 Command_List = new My_Command*[MAX_COMMANDS]; 57 CONNECT_TIMES = new int[MAX_CONNECTIONS]; 58 for(int f = 0; f < MAX_CONNECTIONS; f++) 59 { 60 Connections[f] = NULL; 61 } 62 for(int ff = 0;ff < MAX_COMMANDS;ff++) 63 { 64 Command_List[ff] = NULL; 65 } 66 cout<<"Server created with "<<MAX_CONNECTIONS<<" connections and "<<MAX_COMMANDS<<" commands"<<endl<<endl; 67} 68 69void Server::Initalize(short PORT) //Calls mysocket::startup() and starts listening on a socket for incoming connections. 70{ 71 Port = PORT; 72 Listener.Startup(); 73 _beginthread(Listen,0,(void *)this); 74 _beginthread(Check_Connections,0,(void *)this); 75} 76 77void Server::Listen(void *ptr) 78{ 79 Server *this_class = (Server*)ptr; 80 this_class->TimeToDie = false; 81 this_class->oktodie[0] = false; 82 this_class->oktodie[1] = false; 83 this_class->Listener.Listen(this_class->Port); //Start listening on listener socket on Port. 84 cout<<"Now listening for incoming connections on port: "<<this_class->Port<<endl; 85 while(!this_class->TimeToDie) 86 { 87 if(this_class->Listener.HasData()) 88 { 89 for(int z = 0;z < this_class->MAX_CONNECTIONS;z++) 90 { 91 if(this_class->Connections[z] == NULL) 92 { 93 cout<<"Accepting new connection on identifier: "<<z<<endl; 94 this_class->Connections[z] = new mysocket(this_class->Listener.Accept()); 95 this_class->CONNECT_TIMES[z] = clock(); 96 break; 97 } 98 } 99 } 100 } 101 this_class->oktodie[0] = true; 102 _endthread(); 103} 104 105void Server::Check_Connections(void *ptr) //Checks connections for data pushes commands onto the stack to be executed later. 106{ 107 Server *this_class = (Server*)ptr; 108 this_class->TimeToDie = false; 109 this_class->oktodie[1] = false; 110 while(!this_class->TimeToDie) 111 { 112 for(int z = 0;z < this_class->MAX_CONNECTIONS;z++) 113 { 114 if(this_class->Connections[z] && clock() - this_class->CONNECT_TIMES[z] >= 600000) 115 { 116 delete this_class->Connections[z]; 117 this_class->Connections[z] = 0; 118 cout<<"Dropping connection on socket "<<z<<" due to inactivity."<<endl; 119 } 120 if(this_class->Connections[z] && this_class->Connections[z]->HasData()) 121 { 122 My_Command *Pushable_Command; 123 Pushable_Command = new My_Command; 124 Pushable_Command->identifier = z; 125 char *data = this_class->Connections[z]->Recv(); 126 Pushable_Command->Command = data; 127 if(data && (strcmp(data,"DISCONNECT") != 0)) 128 { 129 do{} 130 while(!this_class->Push_Command(Pushable_Command)); 131 } 132 else {delete this_class->Connections[z];this_class->Connections[z] = 0;} //If we get nothing back from a read something is probably wrong cull that connection. 133 } 134 } 135 } 136 this_class->oktodie[1] = true; 137 _endthread(); 138} 139bool Server::Push_Command(My_Command *cmd) 140{ 141 for(int z = 0;z < MAX_COMMANDS;z++) 142 { 143 if(Command_List[z] == NULL) 144 { 145 Command_List[z] = cmd; 146 Command_List[z]->LOCKED = false; 147 148 return true; //Queued up successfully 149 } 150 } 151 return false; //Failed to queue up command queue is full. 152} 153 154My_Command* Server::Get_Command() //Shall return a string containing a command or NULL if there are no commands to execute. 155{ 156 for(int z = 0;z < MAX_COMMANDS;z++) 157 { 158 if(Command_List[z] != NULL && !Command_List[z]->LOCKED) 159 { 160 Command_List[z]->LOCKED = true; 161 My_Command *thecommand; 162 thecommand = new My_Command; 163 thecommand->identifier = Command_List[z]->identifier; 164 thecommand->Command = new char[strlen(Command_List[z]->Command)+1]; 165 strcpy(thecommand->Command,Command_List[z]->Command); 166 delete Command_List[z]; 167 Command_List[z] = NULL; 168 return thecommand; 169 } 170 } 171 return NULL; 172} 173bool Server::Dead() 174{ 175 if(oktodie[0] == true && oktodie[1] == true) 176 return true; 177 else return false; 178} 179void Server::Die() 180{ 181 TimeToDie = true; 182} 183void Server::SendToAll(string data) //Sends to everyone on the server announcements and update data. 184{ 185 for(int x=0;x<MAX_CONNECTIONS;x++) 186 { 187 if(Connections[x])Connections[x]->Send(data.c_str()); 188 } 189} 190bool Server::SendToPlayer(int x,string data) //Sends to a certain player. Returns true for sent false for error. 191{ 192 if(Connections[x])return Connections[x]->Send(data.c_str()); 193 else return false; 194} 195void Server::SendToList(int y,int *x,string data) //Sends to a list only can be a group or a zone. 196{ 197 for(int z=0;z<y;z++) 198 { 199 if(Connections[x[z]])Connections[x[z]]->Send(data.c_str()); 200 } 201} 202 203void Server::c_SendToAll(char *data) //Sends to everyone on the server announcements and update data. 204{ 205 for(int x=0;x<MAX_CONNECTIONS;x++) 206 { 207 if(Connections[x])Connections[x]->Send(data); 208 } 209} 210bool Server::c_SendToPlayer(int x, char *data) //Sends to a certain player. Returns true for sent false for error. 211{ 212 if(Connections[x])return Connections[x]->Send(data); 213 else return false; 214} 215void Server::c_SendToList(int y,int *x,char *data) //Sends to a list only can be a group or a zone. 216{ 217 for(int z=0;z<y;z++) 218 { 219 if(Connections[x[z]])Connections[x[z]]->Send(data); 220 } 221} 222 223 Server::~Server() 224{ 225 int f; 226 for( f = 0;f < MAX_CONNECTIONS;f++) 227 { 228 delete Connections[f]; 229 }delete[] Connections; 230 for( f = 0;f < MAX_COMMANDS;f++) 231 { 232 delete Command_List[f]; 233 }delete[] Command_List; 234 Listener.Shutdown(); 235}

main.cpp

#SelectExpand
1int main() 2{ 3 4 Test_Server = new Server(MAX_CONNECTIONS_TO_SERVER); 5 Test_Server->Initalize(27115); 6 init(); 7 8 My_Command* testcommand; 9 while(!kbhit()) 10 { 11 do 12 { 13 testcommand = Test_Server->Get_Command(); 14 if(testcommand) 15 { 16 cout<<testcommand->Command<<endl; 17 HandleCommand(testcommand); 18 } 19 } 20 while(testcommand);//run all commands in queue 21 } 22 Test_Server->Die(); 23 while(!Test_Server->Dead()); 24 return 0; 25}

gnolam

Ok so to make a game run smoothly there needs to be latency right? As in the server waits two ticks to actually do command x or something is this the right way of thinking about it?

No. Why would you think that?

verthex

As in the server waits two ticks to actually do command x or something is this the right way of thinking about it?

Your server listens for the client(s) for however many ms you set it.

Quote:

Also what is the best way to make characters "see" each other without sending the position of everyone on the server?

This is possible but only if your simulation is deterministic. You can only take input from your client(s) and send the update from your server with all the positions you changed.

David Sopala

From what I figure- the clients should only send updates when their state changes right? ie 1000xxxx (think up, right, down, left, 4 reserved bits) then lets say they walk up for some amount of time then they stop moving now we get a second packet 0000xxxx and the server stops them moving. Is this a good idea? It seems to have the least amount of traffic in a design that I can think up. The only thing I worry about is the server could potentially get hung up with someone flooding it with commands (repeated presses of a key like up thus sending many update packets) and as you can see from the server design that could cause lagg. Maybe I will need to code a lockout timer 5 commands per 5 seconds or something like that ideas?

verthex

Another thing you might try doing though I'm not sure what the code looks like for it is synchronizing the clients and the server so that the server expects to receive a message from the clients within some time frame. The clients basically have a timer that is in sync with the server and only send a message within a specific timeframe. The idea would work similarly for the server side as well. The gameloop would execute in sync with the client and the server and the updates ( your controls, scores, etc.) would be sent to your clients and the server sometime after the gameloop.

David Sopala

I added a thread to run updates on the players and such; while the other threads if they find nothing will yeild their timeslice to the update thread to make sure things keep going smoothly(so I hope).

Posted before I realized I don't have all the threads posted....

So I have the following threads:

Check for incoming connections - yields there is enough time for it to come back only checking one socket in this case so it is quick doesn't need to check twice.

Check for data on existing connections - does not yield connections could have data any second now....

Pull commands off the stack and execute them - yields with no commands

Update players, NPCs, Monsters, bullets, etc

verthex

I added a thread to run updates on the players and such; while the other threads if they find nothing will yeild their timeslice to the update thread to make sure things keep going smoothly(so I hope).

Does that mean the server is always listening? If not how do you fix missing packets or are you using udp, thats the norm for games.

David Sopala

You have a thread that will always be checking out on the listener. You also have a thread that will always be checking for incoming commands from the clients/players.

TCP actually - The server doesn't "miss" packets although I could put an ACK in there to make sure the client knows the server got the data... The server queues commands up with an identifier and a char* with the command and params.

void Server::Initalize(short PORT)                                         //Calls mysocket::startup() and starts listening on a socket for incoming connections.
  {
      Port = PORT;
      Listener.Startup();
      _beginthread(Listen,0,(void *)this);
      _beginthread(Check_Connections,0,(void *)this);
  }

So I start two threads to handle communications and new connections. Now this main thread goes back to main and basicly goes and grabs commands off a stack the server is pushing commands onto. Now lets say people don't send any commands (Test_Server->Get_Command() == NULL) - there is nothing for my guy here to do so he yields that timeslice to someone who needs it.

while(!kbhit())
    {
        do
        {
            testcommand = Test_Server->Get_Command();
            if(testcommand)
            {
                HandleCommand(testcommand);
            }
            else SwitchToThread();
        }
        while(testcommand);
    }

It also does this while listening on incoming connections for a performance boost I hope.

#SelectExpand
1void Server::Listen(void *ptr) 2{ 3 Server *this_class = (Server*)ptr; 4 this_class->TimeToDie = false; 5 this_class->oktodie[0] = false; 6 this_class->oktodie[1] = false; 7 this_class->Listener.Listen(this_class->Port); //Start listening on listener socket on Port. 8 cout<<"Now listening for incoming connections on port: "<<this_class->Port<<endl; 9 while(!this_class->TimeToDie) 10 { 11 if(this_class->Listener.HasData()) 12 { 13 for(int z = 0;z < this_class->MAX_CONNECTIONS;z++) 14 { 15 if(this_class->Connections[z] == NULL) 16 { 17 cout<<"Accepting new connection on identifier: "<<z<<endl; 18 this_class->Connections[z] = new mysocket(this_class->Listener.Accept()); 19 this_class->CONNECT_TIMES[z] = clock(); 20 break; 21 } 22 } 23 }else SwitchToThread(); 24 } 25 this_class->oktodie[0] = true; 26 _endthread(); 27}

and if you want to see how I handle commands:

#SelectExpand
1void HandleCommand(My_Command* cmd) 2{ 3 char *str = new char[strlen(cmd->Command)+1]; 4 strcpy(str,cmd->Command); 5 char * pch; 6 pch = strtok (str,"_"); 7 for(int x = 0;x < NUM_SERVER_FUNCTIONS;x++) 8 { 9 if(pch && strcmp(pch,Functions[x]->Command)==0) 10 { 11 (*Functions[x]->Funct)(cmd); 12 } 13 } 14 delete[] str; 15 delete cmd; 16}

james_lohr

Ok so to make a game run smoothly there needs to be latency right? As in the server waits two ticks to actually do command x or something is this the right way of thinking about it?

No. You're not even vaguely on the right track. You haven't even begun to address the real challenge of making a fun and responsive network game which is latency hiding.

Have you even established how you are going to maintain consistent state? This will depend a lot on the type of game you are making. For example, for an FPS you'll want the absolute state to be server-side with each client seeing some predictive subset of the state. For an RTS, on the other hand, a good solution is to use a deterministic lock-step engine.

Once you've established this, you'll then want to work on decoupling game-play from communication as much as possible so that the game flows smoothly despite latency spikes.

Finally comes the hard bit: hiding latency and making the state displayed to the user believable despite the inevitable network latency. This involves interpolation, extrapolation, prediction and reconciliation. Moreover, it requires making the correct game design choices in the first place. You'll see this is all the best online multiplayer games: movement, weapon and gameplay mechanics are chosen to be predictable to within a reasonable degree of accuracy so that reconciliation can be done subtly.

It looks to me that you don't really understand the fundamentals. I suggest spending a lot more time thinking about it and reading articles before jumping into client/server design. There are plenty of good articles about like this one:

http://www.gamasutra.com/view/feature/3227/designing_fastaction_for_the_.php

I would also suggest that you stop dwelling on bandwidth usage. Compared to latency, bandwidth is a non-issue.

David Sopala

Wondered why I kept reading things about 28.8kbps modems... that was written in '97.

But you say I am wrong go read that page yourself technically speaking that is what I had said earlier.

"•Schedule events in the future if you want them to happen simultaneously for all users. "

verthex

For example, for an FPS you'll want the absolute state to be server-side with each client seeing some predictive subset of the state

Does that mean my lagging character might shoot someone even if I'm not really pressing the button?

james_lohr

But you say I am wrong go read that page yourself technically speaking that is what I had said earlier.

No, this is not what you said. If this is what you were trying to say then you've either totally misunderstood it, or you've worded it extremely poorly.

It is referring to individual events. For example, jumping: This can easily be scheduled a short time in the future whilst still feeling responsive by adding a "crouch" period. So, the user hits the "jump" key, he sees his character start crouching and so it feels to him like there is immediate feedback; however, the message then travels off to the server at which point the server (immediately, or as soon as possible given the network latency!) notifies other clients of the players intention to jump. The actual lift-off only occurs a short (say 300ms) later than the original player hit his jump key.

Other players will see the player jump at roughly the same time as the player himself jumps; however, if they look really closely, they might notice that he didn't crouch at all.

This is what it is talking about when it says "scheduling events in the future". A few things to note: if you try to employ this technique alone to hide all latency, then the game will start to feel clumsy. So this is just one "trick" in your toolbox of latency hiding techniques. You can't use it everywhere, and so it should not be a mechanic underlying your entire client/server communication engine, or else you will not have the flexibility to use other techniques.

verthex said:

Does that mean my lagging character might shoot someone even if I'm not really pressing the button?

No. Go away.

GullRaDriel

Haha verthex ^^ I hope you were joking thought :-p

verthex

It is referring to individual events. For example, jumping: This can easily be scheduled a short time in the future whilst still feeling responsive by adding a "crouch" period. So, the user hits the "jump" key, he sees his character start crouching and so it feels to him like there is immediate feedback; however, the message then travels off to the server at which point the server (immediately, or as soon as possible given the network latency!) notifies other clients of the players intention to jump. The actual lift-off only occurs a short (say 300ms) later than the original player hit his jump key.

So you're saying the server gets the user input, processes it for physics, etc, and then sends the command for jump to every client including the user to jump. It would solve packet loss (somewhat keeping events in order) but 300ms is a lot of time.

David Sopala

He is still on the 28.8kbps modem mentioned in his other post... 300ms wasn't all that bad back then...

[EDIT]

I guess by tick he thinks seconds as well. I usually figure a tick to be around 50ms the wait two ticks is indicitive of It will probably be roughly 100ms+-50ms for a response to the client.

james_lohr

Everything that article says about latency is as applicable now as it was when the article was written, because guess what, the speed of light hasn't gotten any faster, and this is what latency ultimately comes down to.

The 300ms example I gave was a specific case where one wishes to guarantee (or at least ensure a high probability) that a particular event will occur at the same time across all clients. ~250 ms is roughly the "worst-case" that any good modern multiplayer game will deal with gracefully, even to this day. As I already said, this is just one technique and is probably not even appropriate for jumping. I just gave this example because I hoped that it would be easy for you to understand as comprehension is evidently not your strong point.

I suggest that you give up now, as you're clearly not even intelligent enough to be capable of discerning good advice from bad. You really haven't got a clue what you are doing, and I don't even know why I'm bothering to post in this thread. I guess it was more out of pity because the primary contributor, other than myself, was verthex who is the #1 bullsh*tter on these forums, and so I felt it my duty give some useful information to counter his "noise".

David Sopala

Then please don't post anymore. Actually go post at cprogramming.com they are all like you over there - quick to think they are gods and that no one else has any right to be doing anything.

verthex

I suggest that you give up now, as you're clearly not even intelligent enough to be capable of discerning good advice from bad. You really haven't got a clue what you are doing, and I don't even know why I'm bothering to post in this thread. I guess it was more out of pity because the primary contributor, other than myself, was verthex who is the #1 bullsh*tter on these forums, and so I felt it my duty give some useful information to counter his "noise".

So you posted a shitty article and now you know something. What experience do you actually have making client server games and if you've never made a FPS please don't reply. Thats what David is trying to make and so am I.

Hows this bullshit when everyones talking about it?

GullRaDriel

David,

Have you already read the Beej's guide ?
It's full of nice example and perhaps it has evolved since the first time you watched it.

On Gamasutra and talking about Network, particularly latency hiding, I loved these articles:
Dead Reckoning: Latency Hiding for Networked Games

Defeating-lag-with-cubic-splines, with these two in addition because they somewhat bring a correction/solution to an error in the article: http://www.gamedev.net/topic/401827-lag-reduction-using-cubic-spline-alias-bezier/ , http://en.wikipedia.org/wiki/Cubic_Hermite_spline

gnolam

Then please don't post anymore.

Translation:

Quote:

Guys, when I ask for help I actually don't want it. Thanks!


I shall respect your wishes!

GullRaDriel

Meh !

;D

Thomas Fjellstrom

I think you're both reaching too high. Start with something simpler. Its pretty much the same as trying to make an MMORPG right out of the gate. You will fail. Probably multiple times.

David Sopala

Please note I did have a working MMORPG with items enemies and such - it was all tile based wasn't very pretty and the classes weren't written well (that does not mean it didn't work - it worked fine). I see no problem making something simple for fun. You all act like I want to make money or plan to make money with this. It is just a hobby nothing more nothing less. I don't know everything, but judging me saying I'm already going to fail before I even really start to play around.

Thomas Fjellstrom

It's just a very common occurrence. A beginner comes along and says "I want to make an MMORPG" or "I want to make a RPG" or "I want to make an FPS", and inevitably, they spend more time fighting with the simple issues like timing and bliting, and give up.

Of course if you go into it not expecting to make the "BEST GAME EVER!", and know you're likely to restart several times, that's ok.

james_lohr

I don't know everything, but judging me saying I'm already going to fail before I even really start to play around.

The trouble is not that I think you're taking on an impossible task nor that you are inherently incapable of succeeding, but rather that you don't seem to have the temperament for it. You came on here asking for advice, but then chose to totally ignore it (and the literature to back it up!) because you took a few of our criticisms personally.

verthex

Thus far I've used this as my server/client interface for irrlicht.

I can create clients, display each client as a cube, and allow each client to exit the system without crashing the server as well as ten other things related to basic services. That took me about two weeks to write.

Its a very easy to use server and I highly recommend it over every other socket oriented library. Its not easy to compile and it took me a few minutes to find the libs for it.

Thomas Fjellstrom

Ah, using a pre-made game engine will certainly make creating a game easier. If creating a game asap is your goal, that is definitely a good option.

David Sopala

[quote]
I suggest that you give up now, as you're clearly not even intelligent enough to be capable of discerning good advice from bad. You really haven't got a clue what you are doing, and I don't even know why I'm bothering to post in this thread.
[/quote]

No, thats not directed at anyone in particular couldn't be could it? So yes I take THAT personally who wouldn't? Go away I told you your input is worthless. You clearly can't remember what you type from day to day time to go find another thread troll.

Arthur Kalliokoski

{"name":"hrzfab.gif","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/5\/3540e6c4f5c1d2cc998e46257e43e30f.gif","w":275,"h":210,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/5\/3540e6c4f5c1d2cc998e46257e43e30f"}hrzfab.gif

james_lohr

So yes I take THAT personally who wouldn't?

I don't deny that I was made a personal attack on you; however, it's still up to you as to whether or not you let it get to you.

Quote:

Go away I told you your input is worthless.

To you perhaps, because you're too blinded by emotion to listen. However other people will read this thread and so I will continue to contribute for their sake.

Quote:

go find another thread troll

I'll take the low-hanging fruit first, thank you. ;)

Edgar Reynaldo

I wouldn't want your condescending derogatory help either. :P

james_lohr

Don't worry Edgar, helping you is well beyond me. :P

Edgar Reynaldo

So your definition of help is :
1) Insult someone and say they don't understand what they're talking about
2) When they try to come up with a solution of their own, make sure they feel stupid about it

I remember the math library thread quite well thank you. You said I didn't understand how floating point values worked, but I understood it quite well. When I proposed a perfectly valid solution, you called it naive.

Just how is it that you actually help anyone here anyway?

With friends like that, who needs enemies?

:P::):P

David Sopala

The trouble is not that I think you're taking on an impossible task nor that you are inherently incapable of succeeding, but rather that you don't seem to have the temperament for it. You came on here asking for advice, but then chose to totally ignore it (and the literature to back it up!) because you took a few of our criticisms personally.

I suggest that you give up now, as you're clearly not even intelligent enough to be capable of discerning good advice from bad. You really haven't got a clue what you are doing, and I don't even know why I'm bothering to post in this thread.

I don't deny that I was made a personal attack on you; however, it's still up to you as to whether or not you let it get to you.

You might make a good politician - you play both sides of the fence equally.

I have read Beej's guide to network programming. I used that and a couple others to write the server side code. I am up to about 30 files of code at the moment - from characters to items to communications code and collision classes. I have tested all the commands on the server doing a loopback through an old MUD client of mine to make sure I get the correct responses from the server. So, yes it isn't so much will it work it is what problems will I have that need tweeking to make it smoother. Keep in mind most games back in the 90's were like warcraft 2 I spent hours playing that back then on KALI and in an AOL chatroom trading IP addresses - also prompted me to upgrade to a 56k modem for like 80 bucks.

james_lohr

So your definition of help is :
1) Insult someone and say they don't understand what they're talking about
2) When they try to come up with a solution of their own, make sure they feel stupid about it

I admit that I was being an unpleasant ass. I also accept your criticism of my behaviour, and I agree that a consequence is that I've not been particularly helpful.

However, what is not acceptable is to start making totally illogical arguments, especially when they fly in the face of accepted literature on the subject. If you do this, then you make yourself an easy target.

If we're all completely honest on what's going on here then it's probably something along these lines:

David has had a good first stab at client-server synchronisation, but is struggling a bit because, if we're honest, it's not an easy problem.

I'd had a bad day, and, partly because I've been working on this problem for the past 2 years and now have my own client-server game working smoothly, and partly because I can be an arrogant prick at times, I was rude in my first post.

David got offended, quite rightly, but then made the error of criticising the information I was providing rather than my attitude. Illustrating a lack of understanding on the subject.

I was offended by this, and so said some unpleasant things.

I think that pretty much sums it up.

I'm completely unapologetic about the information that I have provided, and I still claim that he will fail to make something that is playable over the internet unless he fully understand what those articles are talking about.

However, I do apologise for my condescension, arrogance and unpleasantness.

GullRaDriel

Nice.

axilmar

Obviously, James Lohr was correct, but it is pointless to tell others negative comments. We don't know everything, and, at one point in our lives, we were just as knowledgeable as the OP is.

GullRaDriel

Hell yeah. I remember being hurt as much as David in some of my first answers.

Anyway, a few smash aren't bad if in the end all is under control. That's just the result of burning minds exchanges.

Thread #608369. Printed from Allegro.cc