diff --git a/src/main/java/com/example/demo/controller/GameDefinitionController.java b/src/main/java/com/example/demo/controller/GameDefinitionController.java
index 18b333e2a4e4525a68a970f6ca105a1802179e39..00ef5d0c35ce6d4c2bee5fa3e3a8e7c4f07f8d4e 100644
--- a/src/main/java/com/example/demo/controller/GameDefinitionController.java
+++ b/src/main/java/com/example/demo/controller/GameDefinitionController.java
@@ -1,5 +1,6 @@
 package com.example.demo.controller;
 
+import com.example.demo.dto.TrainingDefinitionDto;
 import com.example.demo.dto.input.GameDefinitionCreateDto;
 import com.example.demo.service.GameDefinitionService;
 import io.swagger.annotations.Api;
@@ -40,8 +41,9 @@ public class GameDefinitionController {
     @ApiOperation(value = "Create a new game definition")
     @ApiResponses(value = {@ApiResponse(code = 200, message = "New game definition created"),
                            @ApiResponse(code = 500, message = "Unexpected application error")})
-    public GameDefinitionCreateDto createGameLevel(@ApiParam(value = "Game definition", required = true) @RequestBody(required = true)
-                                                       List<GameDefinitionCreateDto> gameDefinition) {
-        return gameDefinitionService.createGameDefinition(gameDefinition);
+    public GameDefinitionCreateDto createGameLevel(
+        @ApiParam(value = "Game definition", required = true) @RequestBody(required = true)
+            TrainingDefinitionDto trainingDefinitionDto) {
+        return gameDefinitionService.createGameDefinition(trainingDefinitionDto);
     }
 }
diff --git a/src/main/java/com/example/demo/domain/BaseLevel.java b/src/main/java/com/example/demo/domain/BaseLevel.java
index 37f6ddf3207333569f19d0aa0562210db44128d4..7d62c686aede510a1515506e43652bf9cb677fe2 100644
--- a/src/main/java/com/example/demo/domain/BaseLevel.java
+++ b/src/main/java/com/example/demo/domain/BaseLevel.java
@@ -28,6 +28,9 @@ public abstract class BaseLevel {
     @ManyToOne(fetch = FetchType.LAZY)
     private UnityLevel unityLevel;
 
+    @ManyToOne(fetch = FetchType.LAZY)
+    private TrainingDefinition trainingDefinition;
+
     public String getTitle() {
         return title;
     }
@@ -76,6 +79,14 @@ public abstract class BaseLevel {
         this.unityLevel = unityLevel;
     }
 
+    public TrainingDefinition getTrainingDefinition() {
+        return trainingDefinition;
+    }
+
+    public void setTrainingDefinition(TrainingDefinition trainingDefinition) {
+        this.trainingDefinition = trainingDefinition;
+    }
+
     @Override
     public String toString() {
         return "BaseLevel{" + "title='" + title + '\'' + ", estimatedDuration='" + estimatedDuration + '\'' +
diff --git a/src/main/java/com/example/demo/domain/TrainingDefinition.java b/src/main/java/com/example/demo/domain/TrainingDefinition.java
index 79b634f7759fd658eea20166bff1b0c2818d8af9..243ce4da272a7c89c149036e4b1fbdd7c4f61895 100644
--- a/src/main/java/com/example/demo/domain/TrainingDefinition.java
+++ b/src/main/java/com/example/demo/domain/TrainingDefinition.java
@@ -1,10 +1,15 @@
 package com.example.demo.domain;
 
+import javax.persistence.CascadeType;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
 import java.time.LocalDateTime;
 import java.util.Arrays;
+import java.util.List;
 
 @Entity
 public class TrainingDefinition {
@@ -23,6 +28,10 @@ public class TrainingDefinition {
     private byte[] outcomes;
     private byte[] prerequisites;
 
+    @OrderBy
+    @OneToMany(mappedBy = "trainingDefinition", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+    private List<BaseLevel> levels;
+
     public Long getId() {
         return id;
     }
@@ -103,6 +112,14 @@ public class TrainingDefinition {
         this.prerequisites = prerequisites;
     }
 
+    public List<BaseLevel> getLevels() {
+        return levels;
+    }
+
+    public void setLevels(List<BaseLevel> levels) {
+        this.levels = levels;
+    }
+
     @Override
     public String toString() {
         return "TrainingDefinition{" + "id=" + id + ", title='" + title + '\'' + ", lastEdited=" + lastEdited +
diff --git a/src/main/java/com/example/demo/domain/UnityLevel.java b/src/main/java/com/example/demo/domain/UnityLevel.java
index fe50f737a8a623c80bc16f3e81f72d3b884d3711..1b351a4255b7a5668824a76029113c1685acf40f 100644
--- a/src/main/java/com/example/demo/domain/UnityLevel.java
+++ b/src/main/java/com/example/demo/domain/UnityLevel.java
@@ -12,13 +12,13 @@ public class UnityLevel extends BaseLevel {
 
     @OrderBy
     @OneToMany(mappedBy = "unityLevel", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
-    private List<BaseLevel> subLevels;
+    private List<GameLevel> subLevels;
 
-    public List<BaseLevel> getSubLevels() {
+    public List<GameLevel> getSubLevels() {
         return subLevels;
     }
 
-    public void setSubLevels(List<BaseLevel> subLevels) {
+    public void setSubLevels(List<GameLevel> subLevels) {
         this.subLevels = subLevels;
     }
 }
diff --git a/src/main/java/com/example/demo/dto/BaseLevelDto.java b/src/main/java/com/example/demo/dto/BaseLevelDto.java
index b00c134c7f363a25e3fdc23ef58a29ec7d5a13e6..d53d125c4adb89070792e186233212c7b83479ab 100644
--- a/src/main/java/com/example/demo/dto/BaseLevelDto.java
+++ b/src/main/java/com/example/demo/dto/BaseLevelDto.java
@@ -1,5 +1,7 @@
 package com.example.demo.dto;
 
+import com.example.demo.dto.input.LevelType;
+
 import java.io.Serializable;
 
 public abstract class BaseLevelDto implements Serializable {
@@ -9,6 +11,7 @@ public abstract class BaseLevelDto implements Serializable {
     private Integer order;
     private String estimatedDuration;
     private Long maxScore;
+    private LevelType type;
 
     public Long getId() {
         return id;
@@ -50,6 +53,14 @@ public abstract class BaseLevelDto implements Serializable {
         this.maxScore = maxScore;
     }
 
+    public LevelType getType() {
+        return type;
+    }
+
+    public void setType(LevelType type) {
+        this.type = type;
+    }
+
     @Override
     public String toString() {
         return "BaseLevelDto{" + "id=" + id + ", title='" + title + '\'' + ", order=" + order +
diff --git a/src/main/java/com/example/demo/dto/TrainingDefinitionDto.java b/src/main/java/com/example/demo/dto/TrainingDefinitionDto.java
index 8db7e68bee7414e4c4ae66d79c9ca9c04ff29cd0..b2b16036d2503f01318d3881ac0f5f945852ee47 100644
--- a/src/main/java/com/example/demo/dto/TrainingDefinitionDto.java
+++ b/src/main/java/com/example/demo/dto/TrainingDefinitionDto.java
@@ -1,8 +1,11 @@
 package com.example.demo.dto;
 
+import com.example.demo.dto.input.GameDefinitionCreateDto;
+
 import java.io.Serializable;
 import java.time.LocalDateTime;
 import java.util.Arrays;
+import java.util.List;
 
 public class TrainingDefinitionDto implements Serializable {
 
@@ -17,6 +20,8 @@ public class TrainingDefinitionDto implements Serializable {
     private byte[] outcomes;
     private byte[] prerequisites;
 
+    private List<GameDefinitionCreateDto> levels;
+
     public Long getId() {
         return id;
     }
@@ -97,6 +102,14 @@ public class TrainingDefinitionDto implements Serializable {
         this.prerequisites = prerequisites;
     }
 
+    public List<GameDefinitionCreateDto> getLevels() {
+        return levels;
+    }
+
+    public void setLevels(List<GameDefinitionCreateDto> levels) {
+        this.levels = levels;
+    }
+
     @Override
     public String toString() {
         return "TrainingDefinitionDto{" + "id=" + id + ", title='" + title + '\'' + ", lastEdited=" + lastEdited +
diff --git a/src/main/java/com/example/demo/dto/UnityLevelDto.java b/src/main/java/com/example/demo/dto/UnityLevelDto.java
index be0ac4affb6fc1d9e74835ecaf6abba7c6a28d01..aec241f7fc8c584fa73ce937a130f56b57ba7296 100644
--- a/src/main/java/com/example/demo/dto/UnityLevelDto.java
+++ b/src/main/java/com/example/demo/dto/UnityLevelDto.java
@@ -4,7 +4,7 @@ import java.util.List;
 
 public class UnityLevelDto extends BaseLevelDto {
 
-    // TODO any class extending BaseLevel could be used here - this piece of art is here in order to make mapstruct happy
+    // TODO any class extending BaseLevel probable should be used here - this piece of art is here in order to make mapstruct happy
     private List<GameLevelDto> subLevels;
 
     public List<GameLevelDto> getSubLevels() {
diff --git a/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java b/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java
index c19d1608415ba0e33d96d947615fddc938f7d334..5beacd53d101a726e7ac8df9390aa4f3daa622b6 100644
--- a/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java
+++ b/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java
@@ -1,5 +1,8 @@
 package com.example.demo.dto.input;
 
+import com.example.demo.dto.AttachmentDto;
+import com.example.demo.dto.HintDto;
+
 import java.util.List;
 
 public class GameDefinitionCreateDto {
@@ -7,6 +10,24 @@ public class GameDefinitionCreateDto {
     private String title;
     private Integer order;
     private LevelType type;
+
+    // assessment level fields
+    private String assessmentType;
+
+    // game level fields
+    private String content;
+    private boolean solutionPenalized;
+    private String flag;
+    private String solution;
+    private Long incorrectFlagLimit;
+
+    private List<AttachmentDto> attachments;
+    private List<HintDto> hints;
+
+    // info level fields
+    // currently none special
+
+    // unity level fields
     private List<? extends GameDefinitionCreateDto> subLevels;
 
     public Long getId() {
@@ -41,6 +62,70 @@ public class GameDefinitionCreateDto {
         this.type = type;
     }
 
+    public String getAssessmentType() {
+        return assessmentType;
+    }
+
+    public void setAssessmentType(String assessmentType) {
+        this.assessmentType = assessmentType;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public boolean isSolutionPenalized() {
+        return solutionPenalized;
+    }
+
+    public void setSolutionPenalized(boolean solutionPenalized) {
+        this.solutionPenalized = solutionPenalized;
+    }
+
+    public String getFlag() {
+        return flag;
+    }
+
+    public void setFlag(String flag) {
+        this.flag = flag;
+    }
+
+    public String getSolution() {
+        return solution;
+    }
+
+    public void setSolution(String solution) {
+        this.solution = solution;
+    }
+
+    public Long getIncorrectFlagLimit() {
+        return incorrectFlagLimit;
+    }
+
+    public void setIncorrectFlagLimit(Long incorrectFlagLimit) {
+        this.incorrectFlagLimit = incorrectFlagLimit;
+    }
+
+    public List<AttachmentDto> getAttachments() {
+        return attachments;
+    }
+
+    public void setAttachments(List<AttachmentDto> attachments) {
+        this.attachments = attachments;
+    }
+
+    public List<HintDto> getHints() {
+        return hints;
+    }
+
+    public void setHints(List<HintDto> hints) {
+        this.hints = hints;
+    }
+
     public List<? extends GameDefinitionCreateDto> getSubLevels() {
         return subLevels;
     }
diff --git a/src/main/java/com/example/demo/mapper/BeanMapper.java b/src/main/java/com/example/demo/mapper/BeanMapper.java
index 3707c0d02ff2030bcc9a05bb87cc809a73777226..ecc34bf7496939dcf1af9bac3126cef3aac8fe40 100644
--- a/src/main/java/com/example/demo/mapper/BeanMapper.java
+++ b/src/main/java/com/example/demo/mapper/BeanMapper.java
@@ -5,6 +5,7 @@ import com.example.demo.domain.Attachment;
 import com.example.demo.domain.GameLevel;
 import com.example.demo.domain.Hint;
 import com.example.demo.domain.InfoLevel;
+import com.example.demo.domain.TrainingDefinition;
 import com.example.demo.domain.UnityLevel;
 import com.example.demo.dto.AssessmentLevelDto;
 import com.example.demo.dto.AttachmentDto;
@@ -15,8 +16,11 @@ import com.example.demo.dto.HintDto;
 import com.example.demo.dto.InfoLevelCreateDto;
 import com.example.demo.dto.InfoLevelDto;
 import com.example.demo.dto.InfoLevelUpdateDto;
+import com.example.demo.dto.TrainingDefinitionDto;
 import com.example.demo.dto.UnityLevelDto;
+import com.example.demo.dto.input.GameDefinitionCreateDto;
 import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
 
@@ -27,22 +31,29 @@ public interface BeanMapper {
 
     AssessmentLevelDto toDto(AssessmentLevel assessmentLevel);
 
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
     AssessmentLevel toEntity(AssessmentLevelDto assessmentLevel);
 
     GameLevelDto toDto(GameLevel gameLevel);
 
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
     GameLevel toEntity(GameLevelDto gameLevel);
 
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
     GameLevel toEntity(GameLevelCreateDto gameLevel);
 
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
     GameLevel toEntity(GameLevelUpdateDto gameLevel);
 
     InfoLevelDto toDto(InfoLevel infoLevel);
 
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
     InfoLevel toEntity(InfoLevelDto infoLevel);
 
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
     InfoLevel toEntity(InfoLevelCreateDto gameLevel);
 
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
     InfoLevel toEntity(InfoLevelUpdateDto gameLevel);
 
     HintDto toDto(Hint hint);
@@ -55,5 +66,23 @@ public interface BeanMapper {
 
     UnityLevelDto toDto(UnityLevel unityLevel);
 
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
     UnityLevel toEntity(UnityLevelDto unityLevel);
+
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
+    AssessmentLevel toAssessmentLevel(GameDefinitionCreateDto gameDefinitionCreateDto);
+
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
+    InfoLevel toInfoLevel(GameDefinitionCreateDto gameDefinitionCreateDto);
+
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
+    GameLevel toGameLevel(GameDefinitionCreateDto gameDefinitionCreateDto);
+
+    @Mapping(target = "orderInTrainingDefinition", source = "order")
+    UnityLevel toUnityLevel(GameDefinitionCreateDto gameDefinitionCreateDto);
+
+    @Mapping(target = "levels", ignore = true)
+    TrainingDefinition toEntity(TrainingDefinitionDto trainingDefinition);
+
+    TrainingDefinitionDto toDto(TrainingDefinition trainingDefinition);
 }
diff --git a/src/main/java/com/example/demo/repository/TrainingDefinitionRepository.java b/src/main/java/com/example/demo/repository/TrainingDefinitionRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..19236c160670fba2adf1ee1935dc282a4edd07c8
--- /dev/null
+++ b/src/main/java/com/example/demo/repository/TrainingDefinitionRepository.java
@@ -0,0 +1,7 @@
+package com.example.demo.repository;
+
+import com.example.demo.domain.TrainingDefinition;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface TrainingDefinitionRepository extends JpaRepository<TrainingDefinition, Long> {
+}
diff --git a/src/main/java/com/example/demo/service/GameDefinitionService.java b/src/main/java/com/example/demo/service/GameDefinitionService.java
index 5dc2624f6f55410c81d9631ef5f08274dbc971c8..1cc5fd617f9ee0c6b4bedaae14673c9bb58c7d76 100644
--- a/src/main/java/com/example/demo/service/GameDefinitionService.java
+++ b/src/main/java/com/example/demo/service/GameDefinitionService.java
@@ -3,14 +3,21 @@ package com.example.demo.service;
 import com.example.demo.domain.AssessmentLevel;
 import com.example.demo.domain.BaseLevel;
 import com.example.demo.domain.GameLevel;
+import com.example.demo.domain.InfoLevel;
+import com.example.demo.domain.TrainingDefinition;
 import com.example.demo.domain.UnityLevel;
+import com.example.demo.dto.TrainingDefinitionDto;
 import com.example.demo.dto.input.GameDefinitionCreateDto;
 import com.example.demo.dto.input.LevelType;
+import com.example.demo.mapper.BeanMapper;
 import com.example.demo.repository.AssessmentLevelRepository;
 import com.example.demo.repository.GameLevelRepository;
+import com.example.demo.repository.InfoLevelRepository;
+import com.example.demo.repository.TrainingDefinitionRepository;
 import com.example.demo.repository.UnityLevelRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -27,37 +34,43 @@ public class GameDefinitionService {
     @Autowired
     private GameLevelRepository gameLevelRepository;
 
-    public GameDefinitionCreateDto createGameDefinition(List<GameDefinitionCreateDto> gameDefinition) {
+    @Autowired
+    private InfoLevelRepository infoLevelRepository;
 
-        for (GameDefinitionCreateDto gameDefinitionCreateDto : gameDefinition) {
-            if (gameDefinitionCreateDto.getType() == LevelType.assessment) {
-                AssessmentLevel assessmentLevel = new AssessmentLevel();
-                assessmentLevel.setTitle(gameDefinitionCreateDto.getTitle());
-                assessmentLevel.setOrderInTrainingDefinition(gameDefinitionCreateDto.getOrder());
+    @Autowired
+    private TrainingDefinitionRepository trainingDefinitionRepository;
 
-                assessmentLevelRepository.save(assessmentLevel);
-            } else if (gameDefinitionCreateDto.getType() == LevelType.unity) {
-                UnityLevel unityLevel = new UnityLevel();
-                unityLevel.setTitle(gameDefinitionCreateDto.getTitle());
-                unityLevel.setOrderInTrainingDefinition(gameDefinitionCreateDto.getOrder());
+    public GameDefinitionCreateDto createGameDefinition(TrainingDefinitionDto trainingDefinitionDto) {
 
-                unityLevelRepository.save(unityLevel);
+        TrainingDefinition trainingDefinition = BeanMapper.INSTANCE.toEntity(trainingDefinitionDto);
+        trainingDefinitionRepository.save(trainingDefinition);
 
 
-                List<BaseLevel> subLevels = new ArrayList<>();
-                for (GameDefinitionCreateDto subLevel : gameDefinitionCreateDto.getSubLevels()) {
-                    if (subLevel.getType() == LevelType.game) {
-                        GameLevel gameLevel = new GameLevel();
-                        gameLevel.setTitle(subLevel.getTitle());
-                        gameLevel.setOrderInTrainingDefinition(subLevel.getOrder());
-                        gameLevel.setUnityLevel(unityLevel);
+        // TODO refactor this, it's really ugly
+        for (GameDefinitionCreateDto gameDefinitionCreateDto : trainingDefinitionDto.getLevels()) {
+            if (gameDefinitionCreateDto.getType() == LevelType.assessment) {
+                AssessmentLevel assessmentLevel = BeanMapper.INSTANCE.toAssessmentLevel(gameDefinitionCreateDto);
+                assessmentLevel.setTrainingDefinition(trainingDefinition);
+                assessmentLevelRepository.save(assessmentLevel);
+            } else if (gameDefinitionCreateDto.getType() == LevelType.unity) {
+                UnityLevel unityLevel = BeanMapper.INSTANCE.toUnityLevel(gameDefinitionCreateDto);
+                unityLevel.setTrainingDefinition(trainingDefinition);
 
-                        subLevels.add(gameLevel);
-                        gameLevelRepository.save(gameLevel);
-                    }
+                if (!CollectionUtils.isEmpty(unityLevel.getSubLevels())) {
+                    unityLevel.getSubLevels().forEach(x -> x.setUnityLevel(unityLevel));
+                    unityLevel.getSubLevels().forEach(x -> x.setTrainingDefinition(trainingDefinition));
                 }
-                unityLevel.setSubLevels(subLevels);
+
                 unityLevelRepository.save(unityLevel);
+            } else if (gameDefinitionCreateDto.getType() == LevelType.game) {
+                GameLevel gameLevel = BeanMapper.INSTANCE.toGameLevel(gameDefinitionCreateDto);
+                gameLevel.setTrainingDefinition(trainingDefinition);
+                gameLevelRepository.save(gameLevel);
+
+            } else if (gameDefinitionCreateDto.getType() == LevelType.info) {
+                InfoLevel infoLevel = BeanMapper.INSTANCE.toInfoLevel(gameDefinitionCreateDto);
+                infoLevel.setTrainingDefinition(trainingDefinition);
+                infoLevelRepository.save(infoLevel);
             }
         }