Politehnica University Timișoara Faculty of Automation and Computers Department of Computer and Information Technology REAL-TIME STRATEGY GAME SYSTEM… [602767]

1
Politehnica University Timișoara
Faculty of Automation and Computers
Department of Computer and Information Technology

REAL-TIME STRATEGY GAME SYSTEM

Bachelor Thesis

Candidate:
Raul HAMZA
Supervisor:
Ș-l. dr. eng. Răzvan CIOARGĂ

Timișoara
2018

2
Table of Contents
Introduction …………………………………………………… ….……… 5
1. Chapter 1. Brief History ………………………………………… ….……. 7
1.1 An overview of the genre …………………………………… ….……. 7
1.2 Herzog Zwei ………………………………………………… ….……. 9
1.3 Dune II ……………………………………………………… ….…… 10
1.4 War craft: Orcs & Humans …………………………… ….………… ..11
1.5 Age of Empires ………………………………………… ……………1 2
1.6 Starcraft ………………………………………………… ……………1 3

2. Chapter 2. The Unity Engine …………………………………… …….….1 5
2.1 GameObjects ………………………………………………….… ..….16
2.2 Scenes ……………………………………………………… ..…… .…17
2.3 GUI. GUI Group. Rect ……………………………………… ….……1 7
2.4 Screen Coordinates …………………………………………… ..…….17
2.5 Vector3 ………………………………………………………… .……18
2.6 Quaternion …………………………………………………… ………18
2.7 The MonoBehaviour class ……………………………………… …….19
2.7.1 Awake() …………………………………………… …………19
2.7.2 Start() ………………………………………………… ………1 9
2.7.3 Update() ……………………………………………… ………1 9
2.7.4 OnGUI() ……………………………………………… ………19
2.8 The MonoDevelop Editor …………………………………………… ..20

3. Chapter 3. The Real -Time Strategy Game System …………… ….………. 21
3.1. SystemData ……………………………………………… …….…… 21
3.2. Player ………………………………………………………… ….….21
3.2.1 The Player Component ……………………………… ..…… …21
3.2.2 UserInput ………………………………………………… ……22
3.3. Unit Creation. Buildings ……………………………………… ….…25
3.4. Unit Movement ………………………………………………… ……26
3.5. Workers and Gathering Resources …………………… …..……… …28
3.6. Heads -Up Display ……………………………………… …………… 30

3
3.6.1 Cursor State ………………………………………… …… …… 30
3.6.2 Resource Bar …………………………………… …..………… 32
3.6.3 Orders Bar ……………………………………… …..………… 33
3.6.4 Pause Menu ……………………………………… …..……….. 34

4. Chapter 4. System Demo ………………………………… ………………… 36
4.1. Main Menu ………………………………………………… ……. …36
4.2. Game Map …………………………………………… ……… ………3 7

5. Chapter 5. Conclusion . ……………………………………… ………. …… 40
5.1 Achievements …………………………………………… ………… …..40
5.2 Future Developments …………………………………… ……….. …… 40

Bibliography ………………………………………………… …………. …41

4
Table of Figures
Fig. 1.1.1 . Modern recreation of the original Tennis for Two setup ………………7
Fig. 1.1.2. A typical battle in an RTS game – Warcraft III ………………………..8
Fig. 1.2.1. Herzog Zwei ……………………………………………………………9
Fig. 1.3.1. Dune II …………………………………………………………………10
Fig. 1.4.1 . Warcraft: Orcs & Humans …………………………………………….11
Fig. 1.5.1. Age of Empires ………………………………………………………..12
Fig. 1.6.1. The StarEdit Campaign Editor …………………………………………13
Fig. 2.1.1. The Unity interface …………………………………………………….15
Fig. 2.1.2. Unity System Requirements ……………………………………………16
Fig. 2.4.1 . Screen Coordinates …………………………………………………….17
Fig. 2.4.3 . Finding origin point for UI element placed at the center of the screen ..18
Fig. 2.8.1 . The MonoDevelop IDE ………………………………………………..20
Fig. 3.2.2 .2. Possible cursor graphics …………………………………………….22
Fig. 3.6.1 . The game interface …………………………………………………….30
Fig. 3.6.4 . The Pause Menu (center) ………………………………………………34
Fig. 4.1.1 . The Main Menu ………………………………………………………..36
Fig. 4.2.1 . Initial conditions ……………………………………………………….37
Fig. 4.2.2 . Final state, with all resources mined, 2 workers and 12 tanks …………37
Fig. 4.2.3 . Hierarchy view in the proj ect editor showing all the used components .38

5
Introduction
I have chosen to start development on the Real -Time Strategy Game System for multiple
reasons. The foremost reason is that, due to my growing interest in game development, I have
decided that I co uld gain more experience within this domain by creating a system from scratch.
Having more than a passing interest in the Real -Time Strategy genre (also referred to in this
thesis as “RTS”) as well as the lack of any innovation surrounding the genre since the release of
Starcraft II in 2010 , the idea of trying to create something useful in the long -term for the genre
appealed to me immensely .
Unity has been chosen for the development of this system due to its ease of access, its free
availability, as well as the functionalities provided and for allowing C# for the scripting of the
game logic.
This thesis contains descriptions regarding the context surrounding the creation of this system, as
well as detailing aspects of the game engine used and going into d etailed specific ation s of the
developed system.
The first chapter represents a short history of strategy games and tries to find a place and context
for the system within the RTS market.
The second chapter presents a short description of the Unity game eng ine as well as the
functionalities that were used for the development of the Game System .
The third chapter goes into the details of the system by presenting the architecture of the system
as well as each individual component.
The fourth chapter presents the demo provided with the system as an example of what the system
is capable of at the time of this writing.
The fifth and final chapter presents the possible future features that may arise through continuing
developing this system as well as presenting t he conclusions of this thesis.

6

7
Chapter 1 . Brief History
1.1 An over view of the genre
Since ancient history, games have been an important facet of human culture and civilization. One
of the oldest games in existence, Senet, was discovered to have been p layed since at least 3100
BC[1].
As far back as the Roman Empire[2], simulations have been used as tools for commanders to
practice battle tactics. In 1812, German and Prussian military officers were trained in warfare
using a board game setup as a train ing tool . Called Kriegs spiel (“war game”), the board was
divided into a grid much like board games are played now and armies were represented by color –
coded models[3].
Games have first reached the computing medium in 1958, when Tennis for Two was developed
by American physicist William Higinbotham. Built with the use of vacuum tubes and transistors
and using an oscilloscope in order to display graphics, Tennis for Two featured a side view of a
tennis court and allowed two players to play tennis with the hel p of two controllers consisting of
a button and a knob. The serving player could use the knob to adjust the angle at which the ball
would be launched while the button would be used to hit the ball[4].

Fig. 1.1.1 . Modern r ecreation of the original Ten nis for Two setup1

1 https://www.gamasutra.com/blogs/BenJohnson/20151123/260126/Conserving_Tennis_For_Two.php

8
Game consoles have been available commercially since the release of the Magnavox Odyssey in
1972, which over the course of its lifetime managed to sell approximately 350,000 units sold[ 5].
The Odyssey could only draw simple rectangle sh apes. Since the system lacked any writeable
memory, players were forced to keep track of scores manually.[6]
The popularity of th e video game medium increased exponentially during the “arcade era”, when
by the early 1980s there were an estimated number o f 35 million people playing video games on
arcade cabinets[7].
The real -time strategy genre is defined as a game in which the player must control vast armies in
order to conquer their opponents’ armies. Typically, resource management is important as
resour ces allow players to recruit more units, build more buildings and research upgrades for
their army.
The game area is divided into a navigable playable area and the user interface which provides the
player with information regarding the current state of the game.
Gameplay usually consists of the players starting with a small base and few units and expanding
to as much of the map as possible while trying to remove their opponents ’ forces . Managing the
army requires both macromanagement (managing one’s forces and economy and long -term
strategic plans) and micromanagement (managing individual units in order to gain advantages
from its strengths or to avoid its weaknesses).

Fig. 1.1.2. A typical battle in an RTS game – Warcraft III

9
1.2 Herzog Zwei
The f irst strategy game that was in complete real -time (and could therefore be labelled as a Real –
Time Strategy game) was Herzog Zw ei. Released worldwide in 1990 for the Sega Genesis game
console , it did not reach mainstream success due to its lack of marketing and ea rly release on the
system[8]. The basic premise of the game has defined the entire genre and features two
commanders trying to build an army in order to invade the other’s base.
There were several gameplay elements which separate it from more modern RTS ga mes. T he
player was represented as a physical commander -type unit within the game. Resource
management is straightforward, with the player receiving resources at a constant rate. Building
locations are fixed and are hard -coded within the level, with the pl ayer unable to build more .
The game allowed a player to play against a rudimentary AI or to face off against a human
opponent.

Fig. 1.2.1. Herzog Zwei

10
1.3 Dune II
Dune II was released in 1992 for MS -DOS and 1993 for the Amiga computers and the Sega
Genesis console . It is the blueprint that most other RTS games have tried to emulate since then .
The player is not directly represented in -game as a character , but as an abstract, “god -like” being
that has permanent access to his units and buildings to issu e orders.
Unlike Herzog Zwei , resource management is no longer automatic. In order to gather resources
to build a base and create units, the player must first create specialized units called harvesters
whose sole function is the gathering of “spice” which is deposited by the unit into a Refinery –
type building owned by the player.
Base building was implemented in this game as well as the concept of a technology tree: to build
more technologically advanced units and buildings, the player must follow a strict build order.
For example, in order to build Silos which allow the player to stockpile more resources, the
player must first build a Refinery. Because the player was forced to build on a restricted area of
terrain , he was forced to think strategically abou t the plan of his base.
The “fog of war” is another element that brought strategic complexity to the game. When starting
a level, the map would be covered in darkness. By ordering his units around the dark areas, more
and more of the map would be revealed to the player. This was crucial to do in order to find
resource nodes and the opponent’s base.
Although playing against another human opponent was no longer possible, the game featured
three similar but distinct factions with multiple differences between t heir armies , each with their
own single -player campaign storyline . In order to prevail, a player must utilize the strengths of
his chosen faction and exploit the weaknesses of his opponent.

Fig. 1.3.1. Dune II

11
1.4 Warcraft: Orcs & Humans
During the m id-1990s, the RTS genre expanded with the addition of several new franchises. In
1994, Blizzard Entertainment released Warcraft: Orcs & Humans , the first installment of what
would later be a billion -dollar franchise [9].
It featured direct improvements ov er Dune II by allowing orders to be issued simultaneously to
groups of four units, two resource types to manage : gold which was gathered from mines and used
to buy units, and lumber which was used for buildings, gathered from forests. E lements of city
planning were added when expanding bases as all the buildings in a base were required to be
connected by roads .
“Specialist” units were introduced. While in Dune II combat units could only shoot projectiles,
the specialist units in this game had several specia l abilities which could be used to gain a strategic
advantage against their opponents.
The titular Orcs and Humans were the two factions that the player could choose to play as.
Although similar in most regards except graphical appearance, the specialist units for both factions
had completely different abilities at their disposal . To gain an advantage, players had to learn in
which situations they excelled at.
Warcraft: Orcs & Humans also featured support for multiplayer matches via modem or local
networ k connections.

Fig. 1.4.1 . Warcraft: Orcs & Humans

12
1.5 Age of Empires
In 1997, a strategy game based on human history would be released. Developed by Ensemble
Studios and published by Microsoft, Age of Empires allowed players to take command of
armies selected from 12 available civilizations, sufficiently distinct as to have different strengths
or weaknesses. There are four different resource types to manage.
A large amount of emphasis is placed on technological advancements. Mimicking real history,
civilizations in Age of Empires can progress through multiple technological eras: from the Stone
Age, to Tool Age, to Bronze Age and ending in the Iron Age. Each advancement to a new age
unlocks more advanced technologies, buildings and units.

Fig. 1.5.1. Age of Empires

13
1.6 Starcraft
In 1998 Blizzard Entertainment released Starcraft , a game which would sell over 11 million
copies by 2009[10]. The game’s popularity became so widespread that it spawned professional
sports leagues, with matches being broad cast over television and thousands of fans filling
stadiums during Starcraft tournaments. [11]
The game was set in the far future and featured three completely distinct races , all with their own
unique units, buildings, and strategies. Unlike previous entr ies in the genre, the pace of the game
is fast and tense, and to a slow and unprepared player, the armies are destroyed quicker than they
were built.
The multiplayer services are hosted on Blizzard Entertainment’s centralized system Battle.Net
which allows for quick searching and joining matches.
Another notable aspect of Starcraft was the included level editor called StarEdit . A powerful
tool, it allowed the creation of fan -made custom maps for regular play but it also implemented a
system of triggers whic h could allow imaginative fans to create custom game types with
alternative win conditions.

Fig. 1.6.1. The StarEdit Campaign Editor

14

15
Chapter 2. The Unity Engine
A game engine is a software framework which allows developers to build interactive app lications
by providing tools such as a scripting environment for application logic, a graphics renderer for
generating the visuals of the application , support for audio output, memory management and more.
The Unity engine is an game engine first released i n 2005 which supports creating both 2D and
3D games. It is easy to install and offers multiple user licen ses. If the revenue gained from using
Unity is less than $100,000 per year, a basic option for personal use is available for free
downloa d.
Unity is easy to use for beginners as many features are automatically handled by the engine
instead of requiring manual programming.
Unity allows the building of games for over 25 platforms, including Windows, Android,
Macintosh , iOS and Playstation 4.2
The Unity interface is easy to navigate and is configurable if needed. The middle of the screen is
occupied by the Scene inspector, which shows the level being developed in real -time. The
bottom part of the screen is the Asset explorer, where the game files can be see n. The left part of
the screen holds the Hierarchy View, where all the objects in the level can be seen. The Object
Inspector is on the right part of the screen, which details every component of a selected object in
the game. Moving components from one par t to another can be done with drag’n’drop.

Fig. 2.1.1. The Unity interface

2 https://unity3d.com/unity/features/multiplatform

16
For a computer t o be able to run Unity and games made in Unity , the following system
specifications are needed:

Fig. 2.1.2. Unity System Requirements3

2.1 GameObjects
GameObj ects are the fundamental building blocks of all the objects within a Unity game.
Because they have no effect by themselves, their behavior is defined by attaching Components to
them . The most important Component is called the Transform. This Component defi nes the
position and scale of the GameObject within the game world, and it is impossible for a
GameObject to exist without it. Unity provides a list of pre -built Components, such as
RigidBody (which allows the object to interact with its environment in a p hysical way), Colliders
(which can be used to determine the behavior of collisions of the object with other objects),
Light (which allows the object to emit light), but also allows the user to define their own
components using a C# scripting API. A custom object can be saved as an editable template
called a prefab for later instantiation. For multiple objects of the same type, it is more practical
to edit the prefab than edit each instance separately.

3 https://unity3d.com/uni ty/system -requirements

17
2.2 Scenes
Scenes represent a collection of GameObjec ts ordered in a coherent way to form one cohesive
experience. For example, each level in a game may be represented by a scene, as well as every
menu screen.
2.3 GUI. GUI Group. Rect
In order to programmatically draw on the screen, the GUI functions are u sed. Before drawing a
call must be made to the GUI class’ BeginGroup() method in order to define the areas on the
screen that are being drawn on, and Rect() can be used to define rectangles within the Group in
which the drawing will be made. The origin poi nt for drawing within a group is the origin point
of the group itself and not the screen coordinates. After drawing in the selected group, it must be
closed with a call to GUI.EndGroup().
2.4 Screen Coordinates
When drawing two -dimensional user interface e lements, screen coordinates are used. These are
represented by a cartesian system for which the origin point starts at the upper left corner of the
screen. As shown in figure 2.4.1 , the X coordinate of a point increases as the point travels
towards the rig ht of the screen, and the Y coordinate increases as the point travels towards the
bottom.

Fig. 2.4.1 – Screen Coordinates
For compatibility with different resolution settings, interface elements must be drawn
dynamically so that any change in screen siz e will not result in any element being drawn at a
different position than intended. To avoid this, all elements are placed on the screen according to

18
a formula which keeps them at a constant distance ratio from the screen origin point. The
formula is as f ollows:
𝑂𝑟𝑖𝑔𝑖𝑛 (𝑒𝑙𝑒𝑚𝑒𝑛𝑡 )=𝑙𝑒𝑛𝑔𝑡 ℎ(𝑠𝑐𝑟𝑒𝑒𝑛 )−𝑙𝑒𝑛𝑔𝑡 ℎ(𝑒𝑙𝑒𝑚𝑒𝑛𝑡 )
𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑒 𝑟𝑎𝑡𝑖𝑜 (2.4.2)
For example, for placing an element having the center point in the exact center of the screen, its
origin point is defined as having a distance ratio of 2. A geometrical proof for this particular ratio
can be seen in figure 2.4.2 , where the desired point illustrated at the position of the arrow head.

Fig. 2.4.3. Finding origin point for UI element placed at the center of the screen
2.5 Vector3
A Vector3 is a structure representing three -dimensional vector s and is used in the game world to
determine an object’s position within the game world.
2.6 Quaternion
Quaternions are abstract objects used by Unity in order to determine a unit’s r otation.

19
2.7 The MonoBehaviour class
The MonoBehavior class is provided by Unity as a way to programmatically interact with
GameObjects and define new Components for them. As such, classes which represent abstract
concepts are not required to inherit fro m this class.
The MonoBehaviour class provides several important methods used to control the flow of
events: Start(), Awake(), OnGUI() and Update().
2.7.1 Awake()
This method is called by Unity on each object after every object in the scene is loaded. Beca use
of the random and uncontrollable way that this method is called, it cannot be used to reliably
send messages between classes. This method is only called once per object lifetime.
2.7.2 Start()
This method is called when the script component of the Game Object that it is attached to is
enabled. This allows the programmer to fine -tune the timing interaction between classes. Start()
is always called after Awake().
2.7.3 Update()
This method is called once per frame and is used to define the continuous behav ior of a
GameObject .
2.7.4 OnGUI()
This method is called whenever the GUI is needed to draw something. It is called multiple times
per frame. Any calls to GUI must be handled within this method.

20
2.8 The MonoDevelop Editor
For editing C# scripts, Unity comes prepackaged with the MonoDevelop Integrated
Devel opment Environment (IDE).
The text editor is intuitive and offers the possibility of quick refactoring, lookups of symbol
references within the entire codebase, multiple tabs and split screen .
Due to its open -source nature, MonoDevelop also offers extens ibility by including an built -in
Add-in manager to add extra functionalities. Several functionalities that available add -ins can
implement are: support for version control with Git or Subversion, the WakaTime programming
time tracker or a simple hex editor .

Fig. 2.8.1 . The MonoDevelop IDE

21
Chapter 3 . The Real -Time Strategy Game System
This chapter shall be used to detail the specifics of every component and algorithm used to
develop this application.
As it stands, the Real -Time Strategy Game System is capable of managing players and their units
as well as individual actions for each of them .
3.1 SystemData
SystemData is a static class in which we define several values and methods which might be
required globally, such as the speed of the camera movem ent.
3.2 Player
The Player object is the class through which players interact with the game world. A Player
object is defined in the Real-Time Strategy Game System’s world by Player and UserInput
components, and also contains a HUD object and collections of his owned Units and Buildings.
3.2.1 The Player Component
The Player Component contains methods which manage the player’s supply of resources, such as
removing or incrementing. It also contains a method for spawning a unit in the game world and
adding it to the Player’s control. This method is called by a player -owned Factory building when
it has finished creating the unit. This method will be further discussed in Chapter 3.3.
public void AddUnit( string unit, Vector3 spawnPoint, Quaternion rotation ) {
Units units = GetComponentInChildren< Units >();
GameObject newUnit = (GameObject )Instantiate( SystemData .GetUnit(unit), spawnP
oint, rotation);
newUnit.transform.parent = units.transform;
}

A player also holds a maximum of one selected unit. When a unit is selected, its characteristics
are displayed on the orders bar. This will be further discussed in Chapter 3.6.3 .

22

3.2.2 UserInput
The UserInput component checks whether the player tries to interact with the game. There ar e
two ways to do so: with the mouse and with the Escape key. The Escape key is only used to
activate / deactivate the Pause Menu, while the Mouse Input has several functions: checking for
camera panning and checking for clicks .
When the player reaches the edge of the screen with the mouse cursor, the game camera will pan
towards that direction. The HUD is also notified to change the cursor graphic appropriately.

Fig. 3.2.2.2 . Possible cursor graphics
Checking for the camera panning is done in every frame, by checking if the cursor is within
CameraEdge pixels within the screen edges. The panning speed is defined as CameraSpeed per
second. If we remove the multiplication by Time.deltaTime, the speed shall be CameraSpeed per
frame. The code for this method can be seen below.
private void MoveCamera() {
float width = Screen.width;
float height = Screen.height;
float newCoord = SystemData .CameraSpeed * Time.deltaTime;
float mouseX = Input.mousePosition.x;
float mouseY = Input.mousePosition.y;
if (mouseX > width – SystemData .CameraEdge) {
player.hud.SetCursorState (CursorState .PanRight);
Camera.main.transform.position = new Vector3 (Camera.main.transform.posit
ion.x + newCoord, Camera.main.transform.position.y, Camera.main.transform.position.z)
;
} else if (mouseX < SystemData .CameraEdge) {
player.hud.SetCursorState (CursorState .PanLeft);
Camera.main.transform.position = new Vector3 (Camera.main.transform.posit
ion.x – newCoord, Camera.main.transform.position.y, Camera.main.transform.position.z)
;

23
} else if (mouseY > height – SystemData .CameraEdge) {
player.hud.SetCursorState (CursorState .PanUp);
Camera.main.transform.position = new Vector3 (Camera.main.transform.posit
ion.x, Camera.main.transform.position.y, Camera.main.transform.position.z + newCoord)
;
} else if (mouseY < SystemData .CameraEdge) {
player.hud.SetCursorState (CursorState .PanDown);
Camera.main.transform.position = new Vector3 (Camera.main.transform.posit
ion.x, Camera.main.transform.position.y, Camera.main.transform.position.z – newCoord)
;
} else {
player.hud.SetCursorState (CursorState .Main);
}
}

Another fu nction of the UserInput script is to handle mouse clicks. During every frame, checks
are being made if the Left or Right mouse buttons were clicked. If the left mouse button was
clicked , the player has no unit selected and the player has clicked on a unit (excluding the
Ground plane that the game is set on), it will be selected. If the player has a unit already selected,
the unit is responsible to check if any operation is available via a call to its MouseClick()
function.
private void LeftMouseClick() {
GameObject hitObject = FindHitObject();
Vector3 hitPoint = FindHitPoint();
if(hitObject && hitPoint != SystemData .InvalidPosition) {
if(player.SelectedObject) player.Sel ectedObject.MouseClick(hi
tObject, hitPoint, player);
else if(hitObject.name!= "Ground" ) {
WorldObject worldObject = hitObject.transform.parent.
GetComponent< WorldObject > ();
if(worldObject) {
//we already know the player has no selected object
player.SelectedObject = worldObject;
worldObject.SetSelection (true);
}
}
}
}

If the Right mouse button is clicked, the player’s unit selection shall be cleared, as seen in the
code sample below.

24
private void RightMouseClick() {
if (player.SelectedObject) {
player.SelectedObject.SetSelection (false);
player.SelectedObject = null;
}
}

25

3.3 Unit Creation . Buildings
Buildings are defined as immobile objects which can create units. Creation is not instantaneous
and varies based on each unit (values are defined in a Dictionary in the SystemData class), but
multiple units can be queued at a time. Units created by the building are spawned in front of it, at
a distance of 10 pixels. The unit spawn location is determined when th e building is first
initialized. The exact spawn point algorithm is as follows:
float spawnX = transform.forward.x + transform.forward.x * 5;
float spawnZ = transform.forward.z + transform.forward.z * 5;
spawnPoint = new Vector3 (spawnX, 0, spawnZ);

There are several actions which buildings do. To add a unit to the queue, the controlling player
must have sufficient resources to buy it. If the button to create a unit is pressed and the player
does not have sufficient resources, nothing happens. T he building does not add the unit to the
queue, and no resources are subtracted from the player. If the player has sufficient resources,
they are subtracted and the unit is added to the queue.
Every second, the queue is processed. If an uni t is queued to be built , the queue progress is
incremented, and when it has reached the build time defined for the queued unit, the unit is
created under the controlling player’s turn and the queue moves to the next unit after resetting
the progress counte r.
protected void ProcessBuildQueue() {
if (buildQueue.Count > 0) {
currentBuildProgress += Time.deltaTime * SystemData .BuildSpeed;
if (currentBuildProgress > SystemData .unitBuildTime[buildQueue.Peek()]) {
if (player) {
player.AddUnit (buildQueue.Dequeue (), spawnPoint, transform.rota
tion);
currentBuildProgress = 0;
}
}

}
}

Each particular building has its own defined list o f units it can build. These values are easy to
modify as they are stored in an array.

26

3.4 Unit Movement
When the UserInput script has detected that the player has clicked with a unit selected, that unit’s
MouseClick() method is called. After a check fo r redundancy that the object is selected and that
the user has clicked on the Ground, the unit is confirmed to move to the target point. Before
starting to move, the unit first turns so that it is facing the destination (using a Quaternion to
determine the rotation) . If the player has clicked within an unselectable WorldObject (such as a
resource node), the unit shall stop short of its destination, otherwise it will not stop until it has
reached its destination.
protected override void Update()
{
base.Update();
if (rotating)
{
TurnToTarget();
}
else if (moving)
{
MoveToDest();
}
}

public override void MouseClick( GameObject hitObject, Vector3 hitPoint, Player co
ntroller)
{
base.MouseClick(hitObject, hitPoint, controller);
if (currentlySelected && hitObject.name == "Ground" )
{
float x = hitPoint.x;
float y = transform.position.y;
float z = hitPoint.z;
Vector3 vector = new Vector3(x, y, z);
StartMove(vector);
}
}

public void StartMove( Vector3 destination)
{
destinationTarget = null;
this.destination = destination;
targetRotation = Quaternion.LookRotation(destination – base.transform.positio
n);

27
rotating = true;
moving = false;
}

private void TurnToTarget()
{
base.transform.rotation = Quaternion .RotateTowards( base.transform.rotation, t
argetRotation, rotateSpeed);
if (base.transform.rotation == targetRotation)
{
rotating = false;
moving = true;
}
}

private void MoveToDest()
{
base.transform.position = Vector3.MoveTowards( base.transform.pos ition, destin
ation, Time.deltaTime * moveSpeed);
if ((Object)destinationTarget != (Object)null)
{

if ((double)Vector3.Distance( base.transform.position, destinationTarget.t
ransform.position) < 1)
{
moving = false;
}

}
else if (base.transform.position == destination)
{
moving = false;
}
}
}

28
3.5 Workers and Gathering Resources
Unlike other units, units of the Worker class can gath er resources. A worker has several
attributes related to this: the amount of resources currently carried, the type of the carried
resource, the maximum capacity that he can carry, the resource node currently being harvested,
the gathering speed and whether the worker is currently gathering resources or depositing them.
When the user clicks on a resource node with a selected worker, the worker moves to the center
of the node. After reaching it, he starts harvesting. Resources are deducted from the harvested
node and added to the worker’s capacity. Once the worker reaches the maximum capacity, the
carried resources are added to the controlling player’s stockpile. The operations are done on a
per-frame basis and are handled within the Worker’s Update() method as shown below:
void Update () {
base.Update ();
if (harvesting) {
if (!(this.moving)) {
resourceCarried += currentlyMinedResource.Remove (1);
}
if (resourceCarried == resourceMax) {
harvesting = false;
depositing = true;
}
if (currentlyMinedResource == null) {
harvesting = false;
}
} else if (depositing) {
player.AddResource (resourc eType, resourceCarried);
resourceCarried = 0;
depositing = false;
// if resource is empty stop
if (currentlyMinedResource) {
StartHarvest (currentlyMinedResource);
}
}
}

Checking if the worker was ordered to harvest from a node is done when the Worker has
received a MouseClick() call from UserInput. It checks whether the object is a resource node, in
which case it will move towards it and start harvesting. Otherwise it will move to the point on
the ground that the player has clicked on.

29

public override void MouseClick( GameObject hitObject, Vector3 hitPoint, Player contro
ller) {
base.MouseClick (hitObject, hitPoint, controller);
// check if the clicked object was a resource node
Resource resource = hitObject.transform.GetComponent< Resource > ();
if (resource) {
player.SelectedObject = this;
resourceType = resource.GetResour ceType ();
StartHarvest (resource);
} else {
StopHarvest ();
}
}

30
3.6 Heads -Up Display
The Heads -Up Display (henceforth referred to as HUD) represents a collection of user interface
elements that are shown to the player. As it can be seen in Fig. 3.6.1 , the game interface is split
into three parts: the resource bar occupies the top of the screen, the orders bar occupies the
bottom of the screen, and the playing area sits in the middle.

Fig. 3.6.1 . The game interface

3.6.1 Cursor state
As previously discussed in Chapter 3 .2.2, when the mouse reaches the edges of the screen and
the camera starts panning, calls are made to the HUD to change the cursor graphics to pointing
arrows for easier visu al clarity. The graphics are stored as Texture2D values in the HUD object.
To draw the custom cursors, the default Windows cursor must not be visible. The draw position
of the cursor can be anywhere, so we define the GUI group as covering the entire area o f the
screen. The position to draw the cursor is easily determined : same position the default cursor but
we must also take into consideration the screen coordinates as discussed in Chapter 2.4,
otherwise the movement on the Y axis are inverted.
private void DrawMouseCursor()
{
Cursor.visible = false;
GUI.BeginGroup( new Rect(0f, 0f, (float)Screen.width, (float)Screen.height));
Rect cursorDrawPosition = GetCursorDrawPosition();
GUI.DrawTexture(cursorDrawPosition, activeCursor);
GUI.EndGroup();
}

private Rect GetCursorDrawPosition()
{

31
Vector3 mousePosition = Input.mousePosition;
float x = mousePosition.x;
float height = (float)Screen.height;
Vector3 mousePosition2 = Input.mousePosition;
float y = height – mousePosition2.y;
return new Rect(x, y, (float)activeCursor.width, (float)activeCursor.height);
}

Finally, other methods are free to call the SetCursorState method in order to set the cursor
graphic as needed.

public void SetCursorState( CursorState newState)
{
activeCursorState = newState;
switch (newState)
{
case CursorState .Main:
activeCursor = mainCursor;
break;
case CursorState.PanUp:
activeCursor = upCursor;
break;
case CursorState .PanRight:
activeCursor = rightCursor;
break;
case CursorState .PanDown:
activeCursor = downCursor;
break;
case CursorState .PanLeft:
activeCursor = leftCursor;
break;
}
}

32
3.6.2 Resource Bar
The resource bar occupies the top part of the screen and gives information regarding the player’s
amount of resources.
Firstl y the background of the bar is drawn. It is a rectangle occupying the top part of the screen.
Every type of resource has an icon and a player has both a quantity of a resource and a limit to
how many resources of that type can be gathered.
Some padding is added for aesthetic reasons and the resource icon , values and limits are drawn
onto the box.

private void DrawResourceBar()
{
GUI.skin = resourceSkin;
float width = (float)Screen.width;
GUI.BeginGroup( new Rect(0f, 0f, (float)Screen.width, 40f));
GUI.Box(new Rect(0f, 0f, (float)Screen.width, 40f), string.Empty);
int topPadding = 5;
double leftPadding = (double)Screen.width * 0.85;
DrawResource( ResourceName .Money, topPadding, (int)leftPadding);
GUI.EndGroup();
}

private void DrawResource( ResourceName type, int topPadding, int leftPadding)
{
Texture2D image = resourceImages[type];
string text = resourceValues[type].ToString() + "/" + resourceLimits[type].To
String();
GUI.DrawTexture( new Rect((float)leftPadding, (float)topPadding, (float)System
Data.resourceIconWidth, (float)SystemData .resourceIconHeight), image);
GUI.Label(new Rect((float)leftPadding, (float)topPadding, 128f, 32f), text);
}

33
3.6.3 Orders Bar
The Orders bar is drawn on the bottom of the screen. It contains information regarding the
currently selected unit. For units, the only values drawn are its name, hit points and owner
player. Buildings also contain their unit creation buttons on this bar. Two buttons can be drawn
on each column. The modulus 2 operation is used to determine the row of the button, while
padding is used to place sufficient space between the buttons for aesthetic reasons.
private void DrawOrdersBar()
{
GUI.skin = ordersSkin;
ordersBarY = (double)Screen.height * 0.75;
ordersBarHeight = (double)Screen.height – ordersBarY;
actionButtonsX = (double)Screen.width * 0.25;
GUI.BeginGroup( new Rect(0f, (float)ordersBarY , (float)Screen.width, (float)or
dersBarHeight));
GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)ordersBarHeight), string
.Empty);
if (player.SelectedObject)
{
string objectName = player.SelectedObject.objectName;
if (!objectName.Equals( string.Empty))
{
int hitPoints = player.SelectedObject.hitPoints;
int maxHitPoints = player.SelectedObject.maxHitPoints;
string text = hitPoints + " / " + maxHitPo ints;
GUI.Label(new Rect(0f, 0f, 64f, 30f), objectName);
GUI.Label(new Rect(0f, 20f, 64f, 30f), text);
GUI.Label(new Rect(0f, 40f, 64f, 30f), player.username);
}
if (player.SelectedObj ect.IsOwnedByPlayer(player))
{
DrawActions(player.SelectedObject.GetActions());
lastSelection = player.SelectedObject;
}
}
GUI.EndGroup();
}

private void DrawActions( string[] actions)
{
int length = actions.Length;
int padding = SystemData .portraitIconWidth + 100;
for (int i = 0; i < length; i++)
{
int column = i / 2;
int row = i % 2;
Rect position = new Rect((float)(padding + column * 10 + column * SystemD
ata.portraitIconWidth), (float)(row * 10 + row * SystemData .portraitIconHeight), (flo
at)SystemData .portraitIconWidth, (float)SystemData .portraitIconHeight);
Texture2D buildImage = SystemData .GetBuildImage(actions[i]);
if (GUI.Button(position, buildImage))
{
player.SelectedObject.PerformAction(actions[i]);

34
}
}
}

3.6.4 Pause Menu
By pressing Escape, the player pauses the game. To s top time passing in the game while the
game is paused, the time scale used by Unity can be set to 0.

Fig. 3.6.4 . The Pause Menu (center)
The action buttons are stored in a string array .
private string[] actions = { "Resume Game", "Quit to Main Menu", "Exit Game" };

Using the formula discussed in Chapter 2.4 (fig. 2.4.2) , we can place the menu at the exact
center of the screen while keeping in mind the dynamic nature of the menu :
height = buttonHeight * actions.Length + 2*paddingY;
width = buttonWidth + 2*paddingX;
startX = (Screen.width – width) * 0.5;
startY = (Screen.height – height) * 0.5;

When drawing the buttons within the menu, we can set their actions as needed in a switch
statement:
foreach(string action in actions) {
if(GUI.Button( new Rect(paddingX, paddingY + buttonHeight * System.Array.I
ndexOf(actions, action), buttonWidth, buttonHeight), action)) {
switch(action) {
case "Resume Game": {
Resume();
break;
}

35
case "Quit to Main Menu": {
QuitToMainMenu();
break;
}
case "Exit Game": {
ExitGame();
break;
}
default: {
break;
}
}
}
}

36
Chapter 4 . System Demo
The system demo was conceived a s a way to showcase the Real -Time Strategy Game system and
its current usability .
4.1 The Main Menu

Fig. 4.1.1 The Main Menu
The first screen that the user sees when loading the application is the main menu. The screen
consists of two UI elements groupe d separately: the title and a menu consisting of two buttons,
labelled “Start Game” and “Exit Game” respectively . Drawing the main menu is similar to
drawing the pause menu as discussed in Chapter 3.6.4 . Upon pressing the Start Game button,
the player will be loaded into the game map proper.

37
4.2. Game Map

Fig. 4.2.1 . Initial conditions
The sample map provided with the demo consists of a Player with $150 in resources, a Factory
which can build Tanks and Workers, and 3 resource nodes of $1000 each. As the cost of a Tank
is $250, more than the player starts with, the only way for the player to build any tanks is to start
by creating a worker then use it to gather more resources. For faster gathering, more workers can
be used.

Fig. 4.2.2 . Final state, with a ll resources mined, 2 workers and 12 tanks

38
Because of the data -driven approach of the system, creating this map in the Unity Editor was
possible in an accessible way . Several assets were created beforehand: the prefabs for the Tank,
Worker, Factory and Res ourceNode, and their corresponding textures and portrait icons. The
Player is created as an Empty Object, and the scripts handling the Player and UserInput classes
are attached. The following Objects must be added as children for the Player: HUD , Units and
Buildings, all with their own scripts. For the Pause Menu to work when the user presses Escape,
an Empty Object under HUD must be placed under HUD with the PauseMenu script attached.
The ObjectList object is another Empty Object with its own script , into which we add the prefabs
for all available WorldObject types in our game.
Finally, the Factory is added under the player’s control and several resource nodes are placed.

Fig. 4.2.3 . Hierarchy view in the project editor showing all the used components

39

40
Chapter 5 . Conclusion
5.1 Achievements
With the development of this system, I have managed to build almost from scratch a basic, bare –
bones version of an RTS game while lacking the resources that most game development studios
have at their disposal .
The algorithms in place will require few adjustments to accommodate future features as I have
mostly used a data -driven approach to preserve the system’s extensibility.
My hopes for the system is that when it will have reached sufficient maturity to be rele ased as a
free toolkit for creating RTS games much in the same vein as other toolkits do for other genres,
such as Adventure Game Studio for graphical point -and-click adventure games or RPG Maker
for Role -Playing Games.
5.2 Future Developments
Because the system presented in this Bachelor’s Thesis will undergo future development, there
are several critical points to implement which will improve this system :
1. Several features that have been staples of the RTS genre are lacking from this system.
These include :
• Networking play
• Combat
• Artificial Intelligence
• Different types of t errain
• Fog of war
• Minimap
2. A single -player campaign spanning multiple Scenes against AI -controlled enemies, in
order to showcase all the available features of the system
3. A more readily av ailable way to edit certain values such as unit names, their cost, or
other attributes so that they are loaded at run -time instead of compile -time. This could
be easily handled by storing this value into a text file which can be easily readable
and editabl e as a human and for which a reader class can be easily implemented, such
as .json or .xml.

41

Bibliography
[1] Peter A. Piccione, “In Search of the Meaning of Senet ”, [Online:
https://web.archive.org/web/20080918080211/http://www.gamesmuseum.uwaterloo.ca/Archives
/Piccione/index.html ]
[2] Roger Smith, “The Long History of Gaming in Military Training”, [Online:
http://www.dtic.mil/dtic/tr/fulltext/u2/a550307.pdf ]
[3] Laurence Kay, “Kriegsspiel – The 19th Century War Game That Changed History”,
[Online: https://militaryhistorynow.com/2018/05/01/kriegsspiel -the-19th-century -war-game -that-
changed -history/ ]
[4] Alexander Smith, “Tennis Anyone?”, They Create Worlds , [Online:
https://web.archive.org/web/20151225121214/https://videogamehistorian.wordpress.com/2014/0
1/28/tennis -anyone ]
[5] The National Museum of American His tory, “Magnavox Odyssey Video Game Unit,
1972 ” , [Online: http://americanhistory.si.edu/collections/search/object/nmah_1302004 ]
[6] D.S. Cohen, “Magnavox Odyssey – The F irst Gaming Console”, Lifewire. [Online:
https://www.lifewire.com/magnavox -odyssey -the-first-gaming -console -729587 ]
[7] Ellen Wojahn, “The General Mills/Parker Brot hers merger: playing by different rules”,
Beard Books. p. 120
[8] Scott Sharkey, “Hail to the Duke ”, 1Up, [Online:
https://archive.is/20120604112047/http ://www.1up.com/features/essential -50-herzog -zwei ]
[9] Jonathan Leack, “ World of Warcraft Leads Industry With Nearly $10 Billion In
Revenue ”, GameRevolution, [Online: http://www.gamerevolution.com/features/13510 -world -of-
warcraft -leads -industry -with-nearly-10-billion -in-revenue ]
[10] Kris Graft, “Blizzard Confirms One "Frontline Release" for '09” , [Online:
https://web.archive.org/web/20100825135123/http://www.next -gen.biz/news/blizzard -confirms –
one-frontline -release -09 ]
[11] Brian Ashcraft, “Why Is Starcraft So Popular In Korea”, Kotaku, [Online:
https://kotaku.com/5595262/why -is-starcraft -so-popular -in-korea ]

Similar Posts