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/ |