diff --git a/.gitignore b/.gitignore
index 9db3cfb0b35c9ac31228ab865721650dd0e9512f..a31d6a524eab9912473012be6b823a3416fbbf94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,7 @@ lerna-debug.log*
 # db connection
 .env
 *.providers.ts
+
+# uploads
+images/*
+!images/default.jpeg
diff --git a/images/default.jpeg b/images/default.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..7e5e656834bfa61b0fc135c94d1fb9089596f2f6
Binary files /dev/null and b/images/default.jpeg differ
diff --git a/src/app.controller.ts b/src/app.controller.ts
index cce879ee622146012901c9adb47ef40c0fd3a555..045e5b1ae398cd994ada21cd7f9512b475af30ec 100644
--- a/src/app.controller.ts
+++ b/src/app.controller.ts
@@ -1,4 +1,4 @@
-import { Controller, Get } from '@nestjs/common';
+import { Controller, Get, Param, Res } from '@nestjs/common';
 import { AppService } from './app.service';
 
 @Controller()
@@ -9,4 +9,9 @@ export class AppController {
   getHello(): string {
     return this.appService.getHello();
   }
+
+  @Get('images/:id')
+  returnImage(@Param('id') id, @Res() res) {
+    return;
+  }
 }
diff --git a/src/app.module.ts b/src/app.module.ts
index 53a56f466f39eb0e799f5c1c56f9906f9220a102..05685cd88382fd6e6e29caadfbab83b0c658d953 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -2,15 +2,12 @@ import { Module } from '@nestjs/common';
 import { APP_FILTER, APP_INTERCEPTOR, APP_GUARD } from '@nestjs/core';
 import { TypeOrmModule } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
-
 import { AppController } from './app.controller';
 import { AppService } from './app.service';
-
 import { RolesGuard } from './shared/roles.guard';
-import { LoggingInterceptor } from './shared/logging.interceptor';
+//import { LoggingInterceptor } from './shared/logging.interceptor';
 import { StatesGuard } from './shared/states.guard';
 import { HttpErrorFilter } from './shared/http-error.filter';
-
 import { NotificationModule } from './notifications/notifications.module';
 import { TaskModule } from './task/task.module';
 import { TrackingModule } from './tracking/tracking.module';
@@ -20,6 +17,27 @@ import { FactionModule } from './faction/faction.module';
 import { GameModule } from './game/game.module';
 import { ScoreModule } from './score/score.module';
 import { ReplayModule } from './replay/replay.module';
+import { TickModule } from './tick/tick.module';
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+///   Core of the server,                                                                               ///
+///   Every module is being imported and combined here.                                                 ///
+///                                                                                                     ///
+///   AppController needs to be kept in for SSL verification to work (root needs to return something)   ///
+///                                                                                                     ///
+///  TypeOrmModule checks ormconfig.json for database connection.                                       ///
+///                                                                                                     ///
+///   More information on global decorators can be found from shared folder.                            ///
+///                                                                                                     ///
+///   Providers can be found from shared folder                                                         ///
+///    - HttpErrorFilter                                                                                ///
+///    - LoggingInterceptor                                                                             ///
+///    - RolesGuard Decorator                                                                           ///
+///    - StatesGuard Decorator                                                                          ///
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 @Module({
   imports: [
@@ -33,6 +51,7 @@ import { ReplayModule } from './replay/replay.module';
     TrackingModule,
     ScoreModule,
     ReplayModule,
+    TickModule,
   ],
   controllers: [AppController],
   providers: [
@@ -41,10 +60,7 @@ import { ReplayModule } from './replay/replay.module';
       provide: APP_FILTER,
       useClass: HttpErrorFilter,
     },
-    {
-      provide: APP_INTERCEPTOR,
-      useClass: LoggingInterceptor,
-    },
+
     {
       provide: APP_GUARD,
       useClass: RolesGuard,
diff --git a/src/draw/coordinate.entity.ts b/src/draw/coordinate.entity.ts
index e9a1b6ff35544fa599220367638fd3ada00fa865..da5e940a74b31a21479527b02b847aaeda9d950e 100644
--- a/src/draw/coordinate.entity.ts
+++ b/src/draw/coordinate.entity.ts
@@ -1,18 +1,13 @@
-import {
-  Entity,
-  Column,
-  PrimaryGeneratedColumn,
-  ManyToOne,
-  CreateDateColumn,
-  OneToMany,
-} from 'typeorm';
+import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from 'typeorm';
 
 import { GameEntity } from '../game/game.entity';
 import { FactionEntity } from '../faction/faction.entity';
 
-//////////////////////////////////////////////////////////////////////
-/// Entities for different drawings in game and their histories    ///
-//////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+/// MapDrawingEntity & MapDrawingHistoryEntity reflect database tables. ///
+///                                                                     ///
+/// MapDrawing ownershipCheck checks users rights to MapDrawing         ///
+///////////////////////////////////////////////////////////////////////////
 
 @Entity('MapDrawing')
 export class MapDrawingEntity {
@@ -20,7 +15,7 @@ export class MapDrawingEntity {
   @Column({ type: 'bool', nullable: true }) drawingIsActive: boolean;
   @Column({ type: 'json', nullable: true }) data: JSON;
 
-  // When Faction or game that has the drawing in question is deleted from 
+  // When Faction or game that has the drawing in question is deleted from
   // the database, the drawing is also deleted
   @ManyToOne(type => FactionEntity, faction => faction.mapDrawings, {
     onDelete: 'CASCADE',
diff --git a/src/draw/draw.controller.ts b/src/draw/draw.controller.ts
index 08b493940ff0b802a664c4bf5e54d797bf7690f4..d66bebe1ffe091fcda211a64f2b4b49601dd75b1 100644
--- a/src/draw/draw.controller.ts
+++ b/src/draw/draw.controller.ts
@@ -13,7 +13,7 @@ import {
 import { DrawService } from './draw.service';
 import { Roles, GameStates } from '../shared/guard.decorator';
 import { MapDrawingDTO } from './mapdrawing.dto';
-import { GamePerson } from 'src/game/gameperson.decorator';
+import { GamePerson } from '../game/gameperson.decorator';
 
 //////////////////////////////////////////////////////////////////////////
 ///     DrawController                                                 ///
@@ -24,14 +24,14 @@ import { GamePerson } from 'src/game/gameperson.decorator';
 ///     MapDrawingDTO data to database.                                ///
 ///     Data return functions require atleast spectator role.          ///
 //////////////////////////////////////////////////////////////////////////
-  
+
 @Controller('draw')
 export class DrawController {
   constructor(private drawService: DrawService) {}
 
   @Put('mapdrawing/:id')
   @Roles('admin', 'factionleader')
-  @GameStates('CREATED', 'STARTED')
+  @GameStates('CREATED', 'STARTED', 'PAUSED')
   @UsePipes(new ValidationPipe())
   async draw(
     @GamePerson() gameperson,
diff --git a/src/draw/draw.module.ts b/src/draw/draw.module.ts
index bea1b669ffdde53e107179b3379711321a28aceb..f03fc3acf1657620259eab31621c81f72ded7d46 100644
--- a/src/draw/draw.module.ts
+++ b/src/draw/draw.module.ts
@@ -15,6 +15,7 @@ import { NotificationModule } from 'src/notifications/notifications.module';
 /// Draw                                                          ///
 /// - contains everything to do with mapdrawing data.             ///
 /////////////////////////////////////////////////////////////////////
+
 @Module({
   imports: [
     TypeOrmModule.forFeature([
diff --git a/src/draw/draw.service.ts b/src/draw/draw.service.ts
index 5f7566cda9d127173cbba11a8f2f92727a38f7dc..da4b239dd5ef98c1572b5e64ff52525cd9f16e38 100644
--- a/src/draw/draw.service.ts
+++ b/src/draw/draw.service.ts
@@ -9,6 +9,10 @@ import {
 import { MapDrawingDTO } from './mapdrawing.dto';
 import { NotificationGateway } from '../notifications/notifications.gateway';
 
+///////////////////////////////////////////////////////////////////////////
+/// DrawService contains handling of MapDrawings and MapDrawinghistory  ///
+///////////////////////////////////////////////////////////////////////////
+
 @Injectable()
 export class DrawService {
   constructor(
@@ -30,13 +34,7 @@ export class DrawService {
       drawing.faction = gameperson.faction;
       const mapDrawing = await this.mapDrawingRepository.insert(drawing);
       // create a history entity and insert it
-      const history = await this.mapDrawHistoryRepository.create({
-        data: data.data,
-        drawingIsActive: data.drawingIsActive,
-        mapdrawing: mapDrawing.identifiers[0]['mapDrawingId'],
-        timestamp: Date.now(),
-      });
-      await this.mapDrawHistoryRepository.insert(history);
+      await this.createHistory(data, gameperson, mapDrawing);
       return mapDrawing.identifiers;
     }
     // get ref from db
@@ -46,13 +44,7 @@ export class DrawService {
     });
     if (await draw.ownershipCheck(gameperson.faction, gameperson.role)) {
       // else update the existing instance
-      const history = await this.mapDrawHistoryRepository.create({
-        data: data.data,
-        drawingIsActive: data.drawingIsActive,
-        mapdrawing: data.mapDrawingId,
-        timestamp: Date.now(),
-      });
-      await this.mapDrawHistoryRepository.insert(history);
+      await this.createHistory(data, gameperson);
       return await this.mapDrawingRepository.save(drawing);
     }
 
@@ -62,6 +54,22 @@ export class DrawService {
     );
   }
 
+  // used to create mapDrawing history entity entry
+  private async createHistory(data, gameperson, mapDrawing?) {
+    // create a history entity and insert it
+    const history = await this.mapDrawHistoryRepository.create({
+      data: data.data,
+      drawingIsActive: data.drawingIsActive,
+      mapdrawing:
+        data.mapDrawingId || mapDrawing.identifiers[0]['mapDrawingId'],
+      timestamp: Date.now(),
+    });
+    history.data['faction'] = gameperson.faction
+      ? gameperson.faction.factionName
+      : 'admin';
+    await this.mapDrawHistoryRepository.insert(history);
+  }
+
   // draw map based on game and gameperson faction
   async drawMap(gameperson, gameId) {
     // return all active drawings if admin
diff --git a/src/faction/faction.controller.ts b/src/faction/faction.controller.ts
index 60ae33a221877101150967cc424aea3a4bf34360..5eb905cb17b45b451720b0a021bc2ed877ece4ac 100644
--- a/src/faction/faction.controller.ts
+++ b/src/faction/faction.controller.ts
@@ -7,8 +7,6 @@ import {
   Body,
   Get,
   Put,
-  UseInterceptors,
-  ClassSerializerInterceptor,
   Delete,
 } from '@nestjs/common';
 
@@ -24,7 +22,24 @@ import {
 } from './faction.dto';
 import { FactionService } from './faction.service';
 import { Roles, GameStates } from '../shared/guard.decorator';
-import { GamePerson } from 'src/game/gameperson.decorator';
+import { GamePerson } from '../game/gameperson.decorator';
+
+/////////////////////////////////////////////////////////////////////////////////
+/// FactionController is being used for routing:                              ///
+///                                                                           ///
+/// Group                                                                     ///
+/// - create group when game status is CREATED                                ///
+/// - getting groups with faction id(this is used mainly for listing players) ///
+/// - joining group when game status is CREATED                               ///
+///                                                                           ///
+/// Faction                                                                   ///
+/// - checking users faction                                                  ///
+/// - joining faction                                                         ///
+/// - leaving faction                                                         ///
+/// - changing faction multiplier (not implemented)                           ///
+///                                                                           ///
+/// See shared folder files for more information on decorators.               ///
+/////////////////////////////////////////////////////////////////////////////////
 
 @Controller('faction')
 export class FactionController {
@@ -40,9 +55,7 @@ export class FactionController {
     @Param('id') id: string,
     @Body() data: GameGroupDTO,
   ) {
-    try {
-      return this.factionservice.createGroup(person, id, data);
-    } catch (error) {}
+    return this.factionservice.createGroup(person, id, data);
   }
 
   // id is faction ID
@@ -63,12 +76,6 @@ export class FactionController {
     return this.factionservice.joinGroup(gameperson, data);
   }
 
-  @UseInterceptors(ClassSerializerInterceptor)
-  @Get('get-faction-members/:id')
-  async getFactionMembers(@Param('id') factionId) {
-    return this.factionservice.listFactionMembers(factionId);
-  }
-
   // param game ID is passed to @Roles
   @Put('promote/:id')
   @Roles('admin')
@@ -82,7 +89,7 @@ export class FactionController {
   // :id is the id of the game, and is needed for GameStates to check the state of the game
   @Put('join-faction/:id')
   @UseGuards(new AuthGuard())
-  @GameStates('CREATED', 'STARTED')
+  @GameStates('CREATED', 'STARTED', 'PAUSED')
   @UsePipes(new ValidationPipe())
   joinFaction(
     @User('id') person,
@@ -100,13 +107,15 @@ export class FactionController {
   leaveFaction(@GamePerson('gamepersonId') gamepersonId) {
     return this.factionservice.leaveFaction(gamepersonId);
   }
+
   // used to change factions multiplier
-  @Put('faction-multiplier/:id')
-  @Roles('admin')
-  @GameStates('STARTED')
-  factionMultiplier(@Param('id') game, @Body() body: FactionDTO) {
-    return this.factionservice.changeFactionMultiplier(body);
-  }
+  // not implemented in frontend uncomment this and services equivalent when needed
+  // @Put('faction-multiplier/:id')
+  // @Roles('admin')
+  // @GameStates('STARTED')
+  // factionMultiplier(@Param('id') game, @Body() body: FactionDTO) {
+  //   return this.factionservice.changeFactionMultiplier(body);
+  // }
 
   // check if person belongs to a faction in a game
   @Get('check-faction/:id')
diff --git a/src/faction/faction.dto.ts b/src/faction/faction.dto.ts
index fbc46d3267dc109010c4450a371ede7300c0d1d0..511fce12d078c3c126641e62658540cbde7ae71b 100644
--- a/src/faction/faction.dto.ts
+++ b/src/faction/faction.dto.ts
@@ -13,10 +13,16 @@ import {
 } from 'class-validator';
 
 import { GameEntity } from '../game/game.entity';
-import { RoleValidation, Uuid } from '../shared/custom-validation';
 import { GameDTO } from '../game/game.dto';
 import { FactionEntity, GameGroupEntity } from './faction.entity';
 
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/// Contains Validation for FactionDTO, JoinFactionDTO, PromotePlayerDTO, GameGroupDTO, JoinGameGroupDTO  ///
+///                                                                                                       ///
+/// uses class-validator built in validations                                                             ///
+/// see https://github.com/typestack/class-validator                                                      ///
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 export class FactionDTO {
   @IsOptional()
   @IsUUID('4')
@@ -50,7 +56,7 @@ export class JoinFactionDTO {
 export class PromotePlayerDTO {
   @IsUUID('4')
   player: string;
-  @Validate(RoleValidation)
+  @IsIn(['admin', 'soldier', 'factionleader'])
   role: string;
 }
 
diff --git a/src/faction/faction.entity.ts b/src/faction/faction.entity.ts
index a851e190b349d046aae00c776aef345b7de6f373..20b4a0a28b1d6eba7bd24cb0e0bad3fdd518bdcc 100644
--- a/src/faction/faction.entity.ts
+++ b/src/faction/faction.entity.ts
@@ -12,11 +12,11 @@ import { GameEntity } from '../game/game.entity';
 import { Game_PersonEntity } from '../game/game.entity';
 import { MapDrawingEntity } from '../draw/coordinate.entity';
 import { Exclude } from 'class-transformer';
-import { ScoreEntity } from 'src/score/score.entity';
+import { ScoreEntity } from '../score/score.entity';
 
-//////////////////////////////////////////////////////////////////////
-/// Entities for Factions and Groups in Factions                   ///
-//////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///   FactionEntity & GameGroupEntity reflect database tables.  ///
+///////////////////////////////////////////////////////////////////
 
 @Entity('Faction')
 export class FactionEntity {
@@ -44,11 +44,6 @@ export class FactionEntity {
   })
   scores: ScoreEntity[];
 
-  factionObject() {
-    const { factionId, factionName, game } = this;
-    return { factionId, factionName, game };
-  }
-
   passwordCheck(pass: string) {
     return pass == this.factionPassword ? true : false;
   }
diff --git a/src/faction/faction.module.ts b/src/faction/faction.module.ts
index f53f076b7e88af7536e6307640d7e10414a7c357..3a3026da3695e79a7e375ea963cceee3360e048f 100644
--- a/src/faction/faction.module.ts
+++ b/src/faction/faction.module.ts
@@ -6,10 +6,19 @@ import { FactionService } from './faction.service';
 import { GameGroupEntity, FactionEntity } from './faction.entity';
 import { Game_PersonEntity } from '../game/game.entity';
 
-/////////////////////////////////////////////////////////////////////
-/// Faction                                                       ///
-/// - contains everything to do with Faction data.                ///
-/////////////////////////////////////////////////////////////////////
+/////////////////////////////
+/// Entities              ///
+/// - FactionEntity       ///
+/// - Game_PersonEntity   ///
+/// - GameGroupEntity     ///
+///                       ///
+/// Controllers           ///
+/// - FactionController   ///
+///                       ///
+/// Provider              ///
+/// - FactionService      ///
+/////////////////////////////
+
 @Module({
   imports: [
     TypeOrmModule.forFeature([
diff --git a/src/faction/faction.service.ts b/src/faction/faction.service.ts
index 32299861ea7b8a349b89194c7f51e3626b7f2389..9447c36777b01762a697bf75b38c36d14b34b4b8 100644
--- a/src/faction/faction.service.ts
+++ b/src/faction/faction.service.ts
@@ -11,6 +11,21 @@ import {
 } from './faction.dto';
 import { Game_PersonEntity } from '../game/game.entity';
 
+///////////////////////////////////////////////////////
+/// FactionService contains functions for           ///
+/// - Joining faction                               ///
+/// - Leaving faction                               ///
+/// - Change faction multiplier (not implemented)   ///
+///                                                 ///
+/// Group                                           ///
+/// - Creating group                                ///
+/// - List faction players in groups                ///
+///                                                 ///
+/// Player                                          ///
+/// - Promote player                                ///
+/// - verifying user                                ///
+///////////////////////////////////////////////////////
+
 @Injectable()
 export class FactionService {
   constructor(
@@ -67,13 +82,13 @@ export class FactionService {
   }
 
   // changes factions multiplier to the value given to FactionDTO
-  async changeFactionMultiplier(body: FactionDTO) {
-    const faction = await this.factionRepository.findOne({
-      where: { factionId: body.factionId },
-    });
-    faction.multiplier = body.multiplier;
-    return await this.factionRepository.save(faction);
-  }
+  // async changeFactionMultiplier(body: FactionDTO) {
+  //   const faction = await this.factionRepository.findOne({
+  //     where: { factionId: body.factionId },
+  //   });
+  //   faction.multiplier = body.multiplier;
+  //   return await this.factionRepository.save(faction);
+  // }
 
   async promotePlayer(body) {
     const gamepersonId = body.player;
@@ -132,10 +147,64 @@ export class FactionService {
 
   // get the groups in the given Faction
   async showGroups(factionId) {
-    return await this.game_GroupRepository.find({
-      relations: ['leader', 'players'],
+    let players = await this.game_PersonRepository.find({
       where: { faction: factionId },
+      relations: ['person', 'group'],
+    });
+
+    players.sort(function(a, b) {
+      return a.person.name.localeCompare(b.person.name);
     });
+
+    let groups = await this.game_GroupRepository.find({
+      where: { faction: factionId },
+      relations: ['leader', 'leader.person'],
+    });
+
+    let resObj = await Promise.all(
+      groups.map(async group => {
+        return await {
+          id: group.id,
+          name: group.name,
+          class: group.class,
+          leader: group.leader.person.name,
+          players: [],
+        };
+      }),
+    );
+
+    resObj.push({
+      id: 'empty-group-id',
+      name: 'No group',
+      class: 'infantry',
+      leader: '',
+      players: [],
+    });
+
+    await Promise.all(
+      players.map(async player => {
+        for (let i = 0; i < resObj.length; i++) {
+          if (player.group == null) {
+            resObj[resObj.length - 1].players.push({
+              gamepersonId: player.gamepersonId,
+              role: player.role,
+              name: player.person.name,
+            });
+            break;
+          }
+          if (resObj[i].name == player.group.name) {
+            resObj[i].players.push({
+              gamepersonId: player.gamepersonId,
+              role: player.role,
+              name: player.person.name,
+            });
+            break;
+          }
+        }
+      }),
+    );
+
+    return resObj;
   }
 
   // puts a non admin or faction leader player into a specified group
@@ -147,29 +216,18 @@ export class FactionService {
     };
   }
 
-  // lists all members from given faction
-  async listFactionMembers(faction) {
-    const members = await this.game_PersonRepository.find({
-      where: { faction },
-      relations: ['person'],
-    });
-    members.sort(function(a, b) {
-      return a['person']['name'].localeCompare(b['person']['name']);
-    });
-    return members;
-  }
-
   // checks if player is in a faction and what role the player is in
   async verifyUser(person, game) {
     const gameperson = await this.game_PersonRepository.findOne({
       where: { person, game },
-      relations: ['faction'],
+      relations: ['faction', 'group'],
     });
     if (gameperson && gameperson.faction) {
       return {
         factionId: gameperson.faction.factionId,
         factionName: gameperson.faction.factionName,
         role: gameperson.role,
+        group: gameperson.group ? true : false,
       };
     } else {
       return gameperson ? { role: gameperson.role } : { role: '' };
diff --git a/src/game/game.controller.ts b/src/game/game.controller.ts
index 27e3248368c7fa54c76db0cc114e66afdc445118..93068318edb8a99755c8cd44adaa795573888981 100644
--- a/src/game/game.controller.ts
+++ b/src/game/game.controller.ts
@@ -10,12 +10,17 @@ import {
   UseInterceptors,
   ClassSerializerInterceptor,
   Delete,
+  UploadedFile,
+  Res,
 } from '@nestjs/common';
+import { FileInterceptor } from '@nestjs/platform-express';
+import { diskStorage } from 'multer';
+import { extname } from 'path';
 
 import { GameService } from './game.service';
 import { AuthGuard } from '../shared/auth.guard';
 import { User } from '../user/user.decorator';
-import { GameDTO, FlagboxEventDTO, GameStateDTO } from './game.dto';
+import { GameDTO, FlagboxEventDTO, GameStateDTO, newGameDTO } from './game.dto';
 import { ValidationPipe } from '../shared/validation.pipe';
 import { Roles, GameStates } from '../shared/guard.decorator';
 import { GameEntity } from './game.entity';
@@ -33,13 +38,15 @@ import { GameEntity } from './game.entity';
 export class GameController {
   constructor(private gameservice: GameService) {}
 
+  //new game
   @Post('new')
   @UseGuards(new AuthGuard())
   @UsePipes(new ValidationPipe())
-  async newGame(@User('id') person, @Body() body: GameDTO) {
+  async newGame(@User('id') person, @Body() body: newGameDTO) {
     return this.gameservice.createNewGame(person, body);
   }
 
+  // edit game
   @Put('edit/:id')
   @Roles('admin')
   @GameStates('CREATED')
@@ -49,6 +56,7 @@ export class GameController {
     return this.gameservice.editGame(id, body);
   }
 
+  // delete game
   @Delete('delete/:id')
   @Roles('admin')
   @GameStates('CREATED')
@@ -56,6 +64,7 @@ export class GameController {
     return this.gameservice.deleteGame(id);
   }
 
+  // change game state
   @Put('edit-state/:id')
   @Roles('admin')
   @UsePipes(new ValidationPipe())
@@ -63,11 +72,13 @@ export class GameController {
     return this.gameservice.updateGameStatus(body);
   }
 
+  // list all games
   @Get('listgames')
   async listGames(state) {
     return this.gameservice.listGames(state);
   }
 
+  // list games based on parameter
   @Get('listgames/:state')
   async listGamesState(@Param('state') state: string) {
     return this.gameservice.listGames(state);
@@ -80,20 +91,57 @@ export class GameController {
     return this.gameservice.returnGameInfo(id);
   }
 
+  //get all factions
   @Get('get-factions/:id')
   @Roles('admin')
   async returnGameFactions(@Param('id') id: GameEntity) {
     return this.gameservice.listFactions(id);
   }
 
+  // get flagbox events
+  @Get('flag-events/:id')
+  async returnFlagboxInfo(@Param('id') id: GameEntity) {
+    return this.gameservice.returnObjectivePointInfo(id);
+  }
+
+  // initial settings for flagbox
   @Get('flag/:id')
   async flagboxQuery(@Param('id') id: string) {
     return this.gameservice.flagboxQuery(id);
   }
 
+  // flagbox event
   @Post('flag/:id')
   @GameStates('STARTED')
   async flagboxEvent(@Param('id') id: string, @Body() data: FlagboxEventDTO) {
     return this.gameservice.flagboxEvent(id, data);
   }
+
+  // image upload
+  @Post('upload')
+  @UseInterceptors(
+    FileInterceptor('image', {
+      storage: diskStorage({
+        destination: './images',
+        filename: (req, file, cb) => {
+          // Generating a 32 random chars long string
+          const randomName = Array(32)
+            .fill(null)
+            .map(() => Math.round(Math.random() * 16).toString(16))
+            .join('');
+          //Calling the callback passing the random name generated with the original extension name
+          cb(null, `${randomName}${extname(file.originalname)}`);
+        },
+      }),
+    }),
+  )
+  uploadImage(@UploadedFile() image) {
+    return image;
+  }
+
+  // get images
+  @Get('images/:img')
+  returnImage(@Param('img') image, @Res() res) {
+    return res.sendFile(image, { root: 'images' });
+  }
 }
diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts
index abf1742d2af2bd9e10eed82b264217af11f96d8c..a5bb525ddc6c34a17da91787a4bf5027405099f2 100644
--- a/src/game/game.dto.ts
+++ b/src/game/game.dto.ts
@@ -4,7 +4,6 @@ import {
   Length,
   IsDateString,
   IsNumber,
-  Validate,
   Min,
   Max,
   ValidateNested,
@@ -15,7 +14,6 @@ import {
 } from 'class-validator';
 
 import { ObjectivePointEntity } from './game.entity';
-import { CenterJSON } from '../shared/custom-validation';
 import { FactionDTO } from '../faction/faction.dto';
 import { CenterDTO, NodeSettingsDTO } from './game.json.dto';
 import { Type } from 'class-transformer';
@@ -62,15 +60,19 @@ export class newGameDTO {
   @IsNotEmpty()
   @Length(1, 255)
   desc: string;
-  @IsNotEmpty()
-  @Validate(CenterJSON)
-  center: JSON;
+  @ValidateNested()
+  @Type(() => CenterDTO)
+  center: CenterDTO;
   @IsDateString()
   @IsNotEmpty()
   startdate: string;
   @IsDateString()
   @IsNotEmpty()
   enddate: string;
+  @Length(0, 65)
+  image: string;
+  @Allow()
+  map?: JSON;
 }
 
 export class GameStateDTO {
@@ -86,16 +88,18 @@ export class FlagboxDTO {
   objectivePointId: string;
   @IsString()
   @IsNotEmpty()
-  @Length(7)
+  @Length(7, 7)
   objectivePointDescription: string;
   @IsNumber()
   objectivePointMultiplier: number;
+  @IsOptional()
+  data: JSON;
 }
 
 export class FlagboxEventDTO {
   @IsString()
   @IsNotEmpty()
-  @Length(7)
+  @Length(7, 7)
   node_id: string;
   @IsNumber()
   @Min(0)
@@ -109,6 +113,6 @@ export class FlagboxEventDTO {
   @Min(0)
   @Max(3)
   capture: number; // which faction is capturing, same logic as in owner with numbers
-  oP_HistoryTimestamp?: string;
+  oP_HistoryTimestamp?: number;
   objective_point?: ObjectivePointEntity;
 }
diff --git a/src/game/game.entity.ts b/src/game/game.entity.ts
index 22e171b67e655917d108a66695dae59f32304e4e..56f3f3f6e2ffe341e6677e574bebf4b98b2b7be7 100644
--- a/src/game/game.entity.ts
+++ b/src/game/game.entity.ts
@@ -28,6 +28,7 @@ export class GameEntity {
   @Column('text') state: string;
   @Column('timestamp') startdate: Timestamp;
   @Column('timestamp') enddate: Timestamp;
+  @Column('text') image: string;
 
   @OneToMany(type => FactionEntity, factions => factions.game)
   factions: FactionEntity[];
@@ -83,25 +84,30 @@ export class ObjectivePointEntity {
   @PrimaryGeneratedColumn('uuid') objectivePointId: string;
   @Column({ type: 'text' }) objectivePointDescription: string;
   @Column({ type: 'float' }) objectivePointMultiplier: number;
+  @Column({ type: 'json' }) data: JSON;
 
-  // If the MapDrawing or Game where the ObjectivePoint was in is deleted, the ObjectivePoint is also deleted
-  @ManyToOne(type => MapDrawingEntity, coordinate => coordinate.data, {
-    onDelete: 'CASCADE',
-  })
-  coordinate: MapDrawingEntity;
+  // If the Game where the ObjectivePoint was in is deleted, the ObjectivePoint is also deleted
   @ManyToOne(type => GameEntity, game => game.objective_points, {
     onDelete: 'CASCADE',
   })
   game: GameEntity;
+  @OneToMany(
+    () => ObjectivePoint_HistoryEntity,
+    history => history.objective_point,
+    {
+      onDelete: 'NO ACTION',
+    },
+  )
+  history: ObjectivePoint_HistoryEntity[];
 }
 
 @Entity('ObjectivePoint_History')
 export class ObjectivePoint_HistoryEntity {
   @PrimaryGeneratedColumn('uuid') oP_HistoryId: string;
-  @Column({ type: 'timestamp' }) oP_HistoryTimestamp: Timestamp;
+  @Column({ type: 'float' }) oP_HistoryTimestamp: number;
   @Column('float') action: number;
 
-  // If the owner Faction, capturer Faction or ObjectivePoint, that has, is trying to have or is the point where 
+  // If the owner Faction, capturer Faction or ObjectivePoint, that has, is trying to have or is the point where
   // ObjectivePointHistory points to is deleted, the ObjectivePointHistory is also deleted
   @ManyToOne(type => FactionEntity, factionEntity => factionEntity.factionId, {
     onDelete: 'CASCADE',
diff --git a/src/game/game.module.ts b/src/game/game.module.ts
index 8fa0638e4a5ef0a0a72d04a416113c15278fc242..b30424ced696027a22d255e8618c90ad40209f29 100644
--- a/src/game/game.module.ts
+++ b/src/game/game.module.ts
@@ -13,14 +13,15 @@ import { PersonEntity } from '../user/user.entity';
 import { GameGroupEntity } from '../faction/faction.entity';
 import { FactionEntity } from '../faction/faction.entity';
 import { NotificationModule } from '../notifications/notifications.module';
-import { TickService } from './tick.service';
 import { ScoreService } from '../score/score.service';
-import { ScoreEntity } from 'src/score/score.entity';
+import { ScoreEntity } from '../score/score.entity';
+import { MulterModule } from '@nestjs/platform-express';
 
 /////////////////////////////////////////////////////////////////////
 /// Game                                                          ///
 /// - contains everything to do with Game data                    ///
 /////////////////////////////////////////////////////////////////////
+
 @Module({
   imports: [
     TypeOrmModule.forFeature([
@@ -34,8 +35,11 @@ import { ScoreEntity } from 'src/score/score.entity';
       ScoreEntity,
     ]),
     NotificationModule,
+    MulterModule.register({
+      dest: './images',
+    }),
   ],
   controllers: [GameController],
-  providers: [GameService, TickService, ScoreService],
+  providers: [GameService, ScoreService],
 })
 export class GameModule {}
diff --git a/src/game/game.service.ts b/src/game/game.service.ts
index 86bc61ef43c3255b83914cc08e2f1dcfae61bf90..1567d30a1c5aa751de2ef9b0dff4d18af7af94d4 100644
--- a/src/game/game.service.ts
+++ b/src/game/game.service.ts
@@ -1,4 +1,4 @@
-import { Injectable, HttpException, HttpStatus, Inject } from '@nestjs/common';
+import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
 import { InjectRepository } from '@nestjs/typeorm';
 import { Repository, Not } from 'typeorm';
 
@@ -8,11 +8,10 @@ import {
   ObjectivePointEntity,
   ObjectivePoint_HistoryEntity,
 } from './game.entity';
-import { GameDTO, FlagboxEventDTO, GameStateDTO } from './game.dto';
+import { GameDTO, FlagboxEventDTO, GameStateDTO, newGameDTO } from './game.dto';
 import { PersonEntity } from '../user/user.entity';
 import { FactionEntity } from '../faction/faction.entity';
 import { NotificationGateway } from '../notifications/notifications.gateway';
-import { TickService } from './tick.service';
 
 @Injectable()
 export class GameService {
@@ -30,11 +29,9 @@ export class GameService {
       ObjectivePoint_HistoryEntity
     >,
     private notificationGateway: NotificationGateway,
-
-    private tickService: TickService,
   ) {}
   // create a new game
-  async createNewGame(personId: PersonEntity, gameData: GameDTO) {
+  async createNewGame(personId: PersonEntity, gameData: newGameDTO) {
     // checks if a game with the same name exists already
     if (await this.gameRepository.findOne({ name: gameData.name })) {
       throw new HttpException('Game already exists', HttpStatus.BAD_REQUEST);
@@ -83,6 +80,14 @@ export class GameService {
         HttpStatus.BAD_REQUEST,
       );
     }
+    // check that there's location data for each added objective point
+    gameData.objective_points.forEach(obj => {
+      if (!obj['data'])
+        throw new HttpException(
+          'Objective Point error. Add location for each Objective Point.',
+          HttpStatus.BAD_REQUEST,
+        );
+    });
 
     // get factions that have been added previously
     let factions = await this.factionRepository.find({ game: id });
@@ -121,8 +126,10 @@ export class GameService {
         ({ objectivePointId }) => objectivePointId,
       );
       flagboxes.map(async flagbox => {
-        if (!flagboxIds.includes(flagbox.objectivePointDescription)) {
-          await this.objectivePointRepository.delete(flagbox);
+        if (!flagboxIds.includes(flagbox.objectivePointId)) {
+          await this.objectivePointRepository.delete({
+            objectivePointId: flagbox.objectivePointId,
+          });
         }
       });
       gameData.objective_points.map(async flagbox => {
@@ -131,13 +138,18 @@ export class GameService {
           game: gameId,
         });
         await this.objectivePointRepository.save(newFlagbox);
+        // create base status for flagbox
+        this.flagboxEvent(gameId, {
+          node_id: flagbox.objectivePointDescription,
+          owner: 0,
+          action: 0,
+          capture: 0,
+        });
       });
     } else {
       await this.objectivePointRepository.delete({ game: id });
     }
 
-    // TO DO: ADD FLAGBOX LOCATION TO MAPDRAWING ENTITY
-
     return {
       message: 'Game updated',
     };
@@ -147,16 +159,8 @@ export class GameService {
     const updatedGame = await this.gameRepository.findOne({ id: game.id });
     if (updatedGame) {
       updatedGame.state = game.state;
-      console.log(game.state);
       await this.gameRepository.save(updatedGame);
 
-      //add or remove from scoretick based on gamestate
-      if (game.state == 'STARTED') {
-        this.tickService.addGameToTimer(game.id);
-      } else {
-        this.tickService.removeGameFromTimer(game.id);
-      }
-
       // notify players about game state change
       this.notificationGateway.server.emit(game.id, {
         type: 'gamestate-update',
@@ -173,7 +177,7 @@ export class GameService {
   }
 
   async deleteGame(id) {
-    // TODO: Delete factions from Faction table associated with the deleted game
+    // Delete factions from Faction table associated with the deleted game
     await this.gameRepository.delete({ id });
     return {
       message: 'Game deleted',
@@ -209,7 +213,7 @@ export class GameService {
   }
 
   // returns information about a game identified by id
-  async returnGameInfo(id: string) {
+  async returnGameInfo(id) {
     const game = await this.gameRepository.findOne({
       where: { id: id },
       relations: ['factions', 'objective_points'],
@@ -221,6 +225,53 @@ export class GameService {
     return game;
   }
 
+  // returns information about game's flagboxes and their most recent event
+  async returnObjectivePointInfo(gameId) {
+    const info = await this.objectivePointRepository.find({
+      where: { game: gameId },
+      relations: ['history', 'history.owner', 'history.capture'],
+    });
+    let response = await Promise.all(
+      info.map(async obj => {
+        let history = obj.history.pop();
+        return await {
+          objectivePointId: obj.objectivePointId,
+          objectivePointDescription: obj.objectivePointDescription,
+          objectivePointMultiplier: obj.objectivePointMultiplier,
+          action: {
+            status: history.action,
+            message: {
+              0: 'No capture ongoing',
+              1: `Captured by ${
+                history.owner ? history.owner.factionName : 'neutral'
+              }`,
+              2: `Being captured by ${
+                history.capture ? history.capture.factionName : 'neutral'
+              }`,
+            }[history.action],
+          },
+          owner: await this.infoHelper(history.owner),
+          capture: await this.infoHelper(history.capture),
+          data: obj.data,
+        };
+      }),
+    );
+    return response;
+  }
+
+  //returns flagbox colour and faction
+  private async infoHelper(obj) {
+    return (await obj)
+      ? {
+          factionName: obj.factionName,
+          colour: obj.colour,
+        }
+      : {
+          factionName: 'neutral',
+          colour: '#000000',
+        };
+  }
+
   // returns flagbox settings
   async flagboxQuery(gameId) {
     const game = await this.gameRepository.findOne({ id: gameId });
@@ -235,7 +286,7 @@ export class GameService {
     const objectiveRef = await this.objectivePointRepository.findOne({
       where: { objectivePointDescription: data.node_id, game: gameId },
     });
-    data.oP_HistoryTimestamp = new Date(Date.now()).toLocaleString();
+    data.oP_HistoryTimestamp = Date.now();
     const eventUpdate = await this.objectivePoint_HistoryRepository.create({
       oP_HistoryTimestamp: data.oP_HistoryTimestamp,
       action: data.action,
diff --git a/src/game/gameperson.decorator.ts b/src/game/gameperson.decorator.ts
index 26c119ae5edf7771e79fad206b39baaa018ab284..3e2a232880332fbd62b54f76bbb37bf91ef714e7 100644
--- a/src/game/gameperson.decorator.ts
+++ b/src/game/gameperson.decorator.ts
@@ -1,13 +1,16 @@
 import { createParamDecorator } from '@nestjs/common';
 
-/* 
-    gives service access to the gameperson object
-    Game_PersonEntity {
-        gamepersonId
-        role
-        faction
-    }
-*/
+///////////////////////////////////////////////////////////////////////////
+///    gives service access to the gameperson object                    ///
+///    Game_PersonEntity {                                              ///
+///        gamepersonId                                                 ///
+///        role                                                         ///
+///        faction                                                      ///
+///    }                                                                ///
+///                                                                     ///
+///    See more information from decorators in shared folder files.     ///
+///////////////////////////////////////////////////////////////////////////
+
 export const GamePerson = createParamDecorator((data, req) => {
   return data ? req.gameperson[data] : req.gameperson;
 });
diff --git a/src/main.ts b/src/main.ts
index ebd53e5906d44738a4775716b7165108fae426ca..20e08b20631984132638f542266bd34a38ef74ba 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -2,14 +2,20 @@ import { NestFactory } from '@nestjs/core';
 
 import { AppModule } from './app.module';
 
-/*
-  Main.ts starts the server.
-*/
+///////////////////////////////////////////////////////////////////////////
+///   Main.ts starts the server.                                        ///
+///                                                                     ///
+///   .env.PORT is not defined, port 5000 will be listened by default   ///
+///////////////////////////////////////////////////////////////////////////
 
 async function bootstrap() {
+  // port opened
+  const port = 5000;
+
   const app = await NestFactory.create(AppModule);
   // Cors is needed for application/json POST
   app.enableCors();
-  await app.listen(5000);
+  // Server will listen on port
+  await app.listen(process.env.PORT || port);
 }
 bootstrap();
diff --git a/src/notifications/notifications.gateway.ts b/src/notifications/notifications.gateway.ts
index cc3ad3a802c877439b877efdc551f5b4f8f43d01..79fcc0e5f287858f1cf62862dde722e372ba8ef9 100644
--- a/src/notifications/notifications.gateway.ts
+++ b/src/notifications/notifications.gateway.ts
@@ -16,6 +16,10 @@ import { GameEntity } from '../game/game.entity';
 import { NotificationdDTO } from './notification.dto';
 import { ValidationPipe } from '../shared/validation.pipe';
 
+///////////////////////////////////////////////////////////////////////////////////
+/// NotificationGateway contains websocket server and listener for game-info    ///
+///////////////////////////////////////////////////////////////////////////////////
+
 @WebSocketGateway()
 export class NotificationGateway
   implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
diff --git a/src/notifications/notifications.module.ts b/src/notifications/notifications.module.ts
index 6133784682e03ee4aba0eacf79fad64298b1a80d..5ca243fcb3c39c6d49298beff12de51634575e19 100644
--- a/src/notifications/notifications.module.ts
+++ b/src/notifications/notifications.module.ts
@@ -11,6 +11,7 @@ import { NotificationsService } from './notifications.service';
 /// Notification                                                  ///
 /// - contains everything to do with Notification data.           ///
 /////////////////////////////////////////////////////////////////////
+
 @Module({
   imports: [TypeOrmModule.forFeature([NotificationEntity, GameEntity])],
   providers: [NotificationGateway, NotificationsService],
diff --git a/src/replay/replay.controller.ts b/src/replay/replay.controller.ts
index 1b42439569d54da8d6b2fa8f2986b28669e16a39..e39e99d8ba1e5be763e21fc1e00b6496e6e95648 100644
--- a/src/replay/replay.controller.ts
+++ b/src/replay/replay.controller.ts
@@ -7,6 +7,11 @@ import {
   ClassSerializerInterceptor,
 } from '@nestjs/common';
 import { ReplayService } from './replay.service';
+import { Roles } from 'src/shared/guard.decorator';
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/// POST mockdata is mainly used for development, it can be removed from the code when needed, remember to remove service & test relations.   ///
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 @Controller('replay')
 export class ReplayController {
@@ -21,6 +26,7 @@ export class ReplayController {
 
   // gets mockdata for specified Game
   @Post('mockdata/:id')
+  @Roles('admin')
   async mockData(@Param('id') gameId) {
     return this.replayservice.mockdata(gameId);
   }
diff --git a/src/replay/replay.module.ts b/src/replay/replay.module.ts
index d4d5dc095bf95a9fd2316870d4e3d57a17af321f..961e599e4cb9aca8a27dac015b83edb386e41e64 100644
--- a/src/replay/replay.module.ts
+++ b/src/replay/replay.module.ts
@@ -21,12 +21,14 @@ import {
 } from '../draw/coordinate.entity';
 import { ScoreService } from '../score/score.service';
 import { ScoreEntity } from '../score/score.entity';
-import { NotificationModule } from 'src/notifications/notifications.module';
+import { NotificationModule } from '../notifications/notifications.module';
+import { GameService } from '../game/game.service';
 
 /////////////////////////////////////////////////////////////////////
 /// Replay                                                        ///
 /// - contains everything to do with Replay data.                 ///
 /////////////////////////////////////////////////////////////////////
+
 @Module({
   imports: [
     TypeOrmModule.forFeature([
@@ -51,6 +53,7 @@ import { NotificationModule } from 'src/notifications/notifications.module';
     FactionService,
     TrackingService,
     ScoreService,
+    GameService,
   ],
 })
 export class ReplayModule {}
diff --git a/src/replay/replay.service.ts b/src/replay/replay.service.ts
index bb06399aa59082ce46cd98b49b0ca21412f912eb..be423495a09073676a7c7b81916876b23f5ecf38 100644
--- a/src/replay/replay.service.ts
+++ b/src/replay/replay.service.ts
@@ -1,10 +1,14 @@
 import { Injectable } from '@nestjs/common';
 import { InjectRepository } from '@nestjs/typeorm';
-import { Repository, In } from 'typeorm';
+import { Repository } from 'typeorm';
 import * as jwt from 'jsonwebtoken';
 
 import { FactionEntity } from '../faction/faction.entity';
-import { GameEntity } from '../game/game.entity';
+import {
+  GameEntity,
+  ObjectivePointEntity,
+  ObjectivePoint_HistoryEntity,
+} from '../game/game.entity';
 import { TrackingService } from '../tracking/tracking.service';
 import { UserService } from '../user/user.service';
 import { FactionService } from '../faction/faction.service';
@@ -13,8 +17,9 @@ import {
   MapDrawingEntity,
   MapDrawingHistoryEntity,
 } from '../draw/coordinate.entity';
-import { ScoreService } from 'src/score/score.service';
-import { ScoreEntity } from 'src/score/score.entity';
+import { ScoreService } from '../score/score.service';
+import { ScoreEntity } from '../score/score.entity';
+import { GameService } from '../game/game.service';
 
 @Injectable()
 export class ReplayService {
@@ -31,47 +36,23 @@ export class ReplayService {
     private mapHistoryRepository: Repository<MapDrawingHistoryEntity>,
     @InjectRepository(ScoreEntity)
     private scoreRepository: Repository<ScoreEntity>,
+    @InjectRepository(ObjectivePointEntity)
+    private objectivepointRepository: Repository<ObjectivePointEntity>,
     private trackingService: TrackingService,
     private userService: UserService,
     private factionService: FactionService,
     private scoreService: ScoreService,
+    private gameService: GameService,
   ) {}
 
-  /*   async replayData(gameId) {
-    let mapDrawingIds = await this.mapdrawingRepository.find({
-      where: { gameId: gameId },
-      select: ['mapDrawingId'],
-  // replay data for Factions
   async replayData(gameId) {
-    const replay = await this.factionRepository.find({
-      where: { game: gameId },
-      relations: ['mapDrawings', 'scores', 'trackdata'],
-    });
-    let drawings = [];
-    await Promise.all(
-      mapDrawingIds.map(async mapId => {
-        drawings.push(
-          await this.mapHistoryRepository.find({
-            mapdrawing: mapId.mapDrawingId,
-          }),
-        );
-      }),
-    );
-    return drawings;
-  } */
-
-  async replayData(gameId) {
-    //
     // this block returns game's initial location
-    //
     let gameObj = await this.gameRepository.findOne({
       where: { id: gameId },
       select: ['center'],
     });
     let gamelocation = [gameObj.center.lat, gameObj.center.lng];
-    //
     // this block returns all player data from the game
-    //
     let playerdata = await this.trackingRepository.find({
       where: { game: gameId },
       relations: ['faction', 'gamepersonId', 'gamepersonId.person'],
@@ -90,9 +71,9 @@ export class ReplayService {
         return player['data'];
       }),
     );
-    //
+
     // this block returns all faction data from the game
-    //
+
     let factions = await this.factionRepository.find({ game: gameId });
     let currentFactions = factions.map(faction => {
       return {
@@ -102,10 +83,8 @@ export class ReplayService {
         active: true,
       };
     });
-    let factionIds = factions.map(faction => faction.factionId);
-    //
+
     // this block returns all score data from the game
-    //
     let currentScore = [];
     await Promise.all(
       factions.map(async faction => {
@@ -124,9 +103,9 @@ export class ReplayService {
         );
       }),
     );
-    //
+
     // this block returns all map drawings from the game
-    //
+
     let refs = await this.mapdrawingRepository.find({
       where: { gameId: gameId },
       select: ['mapDrawingId'],
@@ -140,22 +119,86 @@ export class ReplayService {
       }),
     );
 
+    // this function returns all flagbox-events from the game
+
+    let objectivepoints = await this.returnObjectivePointInfo(gameId);
+
     return {
       location: gamelocation,
       players: currentdata,
       factions: currentFactions,
       scores: currentScore,
       drawings: drawData,
+      objectivepoints: objectivepoints,
     };
   }
+
+  // returns information about game's flagboxes and all of their events
+  async returnObjectivePointInfo(gameId) {
+    const info = await this.objectivepointRepository.find({
+      where: { game: gameId },
+      relations: ['history', 'history.owner', 'history.capture'],
+    });
+    let response = await Promise.all(
+      info.map(async obj => {
+        return await {
+          objectivePointId: obj.objectivePointId,
+          objectivePointDescription: obj.objectivePointDescription,
+          objectivePointMultiplier: obj.objectivePointMultiplier,
+          data: obj.data,
+          history: await this.parseHistory(obj.history),
+        };
+      }),
+    );
+    return response;
+  }
+
+  // loops all events in history array and returns an array of objects formatted for replay
+  private async parseHistory(history: ObjectivePoint_HistoryEntity[]) {
+    return await Promise.all(
+      history.map(async event => {
+        return {
+          timestamp: event.oP_HistoryTimestamp,
+          action: {
+            status: event.action,
+            message: {
+              0: 'No capture ongoing',
+              1: `Captured by ${
+                event.owner ? event.owner.factionName : 'neutral'
+              }`,
+              2: `Being captured by ${
+                event.capture ? event.capture.factionName : 'neutral'
+              }`,
+            }[event.action],
+          },
+          owner: await this.infoHelper(event.owner),
+          capture: await this.infoHelper(event.capture),
+        };
+      }),
+    );
+  }
+
+  // small helper function that formats data for replay
+  private async infoHelper(obj) {
+    return (await obj)
+      ? {
+          factionName: obj.factionName,
+          colour: obj.colour,
+        }
+      : {
+          factionName: 'neutral',
+          colour: '#000000',
+        };
+  }
   // generate mockdata for a 3 day game
   // create x amount of players
   // assign them to two separate factions
   // assign them to three separate groups
   // insert x amount of locations for each players around some lat lng area
+  // insert x amont of flagbox events
   // insert x amount of score ticks for score mockdata
   // use the game's initial geojson to draw game area
-  //
+
   async mockdata(gameId) {
     // initial settings for mockdata
     // set the x amount of users to be created
@@ -165,6 +208,9 @@ export class ReplayService {
     // set the LAT and LNG for initial location
     const LAT = 62.24147;
     const LNG = 25.72088;
+    // set the x amount of flagbox events
+    // not used at the moment
+    const FLAGBOX_EVENTS = 8;
     // set the score tick amount
     // not used at the moment
     const SCORE_TICKS = 10;
@@ -188,6 +234,10 @@ export class ReplayService {
     await game.factions.forEach(async faction => {
       groups.push(await this.factionService.showGroups(faction.factionId));
     });
+    // get all objective point refs
+    const objectivepoints = await this.objectivepointRepository.find({
+      game: gameId,
+    });
     // create x amount of users for the mock game with random username
     for (let i = 0; i < USER_AMOUNT; i++) {
       let res = await this.userService.register({
@@ -227,6 +277,10 @@ export class ReplayService {
       let x = 1;
       // score ticks with players to sync them
       await this.scoreService.scoreTick(gameId);
+      // flagbox events with players to sync them
+      // use helper function to generate a random event
+      let event = await this.createEvent(objectivepoints);
+      await this.gameService.flagboxEvent(gameId, event);
       // add location entry for each gameperson
       await Promise.all(
         gamepersons.map(async gameperson => {
@@ -252,4 +306,18 @@ export class ReplayService {
       message: 'all done',
     };
   }
+
+  // creates randomized events for randomly chosen flagbox
+  // may result in impossible scenarios where owner is capturing their own flagbox
+  // use only for testing flagbox replay functionalities
+  private async createEvent(objectivepoints: ObjectivePointEntity[]) {
+    let point =
+      objectivepoints[Math.floor(Math.random() * objectivepoints.length)];
+    return await {
+      node_id: point.objectivePointDescription,
+      owner: Math.round(Math.random()) + 1,
+      action: Math.round(Math.random()) ? 2 : 0,
+      capture: Math.round(Math.random()) + 1,
+    };
+  }
 }
diff --git a/src/score/score.controller.ts b/src/score/score.controller.ts
index a9989a06b77d8ec08b1c84db9dbf24ad87fe9377..344c33c02a84f1e49b202090dffedb0d42d23ce8 100644
--- a/src/score/score.controller.ts
+++ b/src/score/score.controller.ts
@@ -32,7 +32,6 @@ export class ScoreController {
   // shows scores, :id is gameId
   @Get('get-score/:id')
   @UseInterceptors(ClassSerializerInterceptor)
-  @GameStates('STARTED')
   async getScores(@Param('id') gameId: GameEntity) {
     return this.scoreService.getScores(gameId);
   }
diff --git a/src/score/score.dto.ts b/src/score/score.dto.ts
index 99955f56eff34a41ce46111d7fd0cb9cd597386f..2feecbfd8aecd189d9fb1f8239abf2793fe6051b 100644
--- a/src/score/score.dto.ts
+++ b/src/score/score.dto.ts
@@ -3,7 +3,7 @@ import { IsNumber, Min, Max, IsUUID } from 'class-validator';
 export class ScoreDTO {
   @IsNumber()
   @Min(1)
-  @Max(99)
+  @Max(999)
   score: number;
   @IsUUID('4')
   faction: string;
diff --git a/src/score/score.entity.ts b/src/score/score.entity.ts
index a5321daa56ae78dbe1d54911bf934a37a9b124db..01fb60bf11ad23461f9bba6492b6ebea68c61c45 100644
--- a/src/score/score.entity.ts
+++ b/src/score/score.entity.ts
@@ -1,11 +1,4 @@
-import {
-  Entity,
-  PrimaryGeneratedColumn,
-  Column,
-  ManyToOne,
-  Timestamp,
-  CreateDateColumn,
-} from 'typeorm';
+import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
 import { FactionEntity } from '../faction/faction.entity';
 
 @Entity('Score')
diff --git a/src/score/score.module.ts b/src/score/score.module.ts
index fce21d189b233bd6f952ebce79e47869171df60b..9ce2f41c5c8ab0cbdbf4c11d1709f305323ba870 100644
--- a/src/score/score.module.ts
+++ b/src/score/score.module.ts
@@ -15,6 +15,7 @@ import { NotificationModule } from '../notifications/notifications.module';
 /// Score                                                         ///
 /// - contains everything to do with Score data.                  ///
 /////////////////////////////////////////////////////////////////////
+
 @Module({
   imports: [
     TypeOrmModule.forFeature([
diff --git a/src/score/score.service.ts b/src/score/score.service.ts
index 7ef613d0f554bc61ffe9106e64845eaefe43428f..ab6d522a805a00dc4456c5a64f550d30ff34fffd 100644
--- a/src/score/score.service.ts
+++ b/src/score/score.service.ts
@@ -1,10 +1,4 @@
-import {
-  Injectable,
-  HttpException,
-  HttpStatus,
-  Logger,
-  OnModuleInit,
-} from '@nestjs/common';
+import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
 import { InjectRepository } from '@nestjs/typeorm';
 import { Repository } from 'typeorm';
 
@@ -32,31 +26,15 @@ export class ScoreService {
     private notificationGateway: NotificationGateway,
   ) {}
 
-  async addScore(scoreData: ScoreDTO, gameId: GameEntity) {
-    // check if faction exists
-    const faction = await this.factionRepository.findOne({
-      factionId: scoreData.faction,
-    });
-    if (!faction) {
-      throw new HttpException('Faction was not found', HttpStatus.BAD_REQUEST);
-    }
-    // get the previous score and add it, if it exists
-    let lastScore = await this.scoreRepository.findOne({
-      where: { faction: scoreData.faction },
-      order: { scoreTimeStamp: 'DESC' },
-    });
-    if (lastScore) {
-      scoreData.score += lastScore.score * faction.multiplier;
-    }
-    // add the score for Faction
-    const newScore = await this.scoreRepository.create(scoreData);
-    newScore.scoreTimeStamp = Date.now();
-    await this.scoreRepository.insert(newScore);
+  async addScore(scoreData: ScoreDTO, gameId) {
+    await this.pushScore(scoreData);
+    this.notificationGateway.server.emit(gameId, { type: 'score-update' });
     return {
       message: 'Score updated!',
     };
   }
 
+  // function to run on timer tick
   async scoreTick(gameId) {
     // get game's flagboxes
     const flagboxes = await this.flagRepository.find({ game: gameId });
@@ -86,7 +64,7 @@ export class ScoreService {
       }),
     );
     scoreData.map(async data => {
-      await this.addScore(data, gameId);
+      await this.pushScore(data);
     });
     this.notificationGateway.server.emit(gameId, { type: 'score-update' });
     return {
@@ -94,6 +72,28 @@ export class ScoreService {
     };
   }
 
+  private async pushScore(scoreData: ScoreDTO) {
+    // check if faction exists
+    const faction = await this.factionRepository.findOne({
+      factionId: scoreData.faction,
+    });
+    if (!faction) {
+      throw new HttpException('Faction was not found', HttpStatus.BAD_REQUEST);
+    }
+    // get the previous score and add it, if it exists
+    let lastScore = await this.scoreRepository.findOne({
+      where: { faction: scoreData.faction },
+      order: { scoreTimeStamp: 'DESC' },
+    });
+    if (lastScore) {
+      scoreData.score += lastScore.score * faction.multiplier;
+    }
+    // add the score for Faction
+    const newScore = await this.scoreRepository.create(scoreData);
+    newScore.scoreTimeStamp = Date.now();
+    await this.scoreRepository.insert(newScore);
+  }
+
   async getScores(gameId: GameEntity) {
     // find games factions
     const factions = await this.factionRepository.find({
@@ -110,7 +110,6 @@ export class ScoreService {
         });
         //if score was found, put info to scores array
         if (score.faction) {
-          let index = await scores.findIndex(i => i.faction === score.faction);
           scores.push(score);
         }
       }),
diff --git a/src/shared/auth.guard.ts b/src/shared/auth.guard.ts
index ff2bdf406d5badffc467cdf22d0f61935aae0af8..acde301a9dca4202d4971a3b34e6d251dc07a7c1 100644
--- a/src/shared/auth.guard.ts
+++ b/src/shared/auth.guard.ts
@@ -7,6 +7,14 @@ import {
 } from '@nestjs/common';
 import * as jwt from 'jsonwebtoken';
 
+/////////////////////////////////////////////////////////
+///   https://docs.nestjs.com/guards                  ///
+///   AuthGuard verifies the user's token             ///
+///   It adds user information to request.user        ///
+///   which can be used by UserDecorator in services  ///
+///   return 403 if token validation fails            ///
+/////////////////////////////////////////////////////////
+
 @Injectable()
 export class AuthGuard implements CanActivate {
   // check for logged in user
diff --git a/src/shared/custom-validation.ts b/src/shared/custom-validation.ts
deleted file mode 100644
index 13b96372e0b76a2897364baa15562edf383a2d81..0000000000000000000000000000000000000000
--- a/src/shared/custom-validation.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import {
-  ValidatorConstraint,
-  ValidatorConstraintInterface,
-  ValidationArguments,
-  Validator,
-} from 'class-validator';
-
-// check if input is null or valid uuid
-@ValidatorConstraint({ name: 'uuid', async: true })
-export class Uuid implements ValidatorConstraintInterface {
-  validate(uuid: string, args: ValidationArguments) {
-    const validator = new Validator();
-    return validator.isUUID(uuid, '4') || uuid == null; // for async validations you must return a Promise<boolean> here
-  }
-
-  defaultMessage(args: ValidationArguments) {
-    return 'Not valid uuid';
-  }
-}
-
-// checks if role is valid
-@ValidatorConstraint({ name: 'roleValidation', async: true })
-export class RoleValidation implements ValidatorConstraintInterface {
-  validate(role: string, args: ValidationArguments) {
-    const validRoles = ['admin', 'soldier', 'factionleader'];
-    return validRoles.includes(role);
-  }
-
-  defaultMessage(args: ValidationArguments) {
-    return 'Not valid uuid';
-  }
-}
-
-// checks for valid JSON for center
-@ValidatorConstraint({ name: 'centerJSON', async: true })
-export class CenterJSON implements ValidatorConstraintInterface {
-  validate(center: JSON, args: ValidationArguments) {
-    const validator = new Validator();
-    return (
-      validator.isNumber(center['lat']) &&
-      validator.isNumber(center['lng']) &&
-      validator.min(center['lat'], -90) &&
-      validator.max(center['lat'], 90) &&
-      validator.min(center['lng'], -180) &&
-      validator.max(center['lng'], 180)
-    );
-  }
-
-  defaultMessage(args: ValidationArguments) {
-    return 'Error with center JSON';
-  }
-}
diff --git a/src/shared/guard.decorator.ts b/src/shared/guard.decorator.ts
index b299d6de913f54dd496c344f6dcdafd2942b2c9c..a313b3a6e52321b70b2f9768b5131252cb7816f7 100644
--- a/src/shared/guard.decorator.ts
+++ b/src/shared/guard.decorator.ts
@@ -1,5 +1,12 @@
 import { SetMetadata } from '@nestjs/common';
 
+/////////////////////////////////////////////////////////
+///   pass information from controllers to guards     ///
+///   for example @Roles("admin") passes it to        ///
+///   roles.guard, which compares user's role         ///
+///   to the values return by SetMetadata             ///
+/////////////////////////////////////////////////////////
+
 export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
 
 export const GameStates = (...states: string[]) =>
diff --git a/src/shared/http-error.filter.ts b/src/shared/http-error.filter.ts
index 8a65068c4275c4a8d576da54b0340c17b6ac8cc4..bf7316fa20d8c5e3107a10b0972a1d1d9e18e940 100644
--- a/src/shared/http-error.filter.ts
+++ b/src/shared/http-error.filter.ts
@@ -7,6 +7,12 @@ import {
   HttpStatus,
 } from '@nestjs/common';
 
+/////////////////////////////////////////////////////////
+///   Global tryCatch for catching errors in services ///
+///   Returns error message for end-users             ///
+///   Also logs the error in console                  ///
+/////////////////////////////////////////////////////////
+
 @Catch()
 export class HttpErrorFilter implements ExceptionFilter {
   catch(exception: HttpException, host: ArgumentsHost) {
diff --git a/src/shared/logging.interceptor.ts b/src/shared/logging.interceptor.ts
index 55083faabd0a781ace687fc2cb9c2977f0befaa9..c29717474c87516cc3e1492bc24a5f13f848c89a 100644
--- a/src/shared/logging.interceptor.ts
+++ b/src/shared/logging.interceptor.ts
@@ -1,7 +1,13 @@
-import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';
+import {
+  Injectable,
+  NestInterceptor,
+  ExecutionContext,
+  CallHandler,
+  Logger,
+} from '@nestjs/common';
 import { Observable } from 'rxjs';
 import { tap } from 'rxjs/operators';
-
+/*
 @Injectable()
 export class LoggingInterceptor implements NestInterceptor {
     intercept(
@@ -19,4 +25,4 @@ export class LoggingInterceptor implements NestInterceptor {
             ))
         )
     }
-}
\ No newline at end of file
+}*/
diff --git a/src/shared/roles.controller.ts b/src/shared/roles.controller.ts
deleted file mode 100644
index 0298723936651e1859e76273b14b9086e167f6c9..0000000000000000000000000000000000000000
--- a/src/shared/roles.controller.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-const AccessControl = require('accesscontrol');
-
-const grants = {
-  admin: {
-    mapmarker: {
-      'create:any': [],
-      'delete:any': [],
-      'read:any': [],
-      'update:any': [],
-    },
-    powerup: {
-      'create:any': [],
-      'delete:any': [],
-      'read:any': [],
-      'update:any': [],
-    },
-    faction: {
-      'create:any': [],
-      'delete:any': [],
-      'read:any': [],
-      'update:any': [],
-    },
-    players: {
-      'create:any': [],
-      'delete:any': [],
-      'read:any': [],
-      'update:any': [],
-    },
-  },
-  faction_leader: {
-    mapmarker: {
-      'create:own': [],
-      'delete:own': [],
-      'read:own': [],
-    },
-    powerup: {
-      'read:own': [],
-    },
-    faction: {
-      'read:own': [],
-      'update:own': [],
-    },
-    players: {
-      'read:own': [],
-      'update:own': [],
-    },
-  },
-  //player & spectator
-};
-
-const ac = new AccessControl(grants);
\ No newline at end of file
diff --git a/src/shared/roles.guard.ts b/src/shared/roles.guard.ts
index 7ae58d2f0c2d9f1258e41ea1a8341e2e664df15d..5e97482e408df52075c4e97553707e32ca70a447 100644
--- a/src/shared/roles.guard.ts
+++ b/src/shared/roles.guard.ts
@@ -13,6 +13,15 @@ import { Validator } from 'class-validator';
 
 import { Game_PersonEntity } from '../game/game.entity';
 
+/////////////////////////////////////////////////////////
+///   https://docs.nestjs.com/guards                  ///
+///   RolesGuard verifies the user's token and role   ///
+///   It adds user information to request.user        ///
+///   which can be used by GamePerson                 ///
+///   decorator in services                           ///
+///   return 403 if token/role validation fails       ///
+/////////////////////////////////////////////////////////
+
 @Injectable()
 export class RolesGuard implements CanActivate {
   constructor(
diff --git a/src/shared/states.guard.ts b/src/shared/states.guard.ts
index 961b93619883e3c55be3ab5e54fdc92e65f27e74..544918d56e4653f6d52950a06ee8abd3e0eea4f1 100644
--- a/src/shared/states.guard.ts
+++ b/src/shared/states.guard.ts
@@ -12,6 +12,13 @@ import { Validator } from 'class-validator';
 
 import { GameEntity } from '../game/game.entity';
 
+//////////////////////////////////////////////////////////
+///   https://docs.nestjs.com/guards                   ///
+///   StatesGuard verifies the game's state            ///
+///   Guard needs gameId as 'id' in request parameters ///
+///   return 400 if state if state validation fails    ///
+//////////////////////////////////////////////////////////
+
 @Injectable()
 export class StatesGuard implements CanActivate {
   constructor(
diff --git a/src/shared/validation.pipe.ts b/src/shared/validation.pipe.ts
index 423f23152e202e3c808d8c1e888f2a5fc00dac30..7e4bb8796f7b036c20238729b54f9c3d6093505c 100644
--- a/src/shared/validation.pipe.ts
+++ b/src/shared/validation.pipe.ts
@@ -8,6 +8,15 @@ import {
 import { validate } from 'class-validator';
 import { plainToClass } from 'class-transformer';
 
+///////////////////////////////////////////////////////////
+///   https://docs.nestjs.com/techniques/validation     ///
+///   ValidationPipe for validating DTO's               ///
+///   DTO's use ClassValidator which are                ///
+///   validated by ValidationPipes                      ///
+///   return 400 if pipe validation fails with          ///
+///   errorMessage stating reason for validation fail   ///
+///////////////////////////////////////////////////////////
+
 @Injectable()
 export class ValidationPipe implements PipeTransform<any> {
   async transform(value: any, metadata: ArgumentMetadata) {
diff --git a/src/task/task.controller.ts b/src/task/task.controller.ts
index 14bbb215de47785a8bf9c284c1b0ef969b1ae84f..ba9f6cc9e9be2e6f8408c337ed270d0a587d2ba9 100644
--- a/src/task/task.controller.ts
+++ b/src/task/task.controller.ts
@@ -42,7 +42,7 @@ export class TaskController {
   @Roles('admin')
   @UsePipes(new ValidationPipe())
   async deleteTask(@Param('id') id: string, @Body() data: DeleteTaskDTO) {
-    return this.taskService.deleteTask(data);
+    return this.taskService.deleteTask(data, id);
   }
 
   // lists all the tasks for the game if the user has game_person entry
diff --git a/src/task/task.dto.ts b/src/task/task.dto.ts
index a1576e7d12c9d9a6263b445fdba293fe94e8964a..02653c39d5762784215303956652aaec78c60f81 100644
--- a/src/task/task.dto.ts
+++ b/src/task/task.dto.ts
@@ -5,10 +5,10 @@ import {
   Validate,
   IsUUID,
   Equals,
+  IsOptional,
 } from 'class-validator';
 import { FactionEntity } from '../faction/faction.entity';
 import { GameEntity } from '../game/game.entity';
-import { Uuid } from '../shared/custom-validation';
 
 export class CreateTaskDTO {
   @IsString()
@@ -19,7 +19,8 @@ export class CreateTaskDTO {
   taskDescription: string;
   @IsBoolean()
   taskIsActive: boolean;
-  @Validate(Uuid)
+  @IsOptional()
+  @IsUUID('4')
   faction: FactionEntity;
   @Equals(null)
   taskWinner: FactionEntity;
diff --git a/src/task/task.module.ts b/src/task/task.module.ts
index dc4b8f63d9a1866771f4c68035a09516cfc56bf6..9b009fc9480aab4e6708a9d8a986447393b76634 100644
--- a/src/task/task.module.ts
+++ b/src/task/task.module.ts
@@ -11,6 +11,7 @@ import { NotificationModule } from '../notifications/notifications.module';
 /// Task                                                          ///
 /// - contains everything to do with Task data.                   ///
 /////////////////////////////////////////////////////////////////////
+
 @Module({
   imports: [
     TypeOrmModule.forFeature([TaskEntity, FactionEntity]),
diff --git a/src/task/task.service.ts b/src/task/task.service.ts
index 478a6c18059c5b0388aaad1abe2f3fcc2e05ce5e..0461d310de44f882ccdf18c4b2ba29f01cb5d8a7 100644
--- a/src/task/task.service.ts
+++ b/src/task/task.service.ts
@@ -32,10 +32,7 @@ export class TaskService {
     await this.taskRepository.insert(createdTask);
     // notify subscribers about a new task
     // if faction was set it notifies only faction members, else everyone
-    this.notificationGateway.server.emit(
-      task.faction != null ? task.faction.toString() : task.taskGame.toString(),
-      { type: 'task-update' },
-    );
+    this.triggerTasks(task, task.taskGame);
     return {
       message: 'Task added',
     };
@@ -59,15 +56,17 @@ export class TaskService {
     task.taskWinner = data.taskWinner;
     task.taskIsActive = false;
     await this.taskRepository.save(task);
+    this.triggerTasks(task, data.taskGame);
     return {
       message: 'Task updated and closed',
     };
   }
 
-  async deleteTask(data: DeleteTaskDTO) {
+  async deleteTask(data: DeleteTaskDTO, gameId) {
     const task = await this.taskRepository.findOne({ taskId: data.taskId });
     if (task) {
       await this.taskRepository.delete({ taskId: task.taskId });
+      this.triggerTasks(task, gameId);
       return {
         message: 'Task deleted',
       };
@@ -75,6 +74,13 @@ export class TaskService {
     throw new HttpException('Task not found', HttpStatus.BAD_REQUEST);
   }
 
+  private triggerTasks(task, gameId) {
+    this.notificationGateway.server.emit(gameId, {
+      type: 'task-update',
+      message: task.faction != null ? task.faction.toString() : '',
+    });
+  }
+
   // finds all tasks if admin and if non-admin player it finds the playres own
   // tasks and general tasks
   async fetchTasks(gameperson, taskGame) {
diff --git a/src/tick/tick.module.ts b/src/tick/tick.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b07fa5fa1eca4c4357d6e551983edf1b5c3aebe6
--- /dev/null
+++ b/src/tick/tick.module.ts
@@ -0,0 +1,32 @@
+import { Module } from '@nestjs/common';
+import { TypeOrmModule } from '@nestjs/typeorm';
+
+import {
+  GameEntity,
+  ObjectivePointEntity,
+  ObjectivePoint_HistoryEntity,
+} from '../game/game.entity';
+import { TickService } from './tick.service';
+import { ScoreService } from '../score/score.service';
+import { FactionEntity } from '../faction/faction.entity';
+import { ScoreEntity } from '../score/score.entity';
+import { NotificationModule } from '../notifications/notifications.module';
+
+@Module({
+  imports: [
+    TypeOrmModule.forFeature([
+      GameEntity,
+      ScoreEntity,
+      ObjectivePointEntity,
+      ObjectivePoint_HistoryEntity,
+      FactionEntity,
+    ]),
+    NotificationModule,
+  ],
+  providers: [TickService, ScoreService],
+})
+export class TickModule {
+  constructor(private tickService: TickService) {
+    this.tickService.startTimer();
+  }
+}
diff --git a/src/game/tick.service.ts b/src/tick/tick.service.ts
similarity index 53%
rename from src/game/tick.service.ts
rename to src/tick/tick.service.ts
index 8417fe8b0b3b11c464bd4d837743ec3cabdcbc33..3a5f7cc1dac03303eaf0febcba0cd603fdeaf45a 100644
--- a/src/game/tick.service.ts
+++ b/src/tick/tick.service.ts
@@ -1,23 +1,26 @@
 import { Injectable, Logger } from '@nestjs/common';
 import { ScoreService } from '../score/score.service';
+import { InjectRepository } from '@nestjs/typeorm';
+import { GameEntity } from 'src/game/game.entity';
+import { Repository } from 'typeorm';
 
 @Injectable()
 export class TickService {
-  constructor(private scoreService: ScoreService) {
+  constructor(
+    private scoreService: ScoreService,
+    @InjectRepository(GameEntity)
+    private gameRepository: Repository<GameEntity>,
+  ) {
     // whenever Tickservice is called, it will start ticktimer
     /* 
     WARNING: multiple calls start multiple timers, 
     if you need to use this service somewhere else remember to call startTimer method from somewhere else
      */
-
-    this.startTimer();
   }
 
   private logger: Logger = new Logger('TickLogger');
   // tickinterval in milliseconds (10 minutes = 600 000)
   private readonly tickInterval: number = 60000;
-  // dictionary to push gameId linked to start state
-  private ongoingGames = {};
 
   // initializing timer
   async startTimer() {
@@ -25,25 +28,23 @@ export class TickService {
     setInterval(this.Tick, this.tickInterval);
   }
 
-  // add the game to tick queue
-  async addGameToTimer(gameId: string) {
-    this.logger.log('Added: ' + gameId);
-    this.ongoingGames[gameId] = Date.now();
-  }
-
-  // remove game if the setting is set to pause
-  async removeGameFromTimer(gameId: string) {
-    this.logger.log('Deleted: ' + gameId);
-    delete this.ongoingGames[gameId];
+  // returns name and id of each game
+  async listGames() {
+    const games = await this.gameRepository.find({
+      where: { state: 'STARTED' },
+    });
+    return games.map(game => {
+      return game.gameObject();
+    });
   }
 
   // tick score for games with STARTED-status
-  Tick = () => {
+  Tick = async _ => {
     this.logger.log('Ticking');
-    if (this.ongoingGames != null) {
-      for (var game in this.ongoingGames) {
-        this.scoreService.scoreTick(game);
-      }
-    }
+    let games = await this.listGames();
+    games.map(game => {
+      this.logger.log(game);
+      this.scoreService.scoreTick(game.id);
+    });
   };
 }
diff --git a/src/tracking/geo.dto.ts b/src/tracking/geo.dto.ts
index 352faf704db72912a548734185d277253d67c789..681e1b6d1f5c4cc30d66e113b5d1fb0dbf653dd9 100644
--- a/src/tracking/geo.dto.ts
+++ b/src/tracking/geo.dto.ts
@@ -1,5 +1,7 @@
 import { IsNumber, Min, Max, Allow } from 'class-validator';
 
+// latitude and longitude accepts degrees from worldmap
+
 export class GeoDTO {
   @IsNumber()
   @Min(-90)
diff --git a/src/tracking/tracking.controller.ts b/src/tracking/tracking.controller.ts
index 93d0779a9c1ec36f2446b93167211f9c8eae9dce..a98c12bfb399cc797c9dd642de2663ae5d0a5d76 100644
--- a/src/tracking/tracking.controller.ts
+++ b/src/tracking/tracking.controller.ts
@@ -42,14 +42,4 @@ export class TrackingController {
   async getPlayerLocations(@GamePerson() gameperson, @Param('id') gameId) {
     return this.trackingservice.getPlayers(gameperson, gameId);
   }
-
-
-  // finds certain player
-  @Get('player/:id')
-  @Roles('admin', 'factionleader')
-  @GameStates('STARTED', 'PAUSED')
-  @UseInterceptors(ClassSerializerInterceptor)
-  async getPlayerData(@User('id') userId, @Param('id') gameid, @Body() person) {
-    return this.trackingservice.getPlayerData(person);
-  }
 }
diff --git a/src/tracking/tracking.dto.ts b/src/tracking/tracking.dto.ts
index 3ac93c71d8ccf3035e82fb52a7d21350b6407763..181430ba1f631fda4202d9d5115247a27c82a99c 100644
--- a/src/tracking/tracking.dto.ts
+++ b/src/tracking/tracking.dto.ts
@@ -1,4 +1,4 @@
-import { Allow, ValidateNested } from 'class-validator';
+import { ValidateNested } from 'class-validator';
 import { GeoDTO } from './geo.dto';
 import { Type } from 'class-transformer';
 
diff --git a/src/tracking/tracking.entity.ts b/src/tracking/tracking.entity.ts
index 4952e18c1f2cbac3b2c31a377909960ed85100c9..dc398ac8d9398aa475de128fd2bc6bfb87074013 100644
--- a/src/tracking/tracking.entity.ts
+++ b/src/tracking/tracking.entity.ts
@@ -1,6 +1,6 @@
 import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
 import { Game_PersonEntity, GameEntity } from '../game/game.entity';
-import { FactionEntity } from 'src/faction/faction.entity';
+import { FactionEntity } from '../faction/faction.entity';
 import { GeoDTO } from './geo.dto';
 
 @Entity('Tracking')
diff --git a/src/tracking/tracking.module.ts b/src/tracking/tracking.module.ts
index b2a731217fadbda0dca4be40af271b711e604482..de4afda4d1450da298902942709df1f039adc024 100644
--- a/src/tracking/tracking.module.ts
+++ b/src/tracking/tracking.module.ts
@@ -6,14 +6,21 @@ import { TrackingService } from './tracking.service';
 import { TrackingEntity } from './tracking.entity';
 import { Game_PersonEntity } from '../game/game.entity';
 import { PersonEntity } from '../user/user.entity';
+import { FactionEntity } from '../faction/faction.entity';
 
 /////////////////////////////////////////////////////////////////////
 /// Tracking                                                      ///
 /// - contains everything to do with Tracking data.               ///
 /////////////////////////////////////////////////////////////////////
+
 @Module({
   imports: [
-    TypeOrmModule.forFeature([TrackingEntity, Game_PersonEntity, PersonEntity]),
+    TypeOrmModule.forFeature([
+      TrackingEntity,
+      Game_PersonEntity,
+      PersonEntity,
+      FactionEntity,
+    ]),
   ],
   controllers: [TrackingController],
   providers: [TrackingService],
diff --git a/src/tracking/tracking.service.ts b/src/tracking/tracking.service.ts
index b366784ec03f8c4f67e0ec99bbc563a292733d6f..175c3eaaeb548507dc103c484b0f908edba9f1e1 100644
--- a/src/tracking/tracking.service.ts
+++ b/src/tracking/tracking.service.ts
@@ -5,6 +5,7 @@ import { Repository } from 'typeorm';
 import { Game_PersonEntity } from '../game/game.entity';
 import { TrackingEntity } from './tracking.entity';
 import { GeoDTO } from './geo.dto';
+import { FactionEntity } from 'src/faction/faction.entity';
 
 @Injectable()
 export class TrackingService {
@@ -13,6 +14,8 @@ export class TrackingService {
     private trackingrepository: Repository<TrackingEntity>,
     @InjectRepository(Game_PersonEntity)
     private gamepersonrepository: Repository<Game_PersonEntity>,
+    @InjectRepository(FactionEntity)
+    private factionRepository: Repository<FactionEntity>,
   ) {}
 
   private icons = {
@@ -39,7 +42,6 @@ export class TrackingService {
       await this.trackingrepository.save(trackedperson);
       return { message: 'Location updated!' };
     } else {
-      // first entry will be empty
       trackdata['time'] = Date.now();
       // initialize data
       trackedperson = await this.trackingrepository.create(trackedperson);
@@ -59,57 +61,64 @@ export class TrackingService {
 
   // get player data while game is running
   async getPlayers(gameperson, gameId) {
-    let playerdata;
+    let playerdata = [];
     // get playerdata
     if (gameperson.faction) {
-      playerdata = await this.trackingrepository.find({
-        where: { faction: gameperson.faction },
-        relations: ['faction', 'gamepersonId'],
-      });
+      // create an array of the response as frontend maps the response
+      // to create different clusters for factions
+      playerdata.push(
+        await this.trackingrepository.find({
+          where: { faction: gameperson.faction },
+          relations: ['faction', 'gamepersonId', 'gamepersonId.person'],
+        }),
+      );
     } else {
-      playerdata = await this.trackingrepository.find({
-        where: { game: gameId },
-        relations: ['faction', 'gamepersonId'],
-      });
+      let factions = await this.factionRepository.find({ game: gameId });
+      playerdata = await Promise.all(
+        factions.map(async faction => {
+          let rawdata = await this.trackingrepository.find({
+            where: { faction: faction.factionId },
+            relations: ['faction', 'gamepersonId', 'gamepersonId.person'],
+          });
+          let groups = {
+            'infantry.svg': [],
+            'recon.svg': [],
+            'mechanized.svg': [],
+          };
+          rawdata.forEach(async player => {
+            groups[player.icon].push(player);
+          });
+          return groups;
+        }),
+      );
     }
-
     // parse data
+    // create an array for each faction
+    // inside faction create an array for each icon type
+    // insisde icon arrays include all players with same icon
     const currentdata = await Promise.all(
-      playerdata.map(async player => {
-        return {
-          gamepersonId: player['gamepersonId']['gamepersonId'],
-          gamepersonRole: player['gamepersonId']['role'],
-          factionId: player['faction']['factionId'],
-          factionColour: player['faction']['colour'],
-          icon: player['icon'],
-          coordinates: player['data'].pop(),
-        };
+      await playerdata.map(async faction => {
+        let data = [];
+        for (let group in faction) {
+          data.push(
+            await Promise.all(
+              faction[group].map(async player => {
+                return await {
+                  username: player['gamepersonId']['person']['name'],
+                  gamepersonId: player['gamepersonId']['gamepersonId'],
+                  gamepersonRole: player['gamepersonId']['role'],
+                  factionId: player['faction']['factionId'],
+                  factionColour: player['faction']['colour'],
+                  icon: player['icon'],
+                  coordinates: player['data'].pop(),
+                };
+              }),
+            ),
+          );
+        }
+        return data;
       }),
     );
-
     return currentdata;
   }
-
-  // get selected player data
-  async getPlayerData(person) {
-    const gameperson = await this.gamepersonrepository.findOne({
-      where: { gamepersonId: person.gamepersonId },
-      relations: ['person', 'leaderGroup', 'group', 'faction'],
-    });
-    if (!gameperson) {
-      throw new HttpException('No player found!', HttpStatus.BAD_REQUEST);
-    }
-
-    return {
-      gamepersonId: gameperson.gamepersonId,
-      name: gameperson.person.name,
-      role: gameperson.role,
-      group: gameperson.group,
-      faction: {
-        factionId: gameperson.faction.factionId,
-        factionName: gameperson.faction.factionName,
-        colour: gameperson.faction.colour,
-      },
-    };
-  }
 }
diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts
index 4d4158d3f037850c8c5230975ef5f46ae5a75ede..8e7635767424c627f8372d8b312cc2b7229e673a 100644
--- a/src/user/user.controller.ts
+++ b/src/user/user.controller.ts
@@ -12,6 +12,16 @@ import { UserDTO } from './user.dto';
 import { AuthGuard } from '../shared/auth.guard';
 import { ValidationPipe } from '../shared/validation.pipe';
 
+/////////////////////////////////////////////////////////////////////
+/// UserController is being used for routing:                     ///
+/// - Login                                                       ///
+/// - Register                                                    ///
+///                                                               ///
+/// - Verify is checking for logged in user                       ///
+///                                                               ///
+/// See shared folder files for more information on decorators.   ///
+/////////////////////////////////////////////////////////////////////
+
 @Controller('user')
 export class UserController {
   constructor(private userService: UserService) {}
diff --git a/src/user/user.decorator.ts b/src/user/user.decorator.ts
index 2c499d904927d0502567fc2131270b81170327f4..4a6ec4788ceb7698d57d6c7986dd98d11e1dae31 100644
--- a/src/user/user.decorator.ts
+++ b/src/user/user.decorator.ts
@@ -1,6 +1,14 @@
-import { createParamDecorator } from "@nestjs/common";
+import { createParamDecorator } from '@nestjs/common';
+
+///////////////////////////////////////////////////////////////////////////////
+/// UserDecorator                                                           ///
+///                                                                         ///
+/// See auth.guard.ts in shared folder for more information                 ///
+///                                                                         ///
+/// Returns user id and user name, this is mainly used to return user id    ///
+///////////////////////////////////////////////////////////////////////////////
 
 // used to pass user information to controllers
 export const User = createParamDecorator((data, req) => {
-    return data ? req.user[data] : req.user;
-})
\ No newline at end of file
+  return data ? req.user[data] : req.user;
+});
diff --git a/src/user/user.dto.ts b/src/user/user.dto.ts
index c5bfa70cc3551645e1773e9aa7c4fb898b3f9887..243dae1faa53acc3c9a6a051db32b1a20b1728d3 100644
--- a/src/user/user.dto.ts
+++ b/src/user/user.dto.ts
@@ -1,10 +1,18 @@
 import { IsString, IsNotEmpty, Length } from 'class-validator';
 
+///////////////////////////////////////////////////////////
+/// Contains Validation for UserDTO                     ///
+/// uses class-validator built in validations           ///
+/// see https://github.com/typestack/class-validator    ///
+///////////////////////////////////////////////////////////
+
 export class UserDTO {
-    // uses class-validator built in validations
-    // see https://github.com/typestack/class-validator
-    @IsString() @IsNotEmpty() @Length(3, 31)
-    name: string;
-    @IsString() @IsNotEmpty() @Length(3, 255)
-    password: string;
-}
\ No newline at end of file
+  @IsString()
+  @IsNotEmpty()
+  @Length(3, 31)
+  name: string;
+  @IsString()
+  @IsNotEmpty()
+  @Length(3, 255)
+  password: string;
+}
diff --git a/src/user/user.entity.ts b/src/user/user.entity.ts
index 716020ae49d675641863a1711e424b85dbd67608..1c4c8d9eb7a38f6fb1f8003a6c5cd7a02d44d339 100644
--- a/src/user/user.entity.ts
+++ b/src/user/user.entity.ts
@@ -11,6 +11,15 @@ import * as jwt from 'jsonwebtoken';
 import { Game_PersonEntity } from '../game/game.entity';
 import { Exclude } from 'class-transformer';
 
+/////////////////////////////////////////////////////////////////////////////
+/// UserEntity reflects database table.                                   ///
+///                                                                       ///
+/// Before handling password to database we encrypt it with bcrypt.       ///
+/// password field will be excluded unless we call repository relation.   ///
+///                                                                       ///
+/// token will be created when user registers or logs in to the system.   ///
+/////////////////////////////////////////////////////////////////////////////
+
 @Entity('Person')
 export class PersonEntity {
   @PrimaryGeneratedColumn('uuid') id: string;
@@ -39,6 +48,7 @@ export class PersonEntity {
     return await bcrypt.compareSync(attempt, this.password);
   }
 
+  // creates token from id and name, it will be created through jsonwebtoken and .env SECRET field
   private get token() {
     const { id, name } = this;
     return jwt.sign(
diff --git a/src/user/user.module.ts b/src/user/user.module.ts
index 6cb77a7b735df532d710febc33a4df53f264563a..85ec0ffd05dff0bd401da8d2807ed81ddbafdd57 100644
--- a/src/user/user.module.ts
+++ b/src/user/user.module.ts
@@ -3,11 +3,21 @@ import { TypeOrmModule } from '@nestjs/typeorm';
 
 import { UserController } from './user.controller';
 import { UserService } from './user.service';
-import { PersonEntity} from './user.entity';
-import { GameEntity } from '../game/game.entity';
+import { PersonEntity } from './user.entity';
+
+///////////////////////////
+/// Entities            ///
+/// - PersonEntity      ///
+///                     ///
+/// Controllers         ///
+/// - UserController    ///
+///                     ///
+/// Provider            ///
+/// - UserService       ///
+///////////////////////////
 
 @Module({
-  imports: [TypeOrmModule.forFeature([PersonEntity, GameEntity])],
+  imports: [TypeOrmModule.forFeature([PersonEntity])],
   controllers: [UserController],
   providers: [UserService],
 })
diff --git a/src/user/user.service.ts b/src/user/user.service.ts
index aa511e27802548a17449e7912144598e7eda3732..5e05634bb81e51d45d3241f3cb4d1fdfc26ee1b9 100644
--- a/src/user/user.service.ts
+++ b/src/user/user.service.ts
@@ -4,16 +4,23 @@ import { InjectRepository } from '@nestjs/typeorm';
 
 import { PersonEntity } from './user.entity';
 import { UserDTO } from './user.dto';
-import { GameEntity } from '../game/game.entity';
-import { GameDTO } from '../game/game.dto';
+
+///////////////////////////////////////////////////////////
+/// UserService contains functions for                  ///
+/// - Login                                             ///
+/// - Register                                          ///
+///                                                     ///
+/// Both functions return logged in users tokenObject   ///
+/// See more info in UserEntity.                        ///
+///                                                     ///
+/// See more info on DTO in it's respective file        ///
+///////////////////////////////////////////////////////////
 
 @Injectable()
 export class UserService {
   constructor(
     @InjectRepository(PersonEntity)
     private userRepository: Repository<PersonEntity>,
-    @InjectRepository(GameEntity)
-    private gameRepository: Repository<GameEntity>,
   ) {}
 
   async register(data: UserDTO) {
@@ -38,25 +45,4 @@ export class UserService {
     }
     return user.tokenObject();
   }
-
-  // liitytään peliin
-  async joinGame(game: GameDTO, data: UserDTO) {
-    try {
-      // etsi peli valinnan mukaan ja otetaan käyttäjän rooli kyseisestä pelistä talteen
-      const role = await this.gameRepository.findOne();
-      return role;
-    } catch (error) {
-      return error.message;
-    }
-  }
-
-  // liitytään factionii
-  async joinFaction(game: GameDTO, data: UserDTO): Promise<boolean> {
-    try {
-      // tarkistetaan factionin salasana
-      return true;
-    } catch (error) {
-      return error;
-    }
-  }
 }