space defenders - university of...
TRANSCRIPT
Space Defenders An arcade video game built in Python
Adrian Daniel Culea School of Computer Science
University of Manchester
Supervised by Dr. Stephen Pettifer
May 2016
1
Abstract
The aim of this project is to build a 2D arcadelike game from scratch in Python, the goal
being for the project to be as lightweight open source resource wise as possible. The core of
the game, is PyGame [1], a set of Python modules designed for game development, which
was used for tasks such blitting images on the screen or moving the said images. The end
product is a two levels game, the goal of the player being to destroy all the enemy space
ships, picking up buffs or debuffs along the way, encountering intelligent enemies in the
latter level of the game.
The following report will provide an indepth understanding of the technicality of the project,
as well as the reasons this game was built in the first place. The report starts by creating a
context for this work and will continue guiding the reader through the journey of its
implementation. The second part of the document will familiarise the reader with the
development of the game, as well as the alternatives that could have been used and the
approaches undertaken during the development, while the following part of the report will
present the evaluation that has been made during and after the implementation. Finally, the
report concludes with a reflection of the last few months of work and the outcome of the
project.
To sum it up, the report is to be used as a guide on a journey that will answer the following
questions about Space Defenders: ‘Why and how the project was build?’ and ‘What
interesting features the game has and why?’
2
Acknowledgements
I would like to take this opportunity to express my gratitude towards Dr. Steve Pettifer for
guiding me throughout the project as well as helping me understand what parts of the project
needed to be improved so I can achieve what I planned for. What is more, I would like to
thank my family for encouragement and support during my studies. Last but not least, I
would like to express my loving thanks to my girlfriend who was next to me when I was
down and helped get on my feet the best she could.
3
Chapter 1 Context 1.1 Video Games Industry
Seen with skepticism and only as a curiosity 40 years ago, the video games industry has
grown to become one of the most profitable market nowadays. Booming in the early 2000s,
the video game industry became, probably, the leading form of entertainment globally,
leaving behind the music or film industries. Statistics show [2] that game lovers have
switched their interests towards this type of activities in the last three years, now spend less
time watching TV, movies or actually going to the movies.
Activity Watching TV Going to the movies Watching movies at home
Less time spent 39% 40% 47%
Fig. 1
The last few years trend of people spending more and more time playing games, regardless of
the type of system the games are being played on, computer or gaming consoles, such as
PlayStation, Xbox or Wii, was reflected in the increase of revenue of this industry.
Region 2013 2012 2011 2010
Asia Pacific £35.12 bn £31.09 bn £29.90 bn £27.35 bn
Europe £14.30 bn £15.05 bn £15.05 bn £14.55 bn
North America £16.11 bn £14.63 bn £14.63 bn £14.48 bn
Latin America £2.76 bn £3.82 bn £3.82 bn £3.35 bn
Middle East £1.84 bn £1.84 bn £1.40 bn £0.85 bn
4
Total £70.13 bn £66.43 bn £64.8 bn £60.53
Fig. 2 [3]
1.1.1 Arcade Video Games
An arcade video game is a game that runs on a coinoperated entertainment machine installed
in public spaces, such as pubs, restaurants, bars or amusement parks. Despite the fact these
type of machines make the vast majority of gamers think of their childhood, they are,
surprisingly, the part of industry that, between 2010 and 2013 generated the most or almost
the most revenue in countries like Japan [4]. Once part of a niche gaming industry, the
arcade video games have significantly decreased in popularity in the western world, mainly
due to their price and space they take in people’s homes. However, there is a trend at the
moment to recreate some of the major arcade video game names, especially for mobile
phones.
Year Revenue (adjusted to 2012 inflation)
2013 £16.03 bn (total market)
● £5.71 billion (arcade market)
● £3.35 billion (retail market)
● £6.97 billion (online market)
○ £4.49 billion (smartphone)
2012 £15.75 bn (total market)
● £6.00 billion (arcade)
● £3.25 billion (retail)
● £6.50 billion (online)
○ £5.35 billion (mobile)
○ £0.83 billion (PC)
○ £312 million (console)
2011 £16.26 bn (total market)
5
● £6.36 billion (arcade)
● £5.65 billion (retail)
● £4.27 billion (online)
○ £3.18 billion (mobile)
○ £0.83 billion (PC)
○ £261.35 million (console)
2010 £14.92 bn (total market)
● £6.09 billion (arcade)
● £5.82 billion (retail)
● £3.01 billion (online)
○ £1.99 billion (mobile)
○ £0.82 billion (PC)
○ £197 million (console)
Fig. 3
1.1.2 Gaming In Python
Throughout the video game industry history, Python, as a sole programming choice, proved
not to be such popular. For a game to become mainstream, the underlying code needs to be
easy to distribute (and/or embed) and have acceptable performance, and Python is not the top
of the list in either of these categories. However, in today’s game development industry,
Python is highly used in writing game logic or server scripting while being integrated with
other programming languages such as C# for games built with Unity [5] (which dominates
the indie game development market) or C++ (which dominates the AAA game development
market). [6]
Despite lacking the resources to build and model the required graphics a modern game should
have on its own, there are big names in the video game industry written purely in Python
(Stackless Python in fact a variant of Python), and, one of these names is EvE Online.[7]
6
1.2 Aim
The aim of the project is to overcome the downsides that Python has (mentioned above) and
create a game from scratch by only using Python (seasoned with PyGame on the side). There
are many platforms similar to PyGame, such as Pyglet[8] or Pyganim[9] and the choice of
using PyGame came from a personal analysis, which will be presented further in the report,
of the advantages and disadvantages of the three.
1.2.1 Why This Project?
Since the 1970s [10], people started to take interest in using their computers as an
entertainment environment, thus, the multi billion game industry [3] was starting to take
shape. Having presented earlier the sum of money this industry produces, I decided to have a
go and create a game of my own.
As a kid, I was always fascinated by the idea of becoming a game developer, but, as years
went by, I have realised this is not exactly what programming and computer science, as a
practice, are about and I dropped the idea. However, the third year project offered me the
possibility to try and achieve one of my childhood’s dreams and I couldn’t resist the
temptation.
1.2.2 What The Project Is About?
The game, called Space Defender, is a 2D arcadelike space shooter built with Python and
elements of PyGame. The main idea of the game is for the player to destroy all the enemy
spaceships before advancing to the last level of the game where intelligent bad guys will do
their absolute best to defeat the good guy. Along the way, after each enemy is eliminated,
there is a chance a powerup will be generated which may or may not be useful to the player.
7
All powerups are generated based on the player’s style of playing as well as the history of
previous powerups. The player spaceship is controlled either via mouse or keyboard and the
enemy spaceships have a predefined movement in the first level of the game, while being
controlled by an AI module in the latter level. The player starts with three lives and has to
dodge enemy bullets in order to survive the continuous attack coming from the opponent
forces.
1.3 Why Python?
Despite the fact that I did not put Python in a very bright light when is used for game
development earlier in the report, I decided that this project is a good opportunity for
experimenting, as well as personal learning. Before starting writing code for the game, my
Python knowledge was limited, but, in the end, the research I have put in paid off. Also, I was
aware from day one that doing graphics in Python will be difficult, even with platforms like
PyGame, which are still crude and limited, but I took my chances.
8
Chapter 2 Development & Approaches 2.1 Overall Architecture
Fig. 4
The above figure shows the overall architecture of the game. As it can be seen from the
diagram, there are four major units that form Space Defenders: Audio, Graphics, Assets and
Game State components. Having followed a loose coupling and high cohesion approach in
building the underlying structure of the system, components can easily be changed without
affecting the others, making the application more flexible and easier to maintain.
9
Assets
The following component is more or less self explanatory, assets of the game being in one of
the two categories: audio or graphical assets. Regardless the category, all the assets that have
been used in this project are open source. Examples of graphical assets are the image used for
the player spaceship or the background image of the game, while an example of audio asset is
the sound that is played when the player spaceships shoots or when an enemy is destroyed.
Game State
Probably the most critical feature of the game, the game state is considered to be a variable
between 0 and 50, 0 signaling the game just started, while 50 representing the death of the
player spaceship. The said variable is what drives the algorithm that decides whether or not
and what powerup to throw to the player (more on powerups later in the report) when an
enemy spaceship is destroyed. The state of the game is strongly related to how many lives left
a player has (from a maximum of three) and what the current score of the player is. An
algorithm will take the two as inputs and will constantly compute, at every CPU clock tick,
the variable that represents the state of the game. One can argue this constantly calculated
variable represents the heart/core of the game engine.
Audio
The task of the audio module is to select and play sounds when certain events happen, such as
a powerup being picked up or the player spaceship has been hit by an enemy bullet. Before
the game starts, sounds are loaded into a mixer (a module used for loading Sound objects and
controlling playback), which acts as driver for the Audio module.
With a custom buffer and a careful choice of audio channels, the game is able continuously
play a background sound throughout the entire gameplay without interfering with sounds that
are played periodically.
10
Graphics
Various techniques to display graphics have been used throughout the video game history and
these techniques have evolved due to hardware improvements as well as the gamers’
demands.
Earliest games had textbased graphics [11], where players could read or view text rooms,
items, players or even actions performed in the game’s world. Requiring less to none
graphical processing, systems that could run these games did not require a video display at
all. The next ‘big hit’ in the video game industry was the vector graphics [12], which used
geometrical primitives such as points and lines, instead of bitmap graphics.
Fast forwarding to current day graphics, in which the 3D first or third person perspective
dominates the industry, I have chosen a 2D top down perspective [Fig. 5] for Space
Defenders. Also referred to as bird’s eye view, the top down perspective is described as a
camera point of view that shows the player (and the rest of the scene) from above [13].
Reason behind this choice is strongly related to the detail this approach offers in displaying
and manipulating entities, as well as aiding the mask based collision algorithm (more on this
later in the report). Currently, there seems to be a trend of remaking classic games and
fortunately, as we live in the HD remastering era, we have already witnessed Age of Empires
HD [14] and with Blizzard being rumoured to release HD remakes of Warcraft III and Diablo
II [15], I decided to follow the same principle so my game has a classical feeling to it.
11
Fig. 5 The game itself has a number of graphical items, such as the player spaceship, the enemy
space ships, bullets or powerups, that interact with each other maximising the gameplay
experience. All these entities are loaded as PNGs and converted to PyGame Sprite objects for
easier manipulation.
2.2 Technical Achievements
PowerUp Module
In the video games world, powerups are objects that aid the entity that picks them up. In
order for the player to benefit from the effects of a powerup, it has to come in direct contact
with the powerup.
Powerups history goes back to the mid 1980s when games such as Pac Man, Sabre Wulf or
Super Mario [16] revolutionized the gaming industry, introducing features that aided the
player to defeat the game. Regardless their type, offensive, defensive or even evasive,
powerups become a crucial part of the gameplay, despite the genre of the game. Having
mentioned the importance of powerups in the gaming world, it seemed imperative for my
game to implement such functionalities.
12
Space Defenders, however, implements powerups with a slight variation: a number of these,
instead of aiding the player, make its job even harder. The reason behind this is to make the
gameplay smoother by assisting or hindering the player depending on his playing style. The
spawning of the powerups is strongly linked to destroying enemy spaceships. Every time the
player successfully kills an enemy, there is a chance, depending on the current state of the
game, that a powerup will be generated.
How are powerups generated
At every CPU clock tick, a score that represents the game state is calculated, taking into
account the player’s score (maximum of 21) and number of lives (maximum of 3) of the
player, as well as what types of powerups the game threw to the player. This score is
between 0 and 50 and an example of this can be seen in the table below.
Game State* No. of Lives Player Score PowerUps Trend**
Between 40 and 50 3 17 Positive
Between 10 and 20 2 16 Negative
Between 25 and 35 2 5 Positive
Between 0 and 5 1 3 Negative
Fig. 6
*The higher the game state the higher the chances for a powerup that will not aid the player
in beating the game
**A positive PowerUp Trend represents a sequence of powerups that aid the player, while a
negative trend is a powerups sequence that hinders it.
13
After the game state has been set, an algorithm will be fed this, as well as the powerups
trend, and will generate a powerup for the player, as it can be seen in the diagram below.
***
*** PowerUps explained, from left to right: lose a life, gain a life, lose the ability to shoot,
invisibility, invincibility
When the game is first loaded, each powerup is assigned an integer number between 1 and 5,
depending on how often the player may receive a certain powerup, 1 beingrarely while 5 is
regularly. For clarity, let’s assume the numbers from 1 to 5 are in an array that dictates what
powerup is thrown to the player. As the game progresses and since the game state score is
computed at every CPU clock tick, the player’s needs for certain powerups changes,
therefore, the array mentioned above changes as well and all powerups are assigned new
integers.
Let’s assume the following scenario: the player has 3 lives left and a score of 15. A scenario
like this one will most probably end with the player beating the game, therefore, naturally, the
game engine will try to stop this for happening. For this to be possible, powerups such as
lose a life or lose the ability to shoot will become more probable than, for example, gain a
life and the powerups rarity array would look like this:
14
Fig. 7
Looking at the diagram above, we can see that certain powerups are to be generated more
often than the others, but, before a powerup is thrown into the game, one more step needs to
be taken, a probability distribution algorithm[16] that will finally decide what powerup the
player receives. On a really high level, a probability distribution is a function that links every
outcome of an experiment with their probability of occurrence. Usually, using such
algorithm, the probabilities of the outcomes would depict a Gaussian curve [17]. If I followed
a step by step implementation of such algorithm, powerups that are assigned the integers 2
and 3 would have been the most common ones. However, for the purposes of these report, I
have altered the classical approach and tried to implement a variation of this algorithm.
How it works
The reason for implementing a variation of the above mentioned algorithm was to avoid the
Gaussian curve representation of the probabilities and try to force the powerups that are
assigned a higher number to be thrown out in the game. The approach I have came up with
generates and subtracts a random number between 1 and 5 from the sum of all numbers in the
rarity array, which is 15. After each subtraction, a new random number is generated and the
process restarts, until the result is a number between 1 and 5, in which case the associated
powerup is given to the player. The motive behind this is simple: the result of such
subtractions is more likely to be a high number, such as 5 or 4, within the rarity array,
rather than a lower number, such as 1 or 2, therefore, a powerup that would directly
influence the gameplay will be awarded to the player.
15
Collision
Collision detection represents the problem of signaling the overlapping between two or more
objects, the topic being mainly associated with video games as well as physical simulations.
Therefore, since collision between entities is one of the factors that make any game seem as
close to a real world scenario as possible, Space Defenders’ collision detection algorithm
aims to achieve this.
In order to understand the collision detection algorithm used in Space Defenders, we need to
understand what are the two approaches that can be undertaken when checking for collisions:
discrete and continuous
A posteriori (discrete) versus a priori (continuous) [19]
With an a posteriori approach a system advances by a time step (one or a few CPU clock
ticks in my case), then check if there are in fact any collisions. With every simulation (time)
step, the algorithm is being fed a list of entities able to collide with the positions of these
entities being considered fixed at every step so the algorithm can check if a collision has
happened. The algorithm then returns a list of intersecting objects. We call this type of
approach a posteriori (discrete) because the collision is signaled only after its occurrence.
With an a priori (continuous) approach, the collision algorithm has to be able to predict the
trajectory of the entities in order for the collision to be signaled before it happens. This type
of algorithms are mainly being used along with artificial intelligence algorithms to help non
playing characters (NPCs) to dodge certain events.
Clearly, each approach has its own advantages and disadvantages. In an a posteriori
approach, the algorithm does not have to be aware of any other factors (physics, entities that
do not follow a pattern, frictions etc) apart from the present objects in a scene. On the other
hand, since a discrete collision algorithm requires a time step, “fixing” this time step wrong
can cause issues. Let’s consider an example from Space Defenders: a bullet (the width and
height of which are really small) can pass through a spaceship without the system advancing
by a step with no collision being signaled. In an a priori approach, the algorithm tends to be
16
more reliable, however, the problem of determining if two bodies will collide considering
their trajectories (influenced by external factors) still remains unsolved.
My work covers a number of possible sources of collision, such as player bullet vs enemy
ship, enemy bullet vs player ship, player ship vs powerups and so on. I have chosen a
discrete approach for my project and I have set the time step at one CPU clock tick. Also, I
have chosen a Mask Based collision detection approach for this.
Mask Based Collision Detection Algorithm
A mask of an image is a bitwise matrix representation of the said image [20], where
transparent pixels are represented as 0s and non transparent pixels as 1s. Let’s consider the
following example image:
For demonstration purposes, let’s imagine the black ‘frame’ of the light blue square is in fact
the background of the image and is transparent. Also, let’s assume that the size of the image
is 4 pixels x 4 pixels and the “frame” is exactly 1 pixel wide. The bitwise mask of the image
above looks like this:
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
17
Despite mentioning above that all my graphical assets were converted to Sprite objects for
easier manipulation, PyGame still loads them as PNGs before thiscasting occurs, therefore, I
can create masks for every graphical object. The main idea behind a Mask Based Collision
Algorithm is straightforward: if, at any time, at least two 1s from different masks overlap,
a collision occurred. Such algorithm follows an a posteriori approach, since the collision is
signaled only after it happened.
Why a Mask Based Collision Algorithm?
Without masks With masks
Fig. 8
The diagram above depicts the difference between using mask based and non mask based
collision detection algorithms. An alternative approach to the mask based collision algorithm,
an approach I have implemented before switching to masks, is to have all the Sprite objects
inside rectangles. Collision would then be signaled if two of these rectangles would intersect,
as it can be seen on the left hand side of the diagram above. Despite this is a possible
approach to tackle collisions, it is not quite accurate, especially if the shape of the objects
within the rectangles are irregular.
18
Using a mask based approach, the algorithm would signal the same scenario as before as no
collision. This would be the case because even though the bitwise matrixes of the two PNGs
would intersect, no 1s would overlap.
Enemy AI
In the gaming world, artificial intelligence (AI) is used to simulate humanlike intelligence in
non playing character. The reason behind this is for the NPCs to behave accordingly within
the environment constraints. From the early 1970s, when a number of games that featured
enemies were released, including Pong, and later Space Invaders, people realised gaming
needs to move forward from the competition between two players, thus, the idea of AI
opponents was starting to become more and more popular. [21]
From simple AI move patterns, game developers introduced, in the early 1990s, the idea of
using a finite state machine (FSM) that simulates the behaviour of an NPC [22]. I have
chosen to implement a similar AI architecture in my game as well.
FSM Based AI Algorithm
19
A finite state machine, or FSM for short, is an abstract model of a system made of a number
(finite) of states. At any given time, the system can find itself in one and only one state, thus,
for the system to perform various actions, the machine has to transition to another state. [23]
FSMs are primarily used to organise the execution flow of a system, therefore being
appropriate to implement AI in video games. Any FSM can be defined as a graph: the nodes
are states and the edges are transitions. Thus, the brain of an enemy can be modeled as a
FSM with states representing actions the NPC can perform, such as Move, Fire, Dodge or
being Dead. All transitions are labeled with events that, if happened, the system changes from
one state to another.
My game follows this approach and the enemy space ships perform actions based on certain
events: player’s actions or position at any given point in time.
Enemy AI Moving
Following an a posteriori approach to handle collisions, it would have been impossible for
the enemy space ships to avoid collision with the player’s bullets. Therefore, to implement an
algorithm that would signal the NPCs when to dodge, I am using an a priori approach.
Fig. 9
20
At every CPU clock tick, the NPCs analyse the environment for player’s bullets and the
enemy space ships will dodge bullets if one of the following two scenarios: the distance
between the player’s bullet and an enemy spaceship is less or equal to d or, considering the
trajectory of the both player’s bullet and the enemy spaceship, they will intersect in the near
future. In either of the two scenarios, the enemy spaceship, taking into account its position,
will dodge the bullet by moving either up or down without leaving the screen.
Enemy AI Shooting
Space Defenders has two types of enemies: enemies that shoot straight regardless the position
of the player and enemies that sense the position of the player spaceship and shoot in its
direction. This subchapter will cover the latter.
PyGame treats movement as continuously blitting on the screen the same object at different
coordinates at every CPU clock tick, thus, the bullets make no exception. For PyGame to
redraw PNGs at every clock tick, it needs to know each new pair of coordinates and,
compared to bullets being shot straight, shooting diagonally requires advanced mathematical
computations.
Fig. 10
As mentioned before, PyGame needs a set of pair of coordinates to know where to draw the
bullet that has been shot diagonally. In order for the enemy bullet to go exactly where the
21
player is, it has to follow an imaginary line that connects both the player and the enemy
spaceships, therefore, a set of points that reside on this line has to be generated.
In order to retrieve such set, we first need to create this line. It is a well known fact that two
points in space create a line and since we have two such points, point A(x1, y1) and B(x2,
y2), where x1, x2, y1, y2 are coordinates, as seen in the diagram above, these points being the
rightmost point of the player spaceship and the leftmost point of the enemy spaceship,
respectively. Once we have established we have two points in space, the equation of line d is:
y − y1y2 − y1 =
x −x1x2 − x1
The equation of lined reads as follows: a new point P(x, y), wherex andy verify the equation
above, reside on line d. Having known that the bullet is shot by the enemy spaceship, we
already know that point B(x2, y2) resides on line d and the question remains on how to
generate a large enough set of points that reside d so the bullet would give the feeling of
moving smoothly. To achieve that, I am incrementing x2 by 1 pixel, which, let’s assume,
results in x3, at every CPU clock tick and using the following equation to find the
corresponding y3: 3 1y = x2 − x1
(y2 − y1) ∙ (x3 − x1) + y
I keep generating these (xn, yn) pairs until either the bullet leaves the screen or hits the player
spaceship. Having computed a set of points that reside on line d, the bullet goes diagonally,
but still needs to be tilted by an angle T, so shooting into the player’s direction would look
more naturally. In order to do this, we need to find the radians value of the angle T.
Keeping in mind the diagram above, we need to find the following: the distance between the
player and the NPC, which is the length d as well as the length of d’.
y2 y1d′ = −
22
d = √ (x2 x1) (y2 y1)− 2 + − 2
With d and d’ calculated, we can compute the sin of T, which can further be used to find the
value of T in degrees (let’s call this value valT). With this value, we can calculate the number
of radians of T (let’s call this value radT), which can be used to tilt the bullet into the
direction of the player.
in(T ) s = dd′
alT rcsin(sin(T )) v = a It is well known that 180 degrees is 2π radians. So, if we know valT, we can easily calculate
radT as follows. radadT r = 360
2π ∙valT Doing these graphical transformations, shooting diagonally looks like the right hand side of
the diagram below.
Fig. 11
23
2.3 Alternative Approaches
The following chapter will cover alternative programming tools that could have been used to
build Space Defender, instead of Python. The two choices I have looked into before deciding
on using Python were Javascript and HTML5 so, I will try to briefly display the advantages
and disadvantages these would have had in relation to Python.
Javascript
One of the greatest advantage Javascript has over Python is that in runs directly in browser,
therefore, an application built completely in Javascript has the capability to run on every
machine, without installing any third party application. On the other hand, Python, alongside
PyGame, has to be installed before the Space Defender can run. Moreover, another Javascript
asset is that the code is executed on the client side, which can lead to better app performance
if the client’s machine is powerful.
On the contrary, Javascript can prove to be disadvantageous as it can sometimes be
interpreted differently by different browsers. Whileserversideapplications produce the same
results on different machines, pure Javascript applications can be erratic if not properly tested
in all major browsers. [24]
HTML5 Canvas
HTML5 has a number of advantages over Python, one of them being that runs on the client
machine, similar to Javascript. Moreover, HTML5 has the potential, unlike Python, to
perform a thorough pixel by pixel manipulation [25], therefore, it can easily be a valuable
tool for image processing. Also, HTML5 is very efficient in manipulating small size images,
which is a powerful asset when checking for collisions. On the other hand, with such great
ability and responsibility, the freedom of drawing HTML5 offers to has a major
disadvantage: the user is in charge of all the drawing, however, libraries have been built to
ease this process.
24
Having presented the advantages Javascript and HTML5 posses over Python in regards to
image processing, I felt a web application could have been unreliable, therefore, I have
decided to use Python and PyGame to build my third year project. Despite having troubles
manipulating graphical objects before I actually gained some experience with PyGame and
despite sleepless nights trying to fix silly bugs, if I were to start over I would still choose
Python and PyGame to build Space Defender.
2.4 Approaches
Agileesque
Agile is a software development technique based mainly on collaboration within a
selforganising team [26]. Since the final year project is a piece of software tailored for sole
development, one cannot assert a full agile development technique can be used in building
this project. However, I have tried my best to follow a number of agile methodologies to
support the development of Space Defenders. The techniques that I found useful for my
project were the Task Board and User Stories, techniques that helped me not only layout all
the tasks I needed to complete, but helped me keep track of my progress as well as set
personal deadlines throughout the project.
Task Board And User Stories
Having taken the Agile Software Development course in the first semester, one task I was
assigned was to follow at least one agile technique during my third year project. My first
thought went to a virtual Task Board and to develop it, I have used an online tool called
Trello.
25
Fig. 12
An agile Task Board is nothing but a board divided in a number of columns in which tasks
(written on cards) are placed taking into account their progress. As it can be seen in the
snapshot above taken from my actual Task Board, each task can find itself in only one
column at the same time, Backlog, In Progress or Done [27]. In order for a task go move
forward (or backwards) in the Task Board, certain events have to happen. For example, a task
can move from Backlog to In Progress at the beginning of a new iteration, or it can go from
In Progress to Backlog if the task was not successfully implemented by the end of an
interation. While the first three columns represent a standard Task Board, the fourth column
is nothing but a Legend that helps me keep track in which sub category of the project each
task is.
In the first couple of months of the project, I was only using a Task Board to break down my
project into subtasks and keep track of them, but soon I realised that User Stories would be
another agile methodology that could prove useful in achieving my goals. A User Story is a
way to capture a description of a software specification/feature from an user perspective.
Usually, User Stories are built using the Connextra template: "As a <role>, I want
<goal/desire> so that<benefit>" [29]. Therefore, User Stories that I designed for my project,
such as: As a player, I want my spaceship to pick up powerups so that the abilities of the
spaceships are altered, or As a player, I want to always see if I have a powerup picked up
already so that I know how to modify my gameplay based on this, helped me not omit any
critical functionalities. Using User Stories I was able to implement full endtoend
slices/components, thus, following such approach I could make sure no task is left undone.
26
Advantages
During the course of the implementation of Space Defenders, I have used a timeboxed, fixed
schedule Sprints of one week, therefore, I was able to deliver early as well as frequently.
Perhaps, if I had not used agile methodologies I would have ended up realising I am behind
schedule and the project would not have been finished on time. What is more, another
advantage of using agile methodologies is that the project was broken down into smaller
units, therefore, I could focus on the parts that would offer the highest value. Last but not
least, as mentioned before, using a Task Board offered me the ability to track the progress of
the game against my goals as well as set personal development deadlines.
Planning
At the beginning of the project, I have planned my work on a weekly basis, covering all 23
weeks the project was spread on, apart from the last couple of weeks that were left for
endtoend testing and debugging purposes. To plan my tasks, I have built a Gantt Chart [29]
and the reason the units are one week long is to have short agile iterations so I can deliver
often.
Each task was assigned a number of weeks, depending on its priority and difficulty. Despite
the initial plan was probably a bit too daring, as the project went along I replanned on a
weekly basis and started to drop tasks that did not carry a high importance factor, such as
enemy spaceships to have their own lives system.
27
Chapter 3 Evaluation
Quality And Correction Of The Project
In Computer Science, the correctness of a piece of code comes from its behaviour against a
well defined specification. This type of correctness refers to the relationship between input
and output (each input produces a planned and desired output). [30]
On a really high level, the correctness of Space Defenders comes from how the game behaves
when certain events happen. Having designed how I want the game to look and act
beforehand, to guarantee Space Defenders behaves accordingly, all algorithms were first
developed on paper and then implemented as code. What is more, if a piece of code was
proved to be correct, it was reused if possible rather than implementing a similar one. To
further assure the correctness of the code, I have followed a Design by Contract approach,
concepts taught in a first semester module Verified Development.
Design by Contract (DbC)
Design by Contract is a software correctness technique that uses pre and postconditions to log
state changes produced by functions/methods or any other pieces of code. [31]
28
To define preconditions and postconditions, let’s assume the following scenario: There is a
system that monitors the state of a car. The car can find itself in one of the following states
engine off, engine on, car braking or car accelerating. Each state is dependant on a number of
variables such as: isKeyPresent, gasPedalDown, breakPedalDown, carAccelerate etc. If we
define a method that checks if the car is accelerating, it would look something like this:
The precondition of the above method, the boolean value of isKeyPresent, gasPedalDown
and brakePedalDown, has to be true in order for the accelerate method to be executed.
Therefore, if, at any given point the three variables have the boolean values required, the
method can execute. After its execution, the postcondition is what will hold true, regardless
of any other pieces of code. To sum it up, preconditions are constraints that must hold true so
a method can execute, while the postconditions are the entities that will hold true after the
method executes.
Even though I have not directly implemented such functionalities in my Python code, when
possible, I designed methods on paper that accept pre and postconditions before
implementing the logic into code. An example of such method would be powerUpAction,
which applies the effect of a powerup to the player and an implementation would like this:
Such implementation assures the powerup has been picked up by the player before applying
its effect, as well as the player will not pick two powerups simultaneously and the player is
under the effect of the powerup for a limited period of time (stopClock variable).
29
Following a Design by Contract approach has a number of benefits, two of the most
important being: a systematic approach in building bug freecode anddealing with abnormal
cases. [32]
Testing
Apart from correctness, for a piece of software to truly behaves the way it should, testing is
required as well. Since testing is designed to provide an objective view of the quality of
software, I strongly believe the job of testing should be out of the hands of the developers.
Representing the third year project, I believe that the best way to test Space Defenders was a
variation of User Acceptance Testing (UAT) [33]. Despite UAT being the last phase of
testing before a release, I consider no developer wants to see their code fail under Unit or
Integration Testing, UAT is the solely way of actually testing such project. In order to
achieve this, I needed users to play the game and log the bugs they find so I asked my
girlfriend to play this role. As the game progressed she would play and try break it so I would
be aware of existing bugs that needed immediate fixing. Also, after every release of the
game, she would make sure the new feature don’t affect the old ones, taking the exact steps
she did to break it before. Having another person, another developer, test my code for bugs
made me aware of many issues with the game, some of which, perhaps, would have still be
there as we speak.
Apart from UAT, I did other types of testing on my own, one of them being Integration
Testing [34]. Following an iterative integration approach, after each component was
implemented separately, it would be tested against other interacting components to make sure
there are no new defects. Progressively throughout the project, if new components caused
others to break, they would have been reviewed and tested again until there were no failures.
If during the course of the project I did Integration and User Acceptance Testing, I have
allocated a couple of weeks before the deadline purely for endtoend testing. Having finished
the game and noted down every bug I encountered in the past few months, I tried to recreate
the same scenarios that led me to those bugs to check if any system is still failing. Without
30
much surprise I managed to find failures that I could fix within the time frame allocated for
the project.
Chapter 4 Reflection and conclusion
Game Dev vs Software Dev
I have worked for more than a year and a half for major corporations and the third year
project offered me the opportunity to try code something else, and for me this something else
was a game. Therefore, since I now have experience in both fields, I believe I can analyze
and compare the two branches of coding: game development and company software
development.
Let us start with company software development, since this is the field I have the greatest
experience in. When a company requires a piece of code to fulfill a certain task, usually, it is
either because the company wants to meet a business requirement or redo their current
software, thus, regardless the case, a business need has to be filled. Fundamentally, leaving
the complexity of company softwares aside, if a team of developers has to build an inventory
system, they can define what types of items they have to handle. If they want to build a
production scheduling system, they have to take into consideration this and that. They can do
all that. Company software is equivalent to making someone’s job easier and faster.
However, when it comes to gaming, the business need is fun. No one is able to write a
technical spec of fun. Therefore, this is what I think makes games different and harder to
implement than company/regular software. No developer can assert that a game is now
complete because these were the client’s requests since the client is an entire world of
gamers. With that in mind, a game does not need 3D graphics, awesome physics, multiplayer
or fancy features to be fun. Remember, Tetris is a fun game and its game engine and physics
are nothing but rotate or move the blocks left or right.
31
All in all, building a game for my third year project was much more fun and even challenging
than building software for top tier banks. Dealing with many segregated systems such as
Collision Detection, Animation, Graphics or Artificial Intelligence helped me understand
how to tackle issues and overcome bugs more efficiently, which is a skill that is great to have
when I start my graduate scheme in September.
Challenges
The past few months spent working on Space Defenders proved to be more challenging than
expected. From tackling graphics in project for the first time to detecting and handling
collision, the third year project carried me on a journey that strengthen my knowledge both as
a student as well as a future developer. During the course of developing this project, the first
and probably the most critical task that challenged me was my knowledge of Python.
Regardless the modules I took in the first and second year of university, Distributed Systems
and Distributed Computing, respectively, the level of Python required for this project was
way above what I was asked to use Python for in the previous years. Therefore, only after I
intensively taught Python myself I could actually make visible progress on Space Defenders.
While working on my third year project, I encountered other two big challenges: the
mathematical graphical manipulations and developing a sensible powerup module.
Firstly, let’s consider the powerup module. The overall challenge with this was how and
when to generate powerups and for this I have altered and used various algorithms, from
continuously computing the game state to implementing my version of a probability
distribution algorithm. Looking back to the past few months, I can argue that the challenge
regarding the powerup module was not as much a technical one as it was a logical one on
how to design this module to be as sensible as possible. Thus, designing and building on top
of an average proved to be both a solid technical as well as thinking exercise.
Secondly, a number of mathematical transformations were required for the enemy spaceships
to be able to shoot diagonally. These were covered in detail in Chapter 2, however, the
32
challenge in achieving these came from the fact that the last time I have used such equations
was when I was in high school, over 4 years ago.
Further Development
If Space Defender was not a third year project and if the development was not constrained by
a tight deadline, the player would have benefited from a number of extra features such as
local and remote multiplayer, boss fights and a mobile version. Even though Local
Multiplayer was part of initial plan, it was not delivered due to the meticulousity other tasks
were undertaken.
To implement a Local Multiplayer functionality, I would have used the Xbox 360 Controllers
API so two non NPC spaceships could be controlled by two players in the same time, on the
same screen. Such functionality would also require two different score as well as lives
systems and an altered powerup module that would compute the game state based not on one
but two different gameplays. While a local multiplayer feature would not require much more
than a Python implementation of the Xbox API and a couple of controllers, a remote
multiplayer functionality would involve a server to which clients are able to connect in order
to send and get data from. Apart from local and remote multiplayer, if Space Defender were
to be a real life project, the players would have enjoyed from a variety of level styles as well
as boss fights to pass certain levels. To take the game one step further, it could have even be
deployed on mobile. Despite Python is not the first programming language that comes to
mind when one thinks of writing applications for either Android or iOS devices, tools such as
Kivy can convert the Python code and create applications from its logic, following a Write
Once, Deploy to Many concept.
Conclusion
If I were to summarize the entire experience of the third year project in a word, it would be:
adventure. Looking back to the past few months, I can truly assert it has been a journey that
started slowly, without much progress due to the lack of technical knowledge required for
33
this project, but took off while making progress with the research. I began the project with
absolutely no idea on how graphics work, how a collision detection system works or even
how to display an image on the screen and, by the end of the project, I got to a point where I
could create my own or modify existing game specific algorithms to suit my needs.
What is more, this was my first attempt to building a game and I believe that achieving to
create a single player space shooter arcade game with a smart powerup module and AI for
NPCs is a good start if I decide to go down the game development path.
34
Figures Fig. 1: Table displaying the time people are not allocating anymore to entertainment activities
other than gaming compared to 2012
Fig. 2: Table displaying the revenue of the video games industry between 2010 and 2013.
Numbers converted from US dollars ($) to Sterling Pounds (£), using the conversion rate of
5th April 2016
Fig. 3: Video Games Industry sales for the domestic Japan Market. Numbers converted from
US dollars ($) to Sterling Pounds (£), using the conversion rate of 5th April 2016
Fig. 4: Overall architecture diagram of the game. Diagram built using cacoo.com web
software
Fig. 5: Example of top down perspective using a GTA 2 screenshot
Fig. 6: Table displaying the game state score in relation to player’s gameplay
Fig. 7: Example of powerups rarity array
Fig. 8: Comparison between mask and nonmask based collision algorithms
Fig. 9: Enemy spaceship behaviour regarding an approaching player bullet
Fig. 10: Enemy and player’s positions when the enemy shoots diagonally
Fig. 11: Tilting of the enemy bullet after mathematical transformations
Fig. 12: Snapshot of the Task Board used throughout the project
References [1] Pygame. URL: http://www.pygame.org/hifi.html. Last accessed: 04/04/2016
[2] The ESA 2015 Report. URL:
http://www.theesa.com/wpcontent/uploads/2015/04/ESAEssentialFacts2015.pdf. Last
accessed: 05/04/2016
[3] Video Games Industry sales. URL: http://vgsales.wikia.com/wiki/Video_game_industry.
Last accessed: 05/04/2016
[4] Video Game Industry sales in Japan. URL:
http://vgsales.wikia.com/wiki/Video_games_in_Japan. Last accessed: 05/04/2016
35
[5] Unity3D. URL:
http://blogs.unity3d.com/2014/09/03/documentationunityscriptinglanguagesandyou/. Last
accessed: 28/04/2016
[6] Quora. URL:
https://www.quora.com/Whatprogramminglanguageisthemostusedtomakevideogame
sWhichisthebest. Last accessed: 28/04/2016
[7] EvE Online. URL: http://evesearch.com/thread/1262481/page/all. Last accessed:
28/04/2016
[8] Pyglet. URL: https://bitbucket.org/pyglet/pyglet/wiki/Documentation. Last accessed:
28/04/2016
[9] Pyganim. URL: http://inventwithpython.com/pyganim/. Last accessed: 28/04/2016
[10] Street Directory. URL:
http://www.streetdirectory.com/travel_guide/141178/gaming/the_very_first_video_game_eve
r_released_and_its_not_pong.html. Last accessed: 28/04/2016
[11] Juul, J. The Open and the Closed: Games of Emerges and Games of Progression.
Copenhagen. p328.
[12] Arie Kaufman (1993). Rendering, Visualization and Rasterization Hardware. Springer
Science & Business Media. pp. 86–87.
[13] Gaming Wikia. URL: http://gaming.wikia.com/wiki/Topdown_view. Last accessed:
28/04/2016
[14] Now Gamer. URL:
http://www.nowgamer.com/ageofempires2remasteredinhdedition/. Last accessed:
28/04/2016
[15] Softpedia. URL:
http://news.softpedia.com/news/blizzardismakinghdremakesforstarcraftwarcraftiiiand
diabloii495743.shtml. Last accessed: 28/04/2016
[16] Ausretrogamer. URL:http://www.ausretrogamer.com/thehistoryofmariospowerups.
Last accessed: 28/04/2016
[17] What is a Probability Distribution?. URL:
http://stattrek.com/probabilitydistributions/probabilitydistribution.aspx. Last accessed:
28/04/2016
36
[18] Gaussian Function. URL:http://mathworld.wolfram.com/GaussianFunction.html. Last
accessed: 28/04/2016
[19] Collision Detection. URL: http://alpcentauri.info/collision_detection.html. Last
accessed: 28/04/2016
[20] Masking Images. URL: http://www.xinapse.com/Manual/masking.html. Last accessed:
28/04/2016
[21] Artificial Intelligence in Games: A look at the smarts behind Lionhead Studio’s “Black
and White” and where it can and will go in the future. URL:
https://www.cs.rochester.edu/~brown/242/assts/termprojs/games.pdf Last accessed:
28/04/2016
[22] Brief History of Video Games AI. URL:
http://www.actiontrip.com/features/briefhistoryofvideogameai.phtml. Last accessed:
28/04/2016
[23] Finite State Machines: Theory and Implementation. URL:
http://gamedevelopment.tutsplus.com/tutorials/finitestatemachinestheoryandimplementati
ongamedev11867. Last accessed: 28/04/2016
[24] Advantages & Disadvantages of Javascript. URL:
http://www.mediacollege.com/internet/javascript/proscons.html. Last accessed: 29/04/2016
[25] HTML 5 Canvas: Pixel Manipulation.
URL:http://tutorials.jenkov.com/html5canvas/pixels.html. Last accessed: 29/04/2016
[26] What is Agile?. URL: https://www.cprime.com/resources/whatisagilewhatisscrum/.
Last accessed: 29/04/2016
[27] Building an Useful Taskboard. URL:
http://agileforall.com/buildingausefultaskboard/. Last accessed: 29/04/2016
[28] Connextra Story Card. URL:
http://agilecoach.typepad.com/photos/connextra_user_story_2001/connextrastorycard.html.
Last accessed 29/04/2016
[29] What is a Gantt Chart? URL: http://www.gantt.com/. Last accessed: 29/06/2016
[30] Correctness. URL:
http://www.tutorialspoint.com/software_testing_dictionary/correctness.htm. Last accessed:
29/06/2016
37
[31] Design by Contract. URL: http://c2.com/cgi/wiki?DesignByContract. Last accessed:
29/06/2016
[32] Building bugfree OO Software:
https://www.eiffel.com/values/designbycontract/introduction/. Last accessed: 29/06/2016
[33] User Acceptance Testing. http://usersnap.com/blog/useracceptancetestingright/. Last
accessed: 29/06/2016
[34] Integration Testing.
http://searchsoftwarequality.techtarget.com/definition/integrationtesting. Last accessed:
29/06/2016
38