doc/kishna.tex
changeset 352 bbc30317fa6a
parent 350 4f90d2c2d221
child 355 0fafdf0029c0
equal deleted inserted replaced
351:7e6d373d8c98 352:bbc30317fa6a
   113 All global game constants are defined in \textit{src/Config.hh}, and may be
   113 All global game constants are defined in \textit{src/Config.hh}, and may be
   114 experimented with. Weapon parameters are defined in \textit{src/Weapons.cc}.
   114 experimented with. Weapon parameters are defined in \textit{src/Weapons.cc}.
   115 
   115 
   116 \section{Program architecture}
   116 \section{Program architecture}
   117 The program consists of four main parts: Graphics\&Input, GameState,
   117 The program consists of four main parts: Graphics\&Input, GameState,
   118 Network and Physics. Each part contains various classes the relations
   118 Network and Physics. Each part contains various classes; the relations
   119 show up in the doxygen generated documentation of the program.
   119 show up in the doxygen generated documentation of the program.
   120 
   120 
   121 The program starts from Application class and it then starts Engine
   121 The program starts from the Application class, which then starts the Engine,
   122 which creates GameState, Graphics and different network related
   122 which creates GameState, Graphics and the Network Client/Server. Physics
   123 things. Physics simulation is started when GameState is created.
   123 simulation is started when GameState is created.
   124 
   124 
   125 GameState contains PhysicsWorld which inherits from Terrain and
   125 GameState contains PhysicsWorld which inherits from Terrain and
   126 contains a list of PhysicsObjects. GameState also contains Player and
   126 contains a list of PhysicsObjects. GameState also contains Player and
   127 Projectile objects which inherit from PhysicsObject (and are contained
   127 Projectile objects which inherit from PhysicsObject (and are contained
   128 in PhysicsWorld).
   128 in PhysicsWorld).
   130 Player objects have a list of Weapon objects which they can use to
   130 Player objects have a list of Weapon objects which they can use to
   131 create Projectiles. Every Player also has a Rope object, which is a
   131 create Projectiles. Every Player also has a Rope object, which is a
   132 separate PhysicsObject, and is either folded away, being thrown or
   132 separate PhysicsObject, and is either folded away, being thrown or
   133 attached to the terrain.
   133 attached to the terrain.
   134 
   134 
   135 Graphics and input are handled in their own classes. Graphics has an
   135 Graphics and Input are handled in their own classes. Graphics has an
   136 Input object which contains InputHandler objects for various classes
   136 Input object which contains InputHandler objects for various classes
   137 of input. One such object is PlayerInput which affects the GameState's
   137 of input. One such object is PlayerInput which affects the GameState's
   138 LocalPlayer. Other object is GuiInput which just modifies what the GUI
   138 LocalPlayer. Other object is GuiInput which just modifies what the GUI
   139 look like on the client side.
   139 look like on the client side.
   140 
   140 
   141 The network code is a bit complicated and has several layers. There
   141 The network code is a bit complicated and has several layers. There
   142 are some nice diagrams about the program structure in the doxygen
   142 are some nice diagrams about the program structure in the doxygen
   143 documentation.
   143 documentation.
   144 
   144 
   145 \section{Data structures and algorithms}
   145 \section{Data structures and algorithms}
   146 
       
   147 
   146 
   148 \subsection{Basic data structures}
   147 \subsection{Basic data structures}
   149 
   148 
   150 \begin{itemize}
   149 \begin{itemize}
   151 \item Vector
   150 \item Vector
   245 \end{align*}
   244 \end{align*}
   246 The next value $(y_n+1)$ is determined by the present value $(y_n)$,
   245 The next value $(y_n+1)$ is determined by the present value $(y_n)$,
   247 the product of the interval $(h)$ and an estimated slope that is
   246 the product of the interval $(h)$ and an estimated slope that is
   248 defined as $\frac{1}{6}h\left(k_1+2k_2+2k_3+k_4\right)$.
   247 defined as $\frac{1}{6}h\left(k_1+2k_2+2k_3+k_4\right)$.
   249 
   248 
   250 % TODO: something network related?
   249 \subsection{Input}
       
   250 
       
   251 All input is represented as a bitmask, composed of bits from \textsl{enum PlayerInputBits}. Additionally, the Graphics
       
   252 code uses some local-only flags defined in \textsl{enum GuiInputBits}. These bitmasks are built using the
       
   253 \textsl{InputHandler} class, which is defined as a generic template. On every update, it goes through its keymap,
       
   254 which is defined as an array of InputKeymapEntry structs. These contain the input bit, flags, and up to two keycodes.
       
   255 The InputHandler then reads keycodes from the keyboard and sets bits in the current input mask based on the entry
       
   256 keycodes (which may be negative to indicate the the specified key must NOT be pressed down) and any key-repetition
       
   257 rules defined by flags.
       
   258 
       
   259 Key repetition is implemented using InputKeyRepeatQueue, which contains a list of InputKeyRepeatEntry's. To rate-limit
       
   260 keypresses, the input code is push()'d to the queue, and it eventually removed from the queue once it expires, or
       
   261 the key is released.
       
   262 
       
   263 The Graphics code then reads the input mask from time to time, resetting the InputHandler's mask to zero, and passes 
       
   264 it on to LocalPlayer, which then either handles it locally, or sends it to the remote server.
       
   265 
       
   266 Since some inputs like walking, aiming and moving up and down the rope are time-dependant, the InputHandler also tracks
       
   267 how many milliseconds the input mask has been held, and this time delta is applied by LocalPlayer.
       
   268 
       
   269 \subsection{Network}
       
   270 
       
   271 The network code is implemented as separate NetworkServer and NetworkClient modules, which use a common high-level
       
   272 network interface, NetworkSession and NetworkObject.
       
   273 
       
   274 The low-level details are implemented using ClanLib's CL\_IPAddress (referred to as NetworkAddress) and CL\_Socket.
       
   275 NetworkUDP provides an interface to send and receive NetworkPackets to/from specific NetworkAddress's across a 
       
   276 NetworkSocket. NetworkTCP provides a NetworkTCPTransport interface, which can send/receive NetworkPackets on a
       
   277 NetworkSocket (using NetworkBuffer to buffer socket I/O). NetworkTCPServer is a listen() socket which accepts client
       
   278 connections as NetworkTCPTransports, and NetworkTCPClient is a NetworkTCPTransport that's connect()'d to some address.
       
   279 
       
   280 NetworkSession encapsulates some simple application server/client behaviour, it can function as both a server, and
       
   281 represents remote NetworkSessions (either clients or servers) as NetworkNode objects. These then provide an interface
       
   282 to send and receive NetworkPackets on specific NetworkChannelDs, using either TCP or UDP as a reliable/unreliable
       
   283 transport.
       
   284 
       
   285 NetworkObject then implements a kind of object-oriented network protocol. A NetworkObjectController (with specific
       
   286 subclasses for server/client behaviour) uses a NetworkSession to send messages on a specific NetworkChannelID. This
       
   287 controller then creates and looks up NetworkObjects (again, with specific subclasses for server/client behaviour).
       
   288 Clients and servers can then communicate by having the server construct new NetworkObjects (which are allocated an
       
   289 unique id), and then sending NetworkPackets with a specific NetworkMessageID type on a specific object. The message is
       
   290 then delivered directly to the NetworkObject instance on the remote end of the connection, or a new NetworkObject is
       
   291 constructed using the data in the NetworkPacket. This enables an easy way to send events for specific objects, and
       
   292 referr to other objects in these messages.
       
   293 
       
   294 NetworkServer then implements a core NetworkServer class which has a NetworkSession and a
       
   295 NetworkObject\_ServerController. Players that connect are represented as NetworkServerPlayers, which inherit from
       
   296 LocalPlayer and NetworkObject\_Server. This class then overrides methods in Player to deliver messages on the Player
       
   297 object to the clients, or to create new NetworkServerProjectiles. NetworkServerProjectile inherits from Projectile and
       
   298 NetworkObject\_Server, and sends messages when constructed, upon hitting a player, and upon being destroyed.
       
   299 
       
   300 NetworkClient is a bit more complicated as it must handle both the LocalPlayer, and a number of RemotePlayers. Again,
       
   301 NetworkClient has a NetworkSession and a specialized NetworkClientController, which then creates objects of various
       
   302 other NetworkClientClasses upon receiving messages from the server.
       
   303 
       
   304 Two of these classes are NetworkClientLocalPlayer and NetworkClientRemotePlayer. Both inherit from
       
   305 NetworkClientPlayerBase, which inherits Player (virtually) and NetworkObject\_Client. NetworkClientLocalPlayer and
       
   306 NetworkClientRemotePlayer then also inherit LocalPlayer and Remote player virtually, respectively.
       
   307 NetworkClientPlayerBase, contains the common methods that update the Player's state in response to messages received
       
   308 from the server. NetworkClientLocalPlayer overrides handleInput to send the input mask to the server, and
       
   309 NetworkClientRemotePlayer can handle remote clients disconnecting from the server.
       
   310 
       
   311 In addition, there is a NetworkClientProjectile class, which inherits from Projectile and NetworkObject\_Client.
       
   312 this is created when a Player fires a Weapon on the server, and handles events received from the server like the
       
   313 projectile hitting a player (inflicting damage), or being destroyed (by hitting the terrain or something similar).
       
   314 
       
   315 When the player first connects to the server, the server sends a large packet containing the terrain array to the
       
   316 client, which updates its own GameState world's terrain array with the received data.
       
   317 
       
   318 Currently, the client only sends handleInput using unreliable UDP messages, and the server only sends position updates
       
   319 (as sent in response to handleInput events) unreliably. All other events are sent using reliable TCP.
   251 
   320 
   252 \section{Known bugs}
   321 \section{Known bugs}
   253 \begin{enumerate}
   322 \begin{enumerate}
   254 \item If player dies while rope is attached the rope will still be
   323 \item If player dies while rope is attached the rope will still be
   255   attached when the player spawns.
   324     attached when the player spawns.
   256 \item If rope is thrown without releasing it first, rope will pull worm
   325 \item If rope is thrown without releasing it first, rope will pull worm
   257   when midair
   326   when midair
   258 \item Collisions with the terrain are only tested for the edgepoints
   327 \item Collisions with the terrain are only tested for the edgepoints
   259   of the polygon.
   328     of the polygon.
       
   329 \item Existing Player ropes and Projectiles are not sent to the client when it connects, which can cause apparent
       
   330     glitches in what the terrain looks like and how players move.
   260 \end{enumerate}
   331 \end{enumerate}
   261 
   332 
   262 \section{Tasks sharing and schedule}
   333 \section{Tasks sharing and schedule}
   263 We could have followed the schedule a lot better. Now we basically
   334 We could have followed the schedule a lot better. We basically forgot the whole
   264 forgot the whole schedule and did things always when we had some spare
   335 schedule and had a lapse in activity during the middle weeks, which caused us
   265 time. And still we were late of the schedule. The good thing was that
   336 to be delayed in terms of the schedule. The positive side was that we almost
   266 almost always all team members were doing things at the same time and
   337 always had all the team members working on their own things in parralel and
   267 communicating, either we were at the same place or everyone was on
   338 communicating together; either at Maari or using our IRC channel.
   268 IRC.
       
   269 
   339 
   270 Tasks sharing worked pretty much as planned. Tero did all the network
   340 Tasks sharing worked pretty much as planned. Tero did all the network
   271 code and everyone else did everything that had something to do with
   341 code and worked on keeping the rest of the code network-safe. Most of our
   272 physics and graphics. Most of our eye candy is done by Marko who was
   342 eye-candy (like terrain textures) was done by Marko, who was responsible for
   273 the responsible person for graphics. Marko, Eric and Atle made
   343 the graphics. Marko, Eric and Atle worked on everything Physics related plus
   274 basically everything physics related. Most of the time every team
   344 the GameState/Player/Rope/etc code. Most of the time all team members were
   275 member was working together so most of the code has been written as is
   345 working together, so the code was written using common agreement.
   276 as a result of a common agreement.
   346 
   277 
   347 We feel that the workload was shared reasonably evenly. % Or does someone disagree with this?
   278 We feel that the workload was shared quite even. % Or does someone disagree with this?
       
   279 
   348 
   280 \section{Differences to the original plan}
   349 \section{Differences to the original plan}
   281 The original plan was quite loose and it let us make decisions during
   350 The original plan was quite loose and it let us make decisions during
   282 development, which was a good thing. The basic structure of the
   351 development, which was a good thing. The basic structure of the program is
   283 program is pretty much as the one we thought about while
   352 pretty much as the one we thought about while planning, although the Network
   284 planning. Though, many parts of the game have many levels of
   353 code ended up being a fair bit more simple-minded due to lack of time to
   285 abstraction (of course).
   354 implement more UDP-based behaviour.
   286 
   355 
   287 % References
   356 % References
   288 \begin{thebibliography}{99}
   357 \begin{thebibliography}{99}
   289 \bibitem{gaffer} Gaffer on games. Game
   358 \bibitem{gaffer} Gaffer on games. Game
   290   Physics. 2006. http://gafferongames.wordpress.com/game-physics/
   359   Physics. 2006. http://gafferongames.wordpress.com/game-physics/