7. Tech Design Document - DevCrumbs/Warcraft-II GitHub Wiki

Warcraft II: The Stolen Artifacts
DevCrumbs
06/06/2018
TDD v1.0

Main Index

Introduction

This is the Tech Desing document for Warcraft II: The Stolen Artifacts. We will develop this projuect using C++ and SDL

Technical goals

  • Randomly generated map
  • 2D ortogonal world
  • Resouce managment
  • Control of allies
  • RTS battle sistem

Target Platform

Hardware Requirements
CPU Intel Core i7-2720QM @ 2.2GHz ( 8 CPUs)
GPU nVidia 4200M
RAM 8192 MB
Free disk space 200 MB
SO Windows 10 Enterprise

External Tools to develop

We will use Visual Studio Community 2017 v15.5.6, paint.net v4.0.19 and Tiled .

Branching

We will have 3 main active branches: Master, Bug fixes and development

In the development branch we will, for every new feature implemented in the game, create a new branch to avoid conflicts between two different features that are being implemented at the same time. This development branches will always merge and pull from Development.
Before pulling to Development you have to chek the code compiles and does not crash.
The only pushes that can be done in development branch are non-code related commits.
Once we have all the features implemented, we'll push from Development to Master.
All releases will be on Master. If a bug is found in a release we will use the bug fix branch. Here, no new features will be implementeted, only bug fixing. Once the bug is fixed we will push to Master (creating a new release) and to Development.

GitHub branching diagram

Code Style Guidelines

1. Naming Conventions

  • All names should be written in English.
  • Use Get/Set to get or set variables, do not use synonyms.
  • Names must never have dual meaning, to ensure all concepts are represented uniquely.
  • Indentation:

if (isOpen)
	Close()
for (int i = 0; i < points; ++i)
{
	// Do things
}

Variables: must be in mixed case, starting with lower case.

  • Single name:
speed
  • Compound name:
cameraShake
  • Temporal variables (only used in a few lines of code) should have short names, whilst long-term variables (used multiple times along the code) can have long names.
  • Temporal variable:
m
  • Long-term variable:
cameraShake
  • Generic variables: should have the same name as their type.
void SetState(PlayerState* playerState)

Enums: Must be all uppercase using underscore to separate words and in singular.

PLAYER_STATE_MACHINE
  • Enums items: must start with the name of the enum, followed by the name of the item. The name of the item must be in uppercase.
STATE_IDLE
STATE_TURN_RIGHT
  • If the name of the enum is long and composed, the elements can start with a shortening of the enum, followed by the name of the item. The name of the item must be in uppercase.
PSM_IDLE
PSM_TURN_RIGHT
  • When creating a variable of the type enum, call it as the enum.
PLAYER_STATE playerState;
  • When referring to an enum item, simply write its name.
playerState = PLAYER_STATE_IDLE`

Constants: Must be all uppercase using underscore to separate words.

  • Also applies to define variables
MOVEMENT_SPEED

Functions and methods:

  • Must be a short explanation of what the function or method does and must be written in mixed cade starting with uppercase
LoadMap()
  • Keep in mind the object the function or method is referred to is implicit and should be avoided in the function or method.
player.GetState();
  • Names representing a collection of numbers must be in plural
int values[];
  • Bool variables should use the is prefix
bool isSet, isVisible, isOpen;

File content must be kept within 160 columns. If you need more columns split the code onto 2 or more lines. Keep in easy to read.

  • You can break:
    • After a comma
    • After an operator Align the new line with the beginning of the expression on the previous line.
for (int table = 0; table < nTables;
     table += tableStep) {
if ((c1.type == COLLIDER_ARROW && c2.type == COLLIDER_IMP) ||
    (c1.type == COLLIDER_ARROW && c2.type == COLLIDER_IMP))

Includes:

  • Should be grouped by their hierarchical position in the system with low levels files first. Leave an empty line between groups of include statements.
#include <iostream>

#include "SDL\include\SDL_rect.h"

#include “map.h”
#include “player.h”

Iterator variables:

  • If the variable is a number, use i, (and j, k for nested loops):
for (int i = 0; i < points; ++i)
for (int j = 0; j < points; ++j)
  • Else, use the standard naming convention:
for (pugi::node animationsNode = node.child(“animation”); animationsNode;
     animationsNode.next_sibling(“animation”))

Number variables:

  • If iterators, increase/decrease them using ++variable/--variable.
++i
  • Else, increase/decrease them using variable++/variable--.
speed++

Whitespace:

  • Use space to improve readability. Add space between operators and operands, commas, and semicolons, and colons. Add space on the outside of parentheses and brackets .
a = (b + c) * d
while (true)
doSomething(a, b, c, d)
for (i = 0; i < 10; i++)
  • Same applies to functions/methods and initialization of variables
App->render->DrawQuad({ 1000, 10, 3, 13 }, 255, 255, 255, 255);
SDL_Rect rect{ 1, 1, 1, 1 }
GetProperty("Draw", false)

Parentheses:

  • In compound arithmetic expressions add parentheses, even if they don’t change order of operations.
a = (b * c) + (d / e) - (f % g)
  • In Boolean expressions you should add parentheses around sub-expressions.
if ((x + (2 * y) > z) || (p < q))

Between Lines:

  • Add one blank line between each logical block of code.
Matrix4x4 matrix = new Matrix4x4();

double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);

matrix.setElement(1, 1, cosAngle);
matrix.setElement(1, 2, sinAngle);
matrix.setElement(2, 1, -sinAngle);
matrix.setElement(2, 2, cosAngle);

multiply(matrix);

Comments:

  • Put a descriptive comment before a logical block of code. Use // comments rather than /* ... */ comments.
// do X
...
  • In variables comments use // in the same line.
int player //Player x coordinate

2. Variables

  • Never use magic numbers!
speed = MAX_SPEED
speed = maxSpeed
  • If there is more than one variable of the same type, declarate them in the same line.
int i, j, k, l
  • After its declaration, always initialize them.
    • Pointers must be initialized with default nullptr (over NULL).
char* name = nullptr
  • Floating numbers must be initialized with default 0.0f.
float speed = 0.0f
  • Integer and unsigned integer numbers must be initialized with default 0.
int childs = 0
  • Booleans must be initialized with true or false.
bool isChild= true
  • Minimize the use of global variables.

Pointers and references:

  • should have their reference symbol next to the type rather than to the name.
char* name = nullptr`

Classes:

  • It is preferred to use private (or protected) variables and access functions instead of public variables, which violate the encapsulation concept (hiding information).

Structs:

  • It is preferred to use global variables.

3. Loops

  • do-while loops can be avoided.
  • Only use break and continue if they give higher readability.

Infinite loops:

  • Use the while(true) form
while (true)

4. Conditionals

  • If: when using ifs avoid the use of operators whenever possible
if (isOpen) {}
if (!isOpen) {}
  • the conditional should be put on a separate line
if (isOpen)
	Close()

  • When working with booleans, put their true form in the if-part and leave the negative one for the else-part.
if (isOpen)
	Close()
else
	Open()
  • If there is only one sentence after the if-else statement, don’t use brackets.
if (isOpen)
	Close()
else
	Open()
if (isHit) {
	speed--;
	ApplySpeed();
}



if (isHit) {}
else if (!isHit) {}

5. Classes and structs

Use a struct when the class is essentially a data structure.

  • Class elements must be written in this order
Class SomeClass {
public:
	constructor and destructor
	public functions and methods
private:
	private functions and methods

public:
	public variables
private: 
private variables

};

XML

  • Booleans: must be 0 or 1.
  • XML data structure

Animations:

<animations>
	<idle speed=“10” loop=“1”>
		<frame x=“1” y=“454” w=“48” h=“48”/>
		<frame x=“50” y=“454” w=“48” h=“48”/>
	</idle>
</animations>

Map types:

<map type="0">
	<rooms>
		<room type="0" y="0" x="0">
			<doors>
				<door direction="0"/>
				<door direction="1"/>
				<door direction="2"/>
			</doors>
		</room>

		<room type="1" y="0" x="0">
			<doors>
				<door direction="0"/>
			</doors>
		</room>

		<room type="0" y="0" x="0">
			<doors>
				<door direction="0"/>
				<door direction="1"/>
				<door direction="2"/>
				<door direction="3"/>
			</doors>
		</room>

	</rooms>
</map>

UML

The following UML provides an overview of the structure of the code. However, the UML, such as the rest of this document, is expected to evolve. Later in the development, we will extend it with specific class UMLs - one for the EntityFactory and one for the Gui.

General UML for the game

Target hardware

UPC CITM Computers

Hardware Recommended requirements Minimum requirements
CPU Intel Core i7-2720QM @ 2.2GHz ( 8 CPUs) Intel Core i3
GPU nVidia 4200M Integred
Free RAM 100 MB 100 MB
Free disk space 200 MB 200 MB
SO Windows 10 Windows 10

Performance budged

The game will run at 60 frames per second.

Data Layout

We will have all the game files inside the game folder. Inside the game folder there will be all the dlls and the data folder.

Inside the data folder there will be assets, maps and save games.

Assets will be distributed in textures and sounds. Textures in map textures and sprites. Sounds in fx and music.
In the map folder will be 2 more folders, one for map types and the other for the rooms (distributed in diferent pulls).
In the save game folder will be all the saved games.

Version list

0.1

Camera movement
Player base
Enemy base

0.2

Random generated map system
Colliders
Player troops

0.3

Pathfinding
Group movement

0.4

UI Menu
Allies random spawn

0.5

Enemies random spawn
Enemies AI

0.6

Battle sistem
Minimap

0.7

Fog of war
Portal and Hero Location

0.8

Boss
New characters

0.9

Polish
Bugs fixed

1.0

Last bugs fixed

External libraries

We will be using STL and SDL libraries, also brofiller.

Build delivery method.

We will be using AppVeyor to draft a new release on every commit in the Development branch, as the commits in the Development branch will always be a new feature implemented, we will have a release for every feature implemented.

< Previous | Next >

⚠️ **GitHub.com Fallback** ⚠️