diff options
Diffstat (limited to 'libkdegames/kgame/DESIGN')
-rw-r--r-- | libkdegames/kgame/DESIGN | 407 |
1 files changed, 0 insertions, 407 deletions
diff --git a/libkdegames/kgame/DESIGN b/libkdegames/kgame/DESIGN deleted file mode 100644 index cd737e3a..00000000 --- a/libkdegames/kgame/DESIGN +++ /dev/null @@ -1,407 +0,0 @@ -This document tries to describe the design of KGame - the KDE multiplayer -library. -This document has been written by: - Andreas Beckermann <[email protected]> - M. Heni <[email protected]> - Burkhard Lehner <[email protected]> - -This document is published under the terms of the GNU FDL - -!!! -Note that this is the initial version of this document and has not yet been -aproved by all core developers (and is far from being complete) -AB: please remove this comments as soon as all KGame hackers have read the -document -!!! - -Please refer the API documentation of every KGame class if you want up tp date -information. - - -0. Contents ------------ - -1. DEFINITIONS -1.1 Message Server -1.2 Client or Message Client -1.3 Master -1.4 Admin -1.5 Server -1.6 Player - -2. Game Negotiation (M.Heni 20.05.2001) - -AB: 3.x is obsolete! -3. Game Properties (Andreas Beckermann 28.07.2001) ( not yet completed ) -3.1 Using KGameProperty -3.2 Custom Classes -3.3 Concepts - -4. KGameIO (Andreas Beckermann 10.08.2001) - -5. Debugging (Andreas Beckermann 06.10.2001) TODO! -5.1 KGameDebugDialog -5.1.1 Debug KGame -5.1.3 Debug Messages - ---------------------------------------------------------------------- -1. DEFINITIONS --------------- - -First we have to clear some words. The main expressions used in KGame which -need a definition are - -1.1 Message Server -1.2 Client or Message Client -1.3 Master -1.4 Admin -1.5 Server -1.6 Player - -The most important and confusing ones are Master, Admin and Server. We make -quite big differerences between those inside KGame. - -1.1 Message Server: -------------------- -A game has always exactly one object of this class, for local games as well as -for network games. For network games, this object can be on one of the users -processes (usually inside KGame), or it can also be on an independant computer, -that has no idea about what game is played on it. - -A KMessageClient object can connect to it. It's main purpose is transmitting -messages between KMessageClient objects. - -The Message Server is the main communication object. It is represented by the -class KMessageServer. Note that there is also a "Master" and a "Server" which -both differ heavily from the Message Server! - -1.2 Client, Message Client: ---------------------------- -Each process that wants to take part in the game must have a -KMessageClient object, that is connected to the Message Server. KGame creates -this object and connects it to the Messager Server, so that you usually don't -need to create these of your own. Even in a local game (no network) there -must be a message server and one message client connected to it. This is usually -done by the KGame object itself. - -Each message client has a unique ID number (a positive integer value, not zero). -The KMessageClient object, which does the communication with the Message Server -is called "Message Client" and to simplify the use we call any KGame object (or -even the game process) that is connected to a game (i.e. even the Master) just -"Client". - -The main purpose of a Client is to connect to a Master (i.e. to a game) and to -communicate with it. A client has always a KGame object. - -1.3 Master: ------------ -The process that contains the Message Server is called "Master". In any local -game this is the game process. The Message Server is started by KGame using -KGame::setMaster(true) which is automatically done on startup. The Message -Server is deleted automatically as soon as you connect to another Master. -So in most cases there is exactly one KGame object / Client which is Master. But -in one case there can be no KGame object / Client that is Master - if the -Message Server is started as an own process. This "Message-Server-only" process -is called "Master" then, although there is no KGame object which is Master. See -also the definition of Admin! - -1.4 Admin: ----------- -One (and only one) of the Clients is the Admin. He can configure the Message -Server and the game in general in several ways. He can limit the maximum number -of connected message clients and can drop the connection to some other clients, -as well as he can configure game specific ssettings (like max/min players, start -money, ...). The Admin also initializes newly connected Clients. If the Admin -himself disconnects, another Client becomes Admin (The Admin can himself elect -some other Client to become Admin. He himself loses that Admin status then). -An Admin is *alway* a KGame object. The Admin is usually the same as the Master, -but if the Master is an own process (i.e. the Message Server has been started -outside KGame) then Master and Admin differ. An Admin *must* be a KGame object -while the Master doesn't have to be. - -1.5 Server: ------------ -The definition of Server differs quite much from the definition of Master. -A Master just accepts connections and forwards messages. The Server on the other -side checks these messages, calculates results and sends the results to the -Clients. That means the Server does all game calculations and doesn't directly -forward the messages from one Clients to all other Clients. -KGamer makes it possible to write multiplayer games even without a Server. All -Clients just send their moves to the Master which forwards them to all Clients. -Now all Clients calculate the result. -E.g. in a poker game a player selects two of five cards to be exchanges and -clicks on "draw" then the client sends the message "Exchange Card-1 and Card-2" -to the Master. A no-Server solution forwards this to all Clients, and these -Clients exchange the cards of the player. Note that in a no-Server solution -(you can also see it as a "every-Client-is-a-Server solution") all Clients must -have the same random seed and must be of the same version, i.e. the result must -be the same on all Clients. -In a Server-Solution on the other hand the Master forwards the Message -("Exchange Card-1 and Card-2") to the Server only. This Server now calculates -the result, and sends the new cards back to the Client. -Both concepts have advantages and disadvantages. It is on you - the game -developer - to decide which way is better for you. -E.g. the Server-Solution makes it easier for you to write games. The version -must not necessarily be the same, you have one central computer which does the -calcultations. The No-Server-Solution on the other hand decreases network -traffik as the Clients just send their moves and all Clients can calculate the -reactions. I'm sure there are a lot of advantages/disadvantages more for both -concepts. - -1.6 Player: ------------ -A KPlayer object is always connected to a KGame object and represents a -player that participates the game. In a network game, every KPlayer object is -duplicated on every other KGame object connected to the message server with -virtual KPlayer objects. So at every time in the game, every KGame object has -the same number of KPlayer objects. - - -2. Game negotiation -------------------- -Upon connection of a client the admin and the client try to negotiate -the game setup. Basically this means the game of the admin is transferred -(saved) on the client. However, the client's players are added to the game -as far as possible. If the addition of the client's players would add more -players than allowed some players are inactivated. Which players are -inactivated depends on their networkPriority(). This procedure allows -easy replacement of players in a constant number game (e.g. chess). If -this feature is of no interest simply keep the priorities equal (all 0) -and the client will only add only players if the number of players is -less or equal the maximum player number. - -The following is the negotiation procedure as started by the connection -of a client. It is initiated in the negotiateNetworkGame() virtual function -of KGame: - -admin: client: ------------- ------------ -IdSetupGame - QINT16 Library - Version - QINT32 Application - cookie - IdSetupGameContinue; - QValueList<int> player id's - QValueList<int> network priority's - -IdGameLoad - all game data - -IdGameReactivate - QValueList<int> id's - -IdSyncRandom - int randomseed - - -3. Game Properties ------------------- -A very hard task in a network game is consistency. You have to achieve that all -properties of the game and of all players have the same value on all clients -every time. This is because -a) the user might be confused if he sees "Player has $0" on client A but -"Player has $10" on client B and -b) Often game handling depends on those values, e.g. if the example above -happens the computer might quit the game for the Player on client A because -he/she doesn't have enough money. But the game continues on client B. -Another not that easy task is the network protocol itself. You have to write -several send() and receive() functions which apply changed values of properties -to the local property. - -KGameProperty is designed to do all of this for you. KGameProperty is -implemented as a template so you can use it theoretically for every type of data -- even for your self defined classes. - - -3.1 Using KGameProperty ------------------------ -It is basically very easy to use a KGameProperty. You first create your own -class containing the property, e.g: -class MyGame : public KGame -{ -[...] -protected: - KGamePropertyInt money; - KGamePropertyQString name; - KGameProperty<AntotherClass> myProperty; -}; -KGamePropertyInt is just a typedef for KGameProperty<int> - just like -KGamePropertyQString. Now you need to register the properties in the constructor -of the class to the KGamePropertyHandler: -MyGame::MyGame() : KGame(myCookie) -{ - money.registerData(KGamePropertyBase::IdUser+1, dataHandler(), "Money"); - name.registerData(KGamePropertyBase::IdUser+2, this, "Name"); - myProperty.registerData(KGamePropertyBase::IdUser+3, dataHandler(), "MyProperty"); -} --> You need to specify a *unique* ID. This ID must be greater than -KGamePropertyBase::IdUser. IDs below this are reserved for KGame. Probably this -will be changed so that you cannot use IDs below IdUser in the future. Then you -have to specify the dataHandler(). You can also use a KGame or KPlayer pointer. -This will automatically use KGame::dataHandler() or KPlayer::dataHandler(). -Finally you *can* provide a name for the property. This will be used for -debugging in KGameDebugDialog. If you want to save some memory you can leave -this out. -Note that if you use pointers to create the properties dynamically they are -*not* deleted automatically! You MUST delete them yourself! -Now you can use the KGameProperty like every variable else. See also Section -"3.3 Concepts" for restrictions in use. - -3.2 Custom Classes ------------------- -To make custom classes possible you have to implement several operators for your -them: you need at least << and >> for QDataStream as well as "==" for your own -class. To overload the "<<" you would e.g. do something like this: -QDataStream& operator<<(QDataStream& stream, MyData& data) -{ - int type = data.type; - QString name = data.name; - stream << type << name; - return stream; -} -So you basically just have to split your class to several basic types and stream -them. - -3.3 Concepts ------------- -You can use KGameProperty basically in two completely different ways. You can -also use a mixture of both but this is not recommended. The default behaviour -and therefore also the recommended is the "clean" way: -a) Always Consistent. This means that a KGameProperty has always the same value -on *every* client. This is achieved by using KGameProperty::send() whenever you -want to change the value using "=". You can still use changeValue() or -setLocal() but send() will be the default. If you use send() then the value of -the property does *NOT* change immediately. It is just sent to the -KMessageServer which forwards the value to all clients. As soon as the new value -is received from the message server the KGamePropertyHandler (a collection class -for KGameProperty) calls KGameProperty::load() and changes the value of the -property. So the game first has to go into the event loop, where the message is -received. This means to you that you cannot do this: -myIntProperty = 10; -int value = myIntProperty; -As myIntPoperty still has the old value when "value = myIntProperty" is called. -This might seem to be quite complex, but -KGamePropertyHandler::signalPropertyChanged() is emitted whenever a new value is -assigned so you can connect to this and work immediately with the new value. -You gain the certainty that the value is the same on every client every time. -That will safe you a lot of time debugging! -Another way is the "dirty" way: -b) Not Always Consistent. Sometimes you really *want* to do something like -myIntProperty = 10; -int value = myIntProperty; -but this is not possible with the default behaviour. If you call -KGameProperty::setAlwaysConsistent(false) in the constructor (right after -registerData()) you get another behaviour. "=" means changeValue() now. -changeValue() also uses send() to change the value but additionally calls -setLocal() to create a local copy of the property. This copy now has the value -you supplied with "=" and is deleted again as soon as any value from the network -is received. - -4. KGameIO ----------- -The class KGameIO is used to let the players communicate with the server. You -can plug as many KGameIO objects into a player as you want, e.g. you can plug a -KGameMouseIO and a KGameKeyIO into a player so that you can control the player -with the mouse and the keyboard - e.g. in a breakout game. -You can probably see the advantage: as most of the control stuff is common in a -lot of games you can use the same IO class in many different games with very -small adjustments. -You could also put all the IO stuff directly into your KPlayer object, like -sendBet(int money) for a poker game. But there is a major disadvantage and I'm -very sure you don't want to use a KPlayer object for your IO stuff as soon as -you know which disadvantage: -KGameIO is designed to be able to switch between different IOs "on the fly". So -you might have a KGamePlayerIO, derived from KGameIO, for your game. But now -this player (who "owns"/uses the KGamePlayerIO) leaves the game (e.g. because he -was a remote player). So now the game would be over for every player as one -player is now out of order. But with KGameIO you can just let any of the -remaining clients create a KGameComputerIO and plug this into the player. So the -player now is controlled by the computer and the game can continue. - -Think about it! You don't have to care about removing players when a player -leaves as you can just replace it! The same works the other way round: imagine a -game with 10 player (e.g. 5 human and 5 computer players) that has already -started. You cannot add any further players without restarting. So if there are -any additional player you can just call KPlayer::removeGameIO() which removes -the IO of a computer player and then call KPlayer::addGameIO() for the same -player which adds a GameIO for new human player. That's all! - -To achieve this you just have to make sure that you make *all* of your IO -operations through a KGameIO! So instead of using MyPlayer::sendBet(int money) -you should use something like MyIO::sendBet(). The amount of money would -probably be calculated by the game IO itself. - - - -5. Debugging ------------- -The general debugging concept (if there is one at all) or general debugging -hints are not yet written. Feel free to do so - -5.1 KGameDebugDialog --------------------- -A nice way of debugging a KGame based game is the KGameDebugDialog. Basically -all you have to do is to add something like "Debug" to your game's menu and add -a slot like -slotDebug() -{ - KGameDebugDialog* dialog = new KGameDebugDialog(mGame, this); - connect(dialog, SIGNAL(finished()), dialog, SLOT(slotDelayedDestruct())); - dialog->show(); -} -that's it. -You can now click on that menu entry and you get a non-modal dialog where you -can start to debug :-) -The dialog consist of several pages. You can easily add your own using -KDialogBase::addVBoxPage() (for example). - -5.1.1 Debug KGame ------------------ -The first page, "Debug KGame" shows on the left most or even all status values of -KGame. That contains e.g. minPlayers(), isAdmin(), gametqStatus(), ... -The right side is probably the more important one. It lists *all* KGameProperties -which have been inserted to this KGame object (only to this KGame object - not -the ones that have been added to the players!). Most of the status variables of -the left side are here again as they are implemented as KGameProperty. You can -see the name of the property (together with its ID), its value and the policy -this property uses. Note that "unknwon" will be displayed as name of the -property if you haven't supplied one. See KGamePropertyBase::registerData() for -info. You probably always want to supply a name for the property to debug it -easily. In the future there will be something like -KGamePropertyHandler::setDebug() so that you can switch off debugging and save -the memory of the names in a release version. -For as long as you use standard types for your properties (int, long, bool, -...) you should always be able to see the value of the property. If you just see -"unknown" then this type has not been implemented. You can connect to the signal -KGamePropertyHandler::signalRequestValue() and supply a QString with the value -yourself. If you do so for a standard type please also submit a bug report! - -Currently the dialog does *not* update automatically! So you alway have to click -the "update" button when you want a current value. There are several reasons for -this (and one of them is that i'm too lazy to implement the update ;)). E.g. -often (very often) a property is just in the background - stores e.g. the -available money in a game. But you don't want it to update whenever the value -changes (a player receives/pays money) but only when the value on the screen -changes. - -5.1.2 Debug Players -------------------- -This page consists of three widgets. On the very left there is a list of all -players in the game. Only the IDs are displayed to save space. If you click one -the other widgets are filled with content. These widgets are quite much the same -as the ones in "Debug KGame" - the left shows the value of the functions and the -right one displays all KProperties of a player. Not much to say here - except: -See "Debug KGame". - -If you change to another player the value are also updated. - -5.1.3 Debug Messages --------------------- -This page is probably not as important as the other ones. It displays *every* -message that is sent through the KGame object. As a KGameProperry also send -messages you probably get a lot of them... -You can exclude message IDs from being displayed (e.g. all game properties). -You can also change the sorting of the list to see all messages of a certain ID. -The default is to sort by time (which is displayed on the left side). - |