User interface design ideas: during the main select(3) loop, we will query at least 1 socket: the listen(2) socket which accepts new connections. When the a new connect comes in, we will use accept(2) to get a new socket, then check to see if we will have violated any limits (user limits for example) and either drop the connection after we tell them to fuck off, _OR_ if we can accept them at this time, we create a new OnlineUser object and initialize it with the first userinterface object. Basically OnlineUser just contains state information for online users (tech stuff, mostly socket and so forth info). It doesn't do anything "useful" in the sense of game play. All the "hard" work is done by "helper classes". Here is an class idea: class UIHandler { public: virtual UIHandler() = 0; virtual ~UIHandler() = 0; }; as you can see its a purely virtual class, obvious only used for subclassing and for providing a common pointer type to these classes. The basic idea: OnlineUser maintains a stack of 'UIHander' objects (ok, pointers to allocated objects), the top item is handling the User interface currently. The idea being that the menu system in FT2002 is essentially a hierarchal system. So a stack system would represent this fairly well: Basically the current UIHandler would use a callback of some sort (perhaps another virtual class... similar to the interface idea in Java) and would request for the OnlineUser to do certain stuff. Like push a new handler onto the stack. or pop the current handler off. in which case the next top-most UIHander object would start handling the user interface/input and request for the OnlineUser to send data. So the UIHandler would be very abstract, you could add another section to the game by modifying an existing UIHandler and add a new UIHandler subclass which would handle the new part of the game. So basically you need several capabilities in a UIHander: the capability to handle user key events, and the capability to send data. The ability to handle user key events could be encapsulated into the following virtual function: void handle_key( char ) = 0; Basically OnlineUser would call 'handle_key()' for each incoming keystroke (or byte of data, whatever...) then the UIHandler object could react however they want. We could define the following class: class OutputProxy { public: virtual OutputProxy() = 0; virtual ~OutputProxy() = 0; virtual void OutputChar( char ) = 0; virtual void OutputStr( char * ) = 0; }; The OutputChar and OutputStr would be non-blocking. All calls should be non-blocking, because if you are blocking, you could be sitting in the select(3) loop servicing other calls. The idea is: no blocking... *EVER*. all commands that might block should use callbacks in possible or use a different way of doing things. Of course we would also want callback functions to push and pop UIHander classes onto the stack. We could extend the OutputProxy and name it something else: class UIProxy { public: virtual UIProxy() = 0; virtual ~UIProxy() = 0; virtual void OutputChar ( char ) = 0; virtual void OutputStr ( char * ) = 0; virtual void pushUI( UIHander * ) = 0; virtual void popUI ( void ) = 0; }; the assumption being with pushUI() that UIHander has be properly initalized, constructed and is ready to start reciving 'handle_key()' events. the assumption being with popUI is that the top UIHander is ready to be destroyed, and has nothing more to say. we can further give an example of usage: class OnlineUser : public UIProxy { /* blah */ }; so the OnlineUser class impliments the 'UIProxy' handlers. further we can construct the first/new UIHandler objects as follows: class Pilot : public UIHandler { /* class definitions here */ }; Pilot p = new Pilot( this, /* other params */ ); so the Pilot class will store the info as such: class Pilot : public UIHander { private: UIProxy *parent; }; And can ask it's parent to do stuff for it. -- There will be some data that needs to be stored persistant... ie: which user does the OnlineUser represent, and so forth. It doesn't make sense to store that data with each UIHander object. So with the callback we can include some data fields that will be handy. According to the paradigm of the game, a user exists in a ship. the ship exists in a sector. the ship can also be on a planet. So we have several options here. First is in the User object is a field which points to a ship number (all things are numbered. so each ship has a number associated with it) the ship furthermore has some information on its location. Now since a ship can be on a planet and in a citidal, what do we do? well, obviously we need more data fields. so perhaps in a ship type: class Ship { private: uint16 sector; uint16 planet; // == 0 if not on a planet }; this might be the best. obviously the planet must have a citdel. but that can be programmed into the game engine. So in class User { private: uint16 ship; }; anyways. you get the point. -- Further to the discussion on the callback interface and data... Basically we need to store several things for quick manipulation: a pointer to the User class. a pointer to the Sector class. a pointer to the Ship class. that way we have quick access to any of the necessary classes without doing a lookup, at an expense of 4 * 3 bytes per online user. worth it forsure. so we can redefine the call back class to: class UIProxy { public: virtual UIProxy() = 0; virtual ~UIProxy() = 0; virtual void OutputChar ( char ) = 0; virtual void OutputStr ( char * ) = 0; virtual void pushUI( UIHander * ) = 0; virtual void popUI ( void ) = 0; // data goes here Universe *u; User *user; Sector *sec; Ship *ship; };