diff --git a/src/game/game.controller.ts b/src/game/game.controller.ts
index bd6551ad714d9abbe172ef2a9be0d9301d8d79a6..433d570aef23d31a3da5b9aea8f9f778e08e4083 100644
--- a/src/game/game.controller.ts
+++ b/src/game/game.controller.ts
@@ -64,6 +64,11 @@ export class GameController {
     return this.gameservice.joinGroup(person, id);
   }
 
+  @Get('get-faction-members/:id')
+  async getFactionMembers(@Param('id') factionId) {
+    return this. gameservice.listFactionMembers(factionId)
+  }
+
   // param game ID is passed to @Roles
   @Put('promote/:id')
   @UseGuards(new AuthGuard())
diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts
index df93b55b574ce8590c728a82f14f928a3b16a6d4..6460193fce2481385a90560bb36d2317cbdc13a9 100644
--- a/src/game/game.dto.ts
+++ b/src/game/game.dto.ts
@@ -1,22 +1,15 @@
 import {
   IsNotEmpty,
   IsString,
-  IsDate,
   Length,
-  IsInt,
-  Min,
-  Max,
-  IsArray,
-  IsJSON,
   IsDateString,
   IsNumber,
-  IsUUID,
   Validate,
+  Min,
+  Max,
 } from 'class-validator';
-import { Timestamp } from 'typeorm';
-import { ObjectivePointEntity, GameEntity } from './game.entity';
-import { StringifyOptions } from 'querystring';
-import { Uuid, RoleValidation } from '../shared/custom-validation';
+import { ObjectivePointEntity } from './game.entity';
+import { CenterJSON } from '../shared/custom-validation';
 
 export class GameDTO {
   @IsString()
@@ -27,11 +20,8 @@ export class GameDTO {
   @Length(1, 255)
   desc: string;
   @IsNotEmpty()
-  //@IsJSON()
+  @Validate(CenterJSON)
   center: JSON;
-  //@IsJSON()
-  // doesn't accept with IsJSON, WIP to get validation for map and center
-  // IsJSON checks with json.parse, expecting string
   map?: JSON;
   nodesettings?: JSON;
   @IsDateString()
@@ -40,12 +30,30 @@ export class GameDTO {
   @IsDateString()
   @IsNotEmpty()
   enddate: string;
-  // custom validation for array length (arr>min, arr<max)
-  //@Validate(ArrayLength, [4, 8])
   factions?: FactionDTO[];
   objective_points?: FlagboxDTO[];
 }
 
+export class newGameDTO {
+  @IsString()
+  @IsNotEmpty()
+  @Length(3, 30)
+  name: string;
+  @IsString()
+  @IsNotEmpty()
+  @Length(1, 255)
+  desc: string;
+  @IsNotEmpty()
+  @Validate(CenterJSON)
+  center: JSON;
+  @IsDateString()
+  @IsNotEmpty()
+  startdate: string;
+  @IsDateString()
+  @IsNotEmpty()
+  enddate: string;
+}
+
 export class FactionDTO {
   @IsString()
   @IsNotEmpty()
@@ -66,10 +74,22 @@ export class FlagboxDTO {
 }
 
 export class FlagboxEventDTO {
+  @IsString()
+  @IsNotEmpty()
+  @Length(7)
   node_id: string;
-  owner: number;
-  action: number;
-  capture: number;
+  @IsNumber()
+  @Min(0)
+  @Max(3)
+  owner: number; // owner = 0, => first entry in faction db, owner = 1, => second entry etc
+  @IsNumber()
+  @Min(0)
+  @Max(3)
+  action: number; // 0=no capture ongoing, 1=captured, 2=capture ongoing
+  @IsNumber()
+  @Min(0)
+  @Max(3)
+  capture: number; // which faction is capturing, same logic as in owner with numbers
   oP_HistoryTimestamp?: string;
   objective_point?: ObjectivePointEntity;
 }
diff --git a/src/game/game.entity.ts b/src/game/game.entity.ts
index 3b36297c022992a43b7a4999fc9eccba1b493b27..036b31c8a3cf1d0343c8f31c691a50d749d97d0f 100644
--- a/src/game/game.entity.ts
+++ b/src/game/game.entity.ts
@@ -12,10 +12,8 @@ import {
 import { PersonEntity } from '../user/user.entity';
 import { GameGroupEntity } from './group.entity';
 import { FactionEntity } from './faction.entity';
-import {
-  MapDrawingEntity,
-  Game_Person_MapDrawingEntity,
-} from './coordinate.entity';
+import { MapDrawingEntity } from './coordinate.entity';
+import { TaskEntity } from '../task/task.entity';
 
 // table that stores all created games
 @Entity('Game')
@@ -40,6 +38,8 @@ export class GameEntity {
     objective_points => objective_points.game,
   )
   objective_points: ObjectivePointEntity[];
+  @OneToMany(type => TaskEntity, tasks => tasks.taskGame)
+  tasks: TaskEntity[];
 
   gameObject() {
     const { id, name } = this;
diff --git a/src/game/game.service.ts b/src/game/game.service.ts
index 571075290d777049db0a90e80a28b62e0f55e102..7c12bdd3dbdc96b21100db39ec0e5736f445db5d 100644
--- a/src/game/game.service.ts
+++ b/src/game/game.service.ts
@@ -8,7 +8,12 @@ import {
   ObjectivePointEntity,
   ObjectivePoint_HistoryEntity,
 } from './game.entity';
-import { GameDTO, FlagboxEventDTO, JoinFactionDTO } from './game.dto';
+import {
+  GameDTO,
+  FlagboxEventDTO,
+  JoinFactionDTO,
+  GameGroupDTO,
+} from './game.dto';
 import { PersonEntity } from '../user/user.entity';
 import { GameGroupEntity } from './group.entity';
 import { FactionEntity } from './faction.entity';
@@ -39,22 +44,18 @@ export class GameService {
   // create a new game
   async createNewGame(personId: PersonEntity, gameData: GameDTO) {
     // checks if a game with the same name exists already
-    const { name } = gameData;
-    if (await this.gameRepository.findOne({ where: { name } })) {
+    if (await this.gameRepository.findOne({ name: gameData.name })) {
       throw new HttpException('Game already exists', HttpStatus.BAD_REQUEST);
     }
     // else add the game to the database
-    const game = await this.gameRepository.create({
-      ...gameData,
-      factions: gameData.factions,
-    });
+    const game = await this.gameRepository.create(gameData);
     await this.gameRepository.insert(game);
+    // add gamePerson with role admin to the game
     const gamePerson = await this.game_PersonRepository.create({
-      faction: null,
       game: game,
       person: personId,
+      role: 'admin',
     });
-    gamePerson['role'] = 'admin';
     await this.game_PersonRepository.insert(gamePerson);
     return {
       message: 'New game added',
@@ -64,16 +65,13 @@ export class GameService {
   // edit already created game
   async editGame(id: string, gameData: GameDTO) {
     // checks if a game with the same name exists already
-    const { name } = gameData;
-    if (await this.gameRepository.findOne({ name: name, id: Not(id) })) {
+    if (
+      await this.gameRepository.findOne({ name: gameData.name, id: Not(id) })
+    ) {
       throw new HttpException('Game already exists', HttpStatus.BAD_REQUEST);
     }
     // update game entry in db
-    const updatedGame = await this.gameRepository.create({
-      ...gameData,
-      factions: null,
-      objective_points: null,
-    });
+    const updatedGame = await this.gameRepository.create(gameData);
     updatedGame['id'] = id;
     const gameId = await this.gameRepository.save(updatedGame);
 
@@ -131,7 +129,7 @@ export class GameService {
   }
 
   // checks the password, creates an entry in GamePerson table with associated role&faction
-  async createGroup(person, gameId, groupData) {
+  async createGroup(person, gameId, groupData: GameGroupDTO) {
     // check if the person already is in a group in this game
     const checkDuplicate = await this.game_PersonRepository.findOne({
       person: person,
@@ -235,6 +233,14 @@ export class GameService {
     this.notificationGateway.server.emit('flagbox', 'event update');
   }
 
+  async listFactionMembers(faction) {
+    return await this.game_PersonRepository.find({
+      where: { faction },
+      relations: ['person'],
+      order: { person: 'DESC' },
+    });
+  }
+
   async promotePlayer(body) {
     const gamepersonId = body.player;
     // get playerdata
diff --git a/src/shared/array-validation.ts b/src/shared/array-validation.ts
deleted file mode 100644
index 494ab42f06d0d067fcb115e6eebb63ef8dca2746..0000000000000000000000000000000000000000
--- a/src/shared/array-validation.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import {ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments} from "class-validator";
-import { Logger } from "@nestjs/common";
-
-// validates array length
-@ValidatorConstraint({ name: "arrayLength", async: true })
-export class ArrayLength implements ValidatorConstraintInterface {
-
-    validate(array: string[], args: ValidationArguments) {
-        Logger.log(array.length)
-        return array.length > args.constraints[0] && array.length < args.constraints[1]; // for async validations you must return a Promise<boolean> here
-    }
-
-    defaultMessage(args: ValidationArguments) { // here you can provide default error message if validation failed
-        return "Please input all passwords";
-    }
-
-}
\ No newline at end of file
diff --git a/src/shared/custom-validation.ts b/src/shared/custom-validation.ts
index a920e717e08a6981f5f2e82ddc5cf237ecddba11..13b96372e0b76a2897364baa15562edf383a2d81 100644
--- a/src/shared/custom-validation.ts
+++ b/src/shared/custom-validation.ts
@@ -30,3 +30,23 @@ export class RoleValidation implements ValidatorConstraintInterface {
     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/roles.guard.ts b/src/shared/roles.guard.ts
index e65916a94b3cc552259a63a9f5395e3118f95e1b..73693f9e1551da1b1b34056a665eb59c1211b3ef 100644
--- a/src/shared/roles.guard.ts
+++ b/src/shared/roles.guard.ts
@@ -32,9 +32,9 @@ export class RolesGuard implements CanActivate {
       return false;
     }
     const gameId = request.params.id;
-    const user = await this.getUserObject(request.headers.authorization);
+    request.user = await this.getUserObject(request.headers.authorization);
     const role = await this.game_PersonRepository.findOne({
-      person: user['id'],
+      person: request.user['id'],
       game: gameId,
     });
     // check that the role matches the criteria and that token is valid for this game
diff --git a/src/task/task.controller.ts b/src/task/task.controller.ts
index 6f272a0ce4c9d51e49ec3fbba78d666e283b0910..32766ffd6bc1c6f5f51a5234ae2024bc345582e2 100644
--- a/src/task/task.controller.ts
+++ b/src/task/task.controller.ts
@@ -7,35 +7,41 @@ import {
   UseGuards,
   Param,
 } from '@nestjs/common';
+
 import { TaskService } from './task.service';
+import { CreateTaskDTO, EditTaskDTO } from './task.dto';
+import { AuthGuard } from '../shared/auth.guard';
 import { Roles } from '../shared/roles.decorator';
 import { ValidationPipe } from '../shared/validation.pipe';
-import { TaskDTO } from './task.dto';
+import { User } from 'src/user/user.decorator';
 
 @Controller('task')
 export class TaskController {
   constructor(private taskService: TaskService) {}
 
-  /*   @Post('new')
-  @UseGuards(new AuthGuard())
+  // creates a new task if the user has admin role in the game
+  // :id is the id of the game
+  @Post('new-task/:id')
+  @Roles('admin')
   @UsePipes(new ValidationPipe())
-  async newGame(@User('id') person, @Body() body: GameDTO) {
-    return this.gameservice.createNewGame(person, body);
+  async newTask(@Param('id') id: string, @Body() task: CreateTaskDTO) {
+    return this.taskService.newTask(task);
   }
 
-  @Put(':id')
+  // edits a created task if the user has admin role in the game
+  // :id is the id of the game
+  @Post('edit-task/:id')
   @Roles('admin')
   @UsePipes(new ValidationPipe())
-  async editGame(@Param('id') id: string, @Body() body: GameDTO) {
-    return this.gameservice.editGame(id, body);
-  } */
+  async editTask(@Param('id') id: string, @Body() data: EditTaskDTO) {
+    return this.taskService.editTask(data);
+  }
 
-  // creates a new task if the user has admin role in the game
+  // lists all the tasks for the game if user has game_person entry
   // :id is the id of the game
-  @Post('new-task/:id')
-  //@Roles('admin')
-  @UsePipes(new ValidationPipe())
-  async newTask(@Param('id') id: string, @Body() task: TaskDTO) {
-    return this.taskService.newTask(task);
+  @Get('get-tasks/:id')
+  @Roles('soldier', 'factionleader', 'admin')
+  async fetchTasks(@User('id') person, @Param('id') id: string) {
+    return this.taskService.fetchTasks(person, id);
   }
 }
diff --git a/src/task/task.dto.ts b/src/task/task.dto.ts
index aa3238f888d0ad2975d4c6bab519421ddd41635d..3a363b5f95602d03294a5d256982558f19c1b937 100644
--- a/src/task/task.dto.ts
+++ b/src/task/task.dto.ts
@@ -1,30 +1,38 @@
 import {
   IsString,
   Length,
-  IsNumber,
   IsBoolean,
-  Min,
-  Max,
+  Validate,
+  IsUUID,
+  Equals,
 } from 'class-validator';
-import { FactionEntity } from 'src/game/faction.entity';
+import { FactionEntity } from '../game/faction.entity';
+import { GameEntity } from '../game/game.entity';
+import { Uuid } from '../shared/custom-validation';
 
-export class TaskDTO {
+export class CreateTaskDTO {
   @IsString()
   @Length(3, 31)
   taskName: string;
   @IsString()
   @Length(0, 255)
   taskDescription: string;
-  @IsNumber()
-  @Min(1)
-  @Max(99)
-  taskScore: number;
-  @IsString()
-  @Length(3, 31)
-  taskWinner?: string;
   @IsBoolean()
   taskIsActive: boolean;
-  // faction unique id
-  @IsString()
+  @Validate(Uuid)
   faction: FactionEntity;
+  @Equals(null)
+  taskWinner: FactionEntity;
+  // faction unique id
+  @IsUUID('4')
+  taskGame: GameEntity;
+}
+
+export class EditTaskDTO {
+  @IsUUID('4')
+  taskId: string;
+  @IsUUID('4')
+  taskWinner: FactionEntity;
+  @IsUUID('4')
+  taskGame: GameEntity;
 }
diff --git a/src/task/task.entity.ts b/src/task/task.entity.ts
index 1e7470102800e44bb60d68d73340eedb67e8b93e..e6fd61879325993ff34609d7e0b15f5dd89dfc18 100644
--- a/src/task/task.entity.ts
+++ b/src/task/task.entity.ts
@@ -1,15 +1,25 @@
-import { PrimaryGeneratedColumn, Column, Entity, ManyToOne } from 'typeorm';
+import {
+  PrimaryGeneratedColumn,
+  Column,
+  Entity,
+  ManyToOne,
+  JoinColumn,
+} from 'typeorm';
 import { FactionEntity } from 'src/game/faction.entity';
+import { GameEntity } from 'src/game/game.entity';
 
 @Entity('Task')
 export class TaskEntity {
   @PrimaryGeneratedColumn('uuid') taskId: string;
   @Column({ type: 'text' }) taskName: string;
   @Column({ type: 'text' }) taskDescription: string;
-  @Column({ type: 'float' }) taskScore: number;
-  @Column({ type: 'text' }) taskWinner: string;
   @Column({ type: 'bool' }) taskIsActive: boolean;
 
   @ManyToOne(type => FactionEntity, faction => faction.factionId)
   faction: FactionEntity;
+  @ManyToOne(type => FactionEntity, faction => faction.factionId)
+  taskWinner: FactionEntity;
+  @ManyToOne(type => GameEntity, game => game.id)
+  @JoinColumn({ name: 'taskGame' })
+  taskGame: GameEntity;
 }
diff --git a/src/task/task.module.ts b/src/task/task.module.ts
index ea321484169a3868f1f5d8d49f62574ab2253be8..12112f92a47ef2c30f0c130d15dba0d5b4c41126 100644
--- a/src/task/task.module.ts
+++ b/src/task/task.module.ts
@@ -4,9 +4,15 @@ import { TypeOrmModule } from '@nestjs/typeorm';
 import { TaskService } from './task.service';
 import { TaskController } from './task.controller';
 import { TaskEntity } from './task.entity';
+import { FactionEntity } from '../game/faction.entity';
+import { Game_PersonEntity } from '../game/game.entity';
+import { NotificationModule } from '../notifications/notifications.module';
 
 @Module({
-  imports: [TypeOrmModule.forFeature([TaskEntity])],
+  imports: [
+    TypeOrmModule.forFeature([TaskEntity, FactionEntity, Game_PersonEntity]),
+    NotificationModule,
+  ],
   controllers: [TaskController],
   providers: [TaskService],
 })
diff --git a/src/task/task.service.ts b/src/task/task.service.ts
index 830e6156222be1039e16c44cd50de1b453628991..3fbe8c51c827d516aedf97a789ccd9badd1cf50b 100644
--- a/src/task/task.service.ts
+++ b/src/task/task.service.ts
@@ -1,21 +1,102 @@
 import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
 import { Repository } from 'typeorm';
 import { InjectRepository } from '@nestjs/typeorm';
+
 import { TaskEntity } from './task.entity';
-import { TaskDTO } from './task.dto';
+import { CreateTaskDTO, EditTaskDTO } from './task.dto';
+import { FactionEntity } from '../game/faction.entity';
+import { Game_PersonEntity } from '../game/game.entity';
+import { NotificationGateway } from '../notifications/notifications.gateway';
 
 @Injectable()
 export class TaskService {
   constructor(
     @InjectRepository(TaskEntity)
     private taskRepository: Repository<TaskEntity>,
+    @InjectRepository(FactionEntity)
+    private factionRepository: Repository<FactionEntity>,
+    @InjectRepository(Game_PersonEntity)
+    private gamePersonRepository: Repository<Game_PersonEntity>,
+    private notificationGateway: NotificationGateway,
   ) {}
 
-  async newTask(task: TaskDTO) {
+  async newTask(task: CreateTaskDTO) {
+    // check if is not null, check that the faction exists in the game
+    if (
+      task.faction != null &&
+      !(await this.factionRepository.findOne({
+        factionId: task.faction.toString(),
+        game: task.taskGame,
+      }))
+    ) {
+      throw new HttpException('Faction not found', HttpStatus.BAD_REQUEST);
+    }
     const createdTask = await this.taskRepository.create(task);
     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() : 'global',
+      'new task',
+    );
     return {
       message: 'Task added',
     };
   }
+
+  async editTask(data: EditTaskDTO) {
+    const task = await this.taskRepository.findOne(data.taskId);
+    console.log(task);
+    // checks if task is already closed
+    if (!task.taskIsActive) {
+      throw new HttpException('Task is not active', HttpStatus.BAD_REQUEST);
+    }
+    // checks if faction is valid
+    if (
+      !(await this.factionRepository.findOne({
+        factionId: data.taskWinner.toString(),
+        game: data.taskGame,
+      }))
+    ) {
+      throw new HttpException('Faction not found', HttpStatus.BAD_REQUEST);
+    }
+    task.taskWinner = data.taskWinner;
+    task.taskIsActive = false;
+    await this.taskRepository.save(task);
+    return {
+      message: 'Task updated and closed',
+    };
+  }
+
+  async fetchTasks(user, taskGame) {
+    const gamePerson = await this.gamePersonRepository.findOne({
+      where: {
+        person: user,
+        game: taskGame,
+      },
+      relations: ['faction'],
+    });
+    if (gamePerson.role == 'admin') {
+      return await this.taskRepository.find({
+        where: { taskGame: taskGame },
+        relations: ['faction'],
+      });
+    } else {
+      return await this.taskRepository.find({
+        relations: ['faction'],
+        where: [
+          {
+            taskGame: taskGame,
+            faction: gamePerson.faction.factionId,
+            taskIsActive: true,
+          },
+          {
+            taskGame: taskGame,
+            faction: null,
+            taskIsActive: true,
+          },
+        ],
+      });
+    }
+  }
 }