Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / Hard Challenge: Can anyone suggest a decent design???? Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
Chris Allport

February 11, 2005, 09:33 AM

I am developing a multiplayer game with a UDP interface and am having difficulty coming up with a good design for my classes so they are adequately decoupled.

Here is a description:
- I need to communicate with numerous other systems.
- Each connection is to either:
+ A single player
+ Another system which manages multiple players
- Each connection resides on a different port.
- Each connection has a single client (for receiving data)
- Each connection has a single server (for sending data)
- Each player has unique information that must be used throughout the game.
- There can be zero or more players per connection.
- The player information is not purely a database (although maybe it could be). It has some internal logic that must be applied to it upon receipt. This logic is applied based on the individual configuration of each player.
- A connection may receive a special message that requires it to "handshake" and add a new player.

This seems like a logical class composition:
Class Connection {
Class UDP_Client
Class UDP_Server
List Class Player_Database
}

However, this composition poses numerous problems.
- The Player_Database is essentially the unpacked messages received by the UDP_Client. PROBLEMS: UDP_Client must pass data UP to Connection who must determine if Player_ID is in Player_Datase list; if so, pass data into Player_Database.

- Game must query the different states of the player. PROBLEM: Accessing data directly. There are just TOO many fields to provide accessors for each. I could provide accessors to each of the message types. Then the application is not flexible if the message format changes.

- When a message is received, it affects the game. The rest of the game must be notified of receipt. (Receipt of this data has been decoupled using the Observer pattern.) PROBLEM: see previous

- Depending on internal settings (on a per player record), the Player_Database may need to send a message acknowledgement. PROBLEM: Player_Database must call UDP_Server.


The suggested class composition forms a logical grouping, however, the data flows do not work out. Any suggestions would be GREATLY appreciated.

 
Victor Widell

February 11, 2005, 07:20 PM

Don't use a new port for each player. It's a nightmare for players behind a NAT router.

 
Chris Allport

February 11, 2005, 08:50 PM

That part of the architecture is fixed and cannot be changed. Besides, although I have used the analogy of a video game, this is not exactly an application that will be used behind a router/firewall.

 
I'M BRIAN FELLOWS

February 11, 2005, 11:25 PM

OF COURSE IT CAN BE CHANGED, JUST CHANGE IT.

 
juhnu

February 12, 2005, 07:40 AM

"am developing a multiplayer game with a UDP interface and am having difficulty coming up with a good design for my classes so they are adequately decoupled.
"

"Besides, although I have used the analogy of a video game"


First you say you developing a multiplayer game and suddenly is just an analogy??

anyway.. I'm interesting in what were the reasons you have chosen udp-transport over tcp/ip?




juhani


 
philh

February 14, 2005, 03:11 AM

Shouldn't UDP_Client & UDP_Server be child classes of the parent Connection class ? Then Connection contains the Player_Database as a protected attribute (so it can be accessed by child classes), and the UDP_Client & UDP_Server classes extend the Connection class with the appropriate methods.

Also, any particular reason for choosing UDP ? IIRC UDP doesn't give any guarantee that a message will be correctly sent between two points - this could be a problem if servers don't receive messages from clients and therefore don't change player information.

As for the message format issue "There are just TOO many fields to provide accessors for each. I could provide accessors to each of the message types. Then the application is not flexible if the message format changes." - I would think that this suggests the message format is too complex and perhaps could be decomposed into a set of smaller message types/classes ?

It's a little hard to envisage exactly what you want this game to do - perhaps a couple of examples of game interaction might be useful to give a better idea of how you think the classes should interact ?

 
Chris Allport

February 14, 2005, 12:24 PM

Thanks for your well thought out response. I have actually converged on a very different implementation after some discussion with colleagues.

To explain the aforementioned problem better, I am not actually implementing a game. A multiplayer game is merely an analogy to my project - a control station for a number of robots.

You offered a couple of helpful suggestions, however, I am implementing a standard, not creating the messages and deciding on protocols. The messages ARE incredibly complex, but they cannot be simplified or refactored. They were, however, designed to be a general solution, not a specific "player state" solution.

As for UDP vs. TCP, you are again correct. UDP was selected for a number of reasons. Initially, TCP was completely ruled out, however, there is now a provision that it may be used in the future.

Again, thank you for taking the time to try and understand.

 
Sp0rtyt

February 14, 2005, 02:33 PM

I don't think he even knows what he is talking about. He's just rambling about abstract interfaces, he hasn't even written a line of real code yet.

 
ddn2

February 27, 2005, 10:42 PM

Here's what I usually do.

Don't try to design the system from the bottom up, trying to build the system first by building the primitives. In this case you'll be better served from doing this top down.

define the tiers:

a)applicaiton level ( flow of control, player management, game logic )
b)protocol level ( seralzaition of data packets, post/pre processing of data )
c)hardware level ( sending of data itself, routing, compression )

now we can define the primitves, keeping in mind your overall design ( which I won't critique, I'm of the philosophy that you just have to try it and see )

a) Application level objects might include..

struct PlayerID{
unsigned int m_uid; //unique player ID assigned by a factory object, guarentee unique across the network..
};

you might want to define overloaded operators for equality for the PlayerID.

struct PlayerObject{
//player states enumeraton
enum EnumPlayerStates{
ePlayerConnecting,
ePlayerConnected,
ePlayerInLobby,
....
};

PlayerID m_playerId; //players unique id
EnumPlayerStates m_playerState;//players current state
ConnectionHandle m_connection; //handle to connectin (usually resolves to socket or socket wrapper object..
...other stuff which your application will need
};

This gives u an idea of what you'll need at the applciaiton level. This is just a few objects, you'll need to implement controller, managers, etc... to get them to do something useful.

You'll need to define the enumerations which is used to control the state and flow of the clients through the system as well. Something like a protocol struct like so..

struct Protocol{
enum EnumProtocolMsgsToClient{
ePasswordChallenge,
...
};

enum EnumProtocolMsgsToServer{
eJoinRequest,
ePasswordReply,
...
};

bool mFromClient;
EnumProtocolMsgsToClient mForClient;
EnumProtocolMsgsToServer mForServer;
.... generic data objects which condtionally apply depending upon the enum..
}

I'll just briefly describe what you'll need for the other layers.

B) Protocol Level

manages the connection objects, transform the raw packets into data ready for transmission and reverse, responsible for passing errors to applciation level for example failure to decode a packet, send decoded packets to application level.. etc

Note the connection obejcts will have their own states, like how the player has states as well..

C) Hardware Level

send data to approriate destinations through the proper socket, if nessecary can peform generic compression at this level, also responsble for sending errors to protocol level if there is a socket failure etc..

Like a cyclic pattern, all levels will have to manage their objects state, hardware level included..

It's like some sort of cake.

Good Luck!

-ddn



 
This thread contains 9 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.