From c63e4badf4e784eb4a9f43d7912e56d037711ac8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Elias=20M=C3=BCller?= <elias@elias-mueller.com>
Date: Sat, 2 Dec 2023 21:24:33 +0100
Subject: [PATCH] Added infrastructure code for game summaries

---
 .../minenet/minigames/instance/game/Game.java | 13 ++++++++-
 .../game/stateless/StatelessGame.java         |  5 ++--
 .../game/stateless/config/GameFactory.java    | 17 +++++------
 .../types/acidRain/AcidRainFactory.java       |  7 +++--
 .../types/backrooms/BackroomsFactory.java     |  7 +++--
 .../types/bedwars/BedwarsFactory.java         |  8 +++---
 .../types/bowSpleef/BowSpleefFactory.java     |  7 +++--
 .../types/deathcube/DeathcubeFactory.java     |  7 +++--
 .../types/elytraRace/ElytraRaceFactory.java   |  7 +++--
 .../types/minerun/MinerunFactory.java         |  7 +++--
 .../stateless/types/spleef/SpleefFactory.java |  8 +++---
 .../types/stickfight/StickFightFactory.java   |  7 +++--
 .../stateless/types/tntrun/TntRunFactory.java |  7 +++--
 .../towerdefense/TowerdefenseFactory.java     |  7 +++--
 .../TrafficLightRaceFactory.java              |  7 +++--
 .../minenet/minigames/instance/room/Room.java |  6 ++++
 .../mhsl/minenet/minigames/score/Score.java   |  9 +++---
 .../score/tournament/Tournament.java          | 28 +++++++++++++++++++
 18 files changed, 110 insertions(+), 54 deletions(-)
 create mode 100644 src/main/java/eu/mhsl/minenet/minigames/score/tournament/Tournament.java

diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/Game.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/Game.java
index b4c5646..cf120d6 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/Game.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/Game.java
@@ -5,6 +5,7 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
 import eu.mhsl.minenet.minigames.message.Icon;
 import eu.mhsl.minenet.minigames.message.type.ChatMessage;
+import eu.mhsl.minenet.minigames.score.Score;
 import eu.mhsl.minenet.minigames.util.CommonEventHandles;
 import eu.mhsl.minenet.minigames.instance.Spawnable;
 import eu.mhsl.minenet.minigames.instance.room.Room;
@@ -27,6 +28,7 @@ import java.util.logging.Logger;
 
 public abstract class Game extends MineNetInstance implements Spawnable {
 
+    protected Room parentRoom;
     protected boolean isRunning = false;
     protected boolean isBeforeBeginning = true;
 
@@ -48,10 +50,15 @@ public abstract class Game extends MineNetInstance implements Spawnable {
                 .addListener(ItemDropEvent.class, this::onItemDrop);
     }
 
+    public Game setParent(Room parentRoom) {
+        this.parentRoom = parentRoom;
+        return this;
+    }
+
     public static void initialize(GameFactory factory, List<Option<?>> options, Player owner) {
         try {
 
-            Game game = factory.manufacture(options);
+            Game game = factory.manufacture(Room.getRoom(owner).orElseThrow(), options);
             game.load();
             Room.getRoom(owner).orElseThrow().moveMembersToGame(game);
 
@@ -138,6 +145,10 @@ public abstract class Game extends MineNetInstance implements Spawnable {
         });
     }
 
+    protected void publishScore(Score score) {
+        this.parentRoom.getTournament().addScore(score);
+    }
+
     public boolean isRunning() {
         return isRunning;
     }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java
index 101db05..4509c35 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java
@@ -18,7 +18,7 @@ import java.util.concurrent.CompletableFuture;
 
 public class StatelessGame extends Game {
     private final String name;
-    private Score score;
+    private final Score score;
 
     private int timeLimit = 0;
     private int timePlayed = 0;
@@ -93,11 +93,12 @@ public class StatelessGame extends Game {
     public void stop() {
         isRunning = false;
         this.onStop();
+        this.publishScore(getScore());
 
         countdownUnload();
     }
 
-    protected void countdownUnload() {
+    private void countdownUnload() {
         new TitleMessage(Duration.ofSeconds(1)).appendStatic("Finish").send(getPlayers());
         scheduler().scheduleTask(this::unload, TaskSchedule.seconds(5), TaskSchedule.stop());
     }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/config/GameFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/config/GameFactory.java
index 58fd80c..6f15bb7 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/config/GameFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/config/GameFactory.java
@@ -1,7 +1,8 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.config;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -25,20 +26,20 @@ public interface GameFactory {
         return TranslatedComponent.byId("GameFactory#missingDescription");
     }
 
-    StatelessGame manufacture(Map<String, Option<?>> configuration) throws Exception;
+    Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception;
 
-    default StatelessGame manufacture(List<Option<?>> configuration) throws Exception {
-        if(configuration == null) return manufacture();
+    default Game manufacture(Room parent, List<Option<?>> configuration) throws Exception {
+        if(configuration == null) return manufacture(parent);
 
         Map<String, Option<?>> cnf = new HashMap<>();
         configuration.forEach(option -> cnf.put(option.getId(), option));
 
-        return manufacture(cnf);
+        return manufacture(parent, cnf);
     }
 
-    default StatelessGame manufacture() throws Exception {
-        if(this.configuration() == null) return manufacture(List.of());
+    default Game manufacture(Room parent) throws Exception {
+        if(this.configuration() == null) return manufacture(parent, List.of());
 
-        return manufacture(this.configuration().getAll());
+        return manufacture(parent, this.configuration().getAll());
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRainFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRainFactory.java
index 5cc0415..3f6964b 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRainFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRainFactory.java
@@ -1,8 +1,9 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -20,7 +21,7 @@ public class AcidRainFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) throws Exception {
-        return new AcidRain();
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
+        return new AcidRain().setParent(parent);
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/backrooms/BackroomsFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/backrooms/BackroomsFactory.java
index ace897b..73f3d7b 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/backrooms/BackroomsFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/backrooms/BackroomsFactory.java
@@ -1,8 +1,9 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 
 import java.util.Map;
@@ -14,7 +15,7 @@ public class BackroomsFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) throws Exception {
-        return new Backrooms();
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
+        return new Backrooms().setParent(parent);
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/bedwars/BedwarsFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/bedwars/BedwarsFactory.java
index 479cae5..0de3d94 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/bedwars/BedwarsFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/bedwars/BedwarsFactory.java
@@ -1,11 +1,11 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
-import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -34,7 +34,7 @@ public class BedwarsFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) throws Exception {
-        return new Bedwars();
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
+        return new Bedwars().setParent(parent);
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/bowSpleef/BowSpleefFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/bowSpleef/BowSpleefFactory.java
index 1e69a08..86bc7f7 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/bowSpleef/BowSpleefFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/bowSpleef/BowSpleefFactory.java
@@ -1,8 +1,9 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -20,7 +21,7 @@ public class BowSpleefFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) throws Exception {
-        return new BowSpleef();
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
+        return new BowSpleef().setParent(parent);
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/deathcube/DeathcubeFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/deathcube/DeathcubeFactory.java
index f34aa0d..8d16b2c 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/deathcube/DeathcubeFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/deathcube/DeathcubeFactory.java
@@ -1,10 +1,11 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -32,8 +33,8 @@ public class DeathcubeFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) {
-        return new Deathcube(configuration.get("radius").getAsInt(), configuration.get("height").getAsInt(), configuration.get("percentage").getAsInt(), configuration.get("pvpEnabled").getAsInt());
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
+        return new Deathcube(configuration.get("radius").getAsInt(), configuration.get("height").getAsInt(), configuration.get("percentage").getAsInt(), configuration.get("pvpEnabled").getAsInt()).setParent(parent);
     }
 
     @Override
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRaceFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRaceFactory.java
index 04533f8..c805d47 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRaceFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRaceFactory.java
@@ -1,10 +1,11 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -28,7 +29,7 @@ public class ElytraRaceFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) throws Exception {
-        return new ElytraRace(configuration.get("ringCount").getAsInt());
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
+        return new ElytraRace(configuration.get("ringCount").getAsInt()).setParent(parent);
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/minerun/MinerunFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/minerun/MinerunFactory.java
index 394b692..cb0d03a 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/minerun/MinerunFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/minerun/MinerunFactory.java
@@ -1,10 +1,11 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -25,8 +26,8 @@ public class MinerunFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) {
-        return new Minerun(configuration.get("width").getAsInt(), configuration.get("length").getAsInt(), configuration.get("percentage").getAsInt());
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
+        return new Minerun(configuration.get("width").getAsInt(), configuration.get("length").getAsInt(), configuration.get("percentage").getAsInt()).setParent(parent);
     }
 
     @Override
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/spleef/SpleefFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/spleef/SpleefFactory.java
index cfa8522..e238957 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/spleef/SpleefFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/spleef/SpleefFactory.java
@@ -1,16 +1,16 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
-import java.util.List;
 import java.util.Map;
 
 public class SpleefFactory implements GameFactory {
@@ -43,7 +43,7 @@ public class SpleefFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) throws Exception {
-        return new Spleef(configuration.get("radius").getAsInt(), configuration.get("stackCount").getAsInt());
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
+        return new Spleef(configuration.get("radius").getAsInt(), configuration.get("stackCount").getAsInt()).setParent(parent);
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/stickfight/StickFightFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/stickfight/StickFightFactory.java
index 14ccce7..f3be090 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/stickfight/StickFightFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/stickfight/StickFightFactory.java
@@ -1,6 +1,6 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
@@ -8,6 +8,7 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOp
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MaximalPlayeramountGameRestriction;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -38,8 +39,8 @@ public class StickFightFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) {
-        return new Stickfight();
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
+        return new Stickfight().setParent(parent);
     }
 
     @Override
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tntrun/TntRunFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tntrun/TntRunFactory.java
index 59c6d9c..0bc3dd4 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tntrun/TntRunFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tntrun/TntRunFactory.java
@@ -1,10 +1,11 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.tntrun;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -29,7 +30,7 @@ public class TntRunFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) throws Exception {
-        return new TntRun(configuration.get("radius").getAsInt(), configuration.get("levels").getAsInt());
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
+        return new TntRun(configuration.get("radius").getAsInt(), configuration.get("levels").getAsInt()).setParent(parent);
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/towerdefense/TowerdefenseFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/towerdefense/TowerdefenseFactory.java
index b63e37d..1c215b5 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/towerdefense/TowerdefenseFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/towerdefense/TowerdefenseFactory.java
@@ -1,8 +1,9 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -24,7 +25,7 @@ public class TowerdefenseFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) {
-        return new Towerdefense();
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
+        return new Towerdefense().setParent(parent);
     }
 }
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/trafficlightrace/TrafficLightRaceFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/trafficlightrace/TrafficLightRaceFactory.java
index 22f7884..83eaded 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/trafficlightrace/TrafficLightRaceFactory.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/trafficlightrace/TrafficLightRaceFactory.java
@@ -1,10 +1,11 @@
 package eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace;
 
-import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
+import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
 import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
+import eu.mhsl.minenet.minigames.instance.room.Room;
 import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
 import net.minestom.server.item.Material;
 
@@ -24,8 +25,8 @@ public class TrafficLightRaceFactory implements GameFactory {
     }
 
     @Override
-    public StatelessGame manufacture(Map<String, Option<?>> configuration) {
-        return new TrafficLightRace(configuration.get("width").getAsInt(), configuration.get("length").getAsInt());
+    public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
+        return new TrafficLightRace(configuration.get("width").getAsInt(), configuration.get("length").getAsInt()).setParent(parent);
     }
 
     @Override
diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/room/Room.java b/src/main/java/eu/mhsl/minenet/minigames/instance/room/Room.java
index b52dbb4..de4392f 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/instance/room/Room.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/instance/room/Room.java
@@ -5,6 +5,7 @@ import eu.mhsl.minenet.minigames.instance.MineNetInstance;
 import eu.mhsl.minenet.minigames.instance.game.Game;
 import eu.mhsl.minenet.minigames.message.Icon;
 import eu.mhsl.minenet.minigames.message.type.ChatMessage;
+import eu.mhsl.minenet.minigames.score.tournament.Tournament;
 import eu.mhsl.minenet.minigames.util.CommonEventHandles;
 import eu.mhsl.minenet.minigames.util.MoveInstance;
 import eu.mhsl.minenet.minigames.instance.Spawnable;
@@ -83,6 +84,7 @@ public class Room extends MineNetInstance implements Spawnable {
     public final UUID uuid = UUID.randomUUID();
     public final boolean apiDriven;
     private GameSelector gameSelector;
+    private final Tournament tournament = new Tournament();
     private Room(Player owner) {
         super(Dimension.THE_END.DIMENSION);
         this.apiDriven = false;
@@ -152,6 +154,10 @@ public class Room extends MineNetInstance implements Spawnable {
                 .collect(Collectors.toSet());
     }
 
+    public Tournament getTournament() {
+        return this.tournament;
+    }
+
     @Override
     public Pos getSpawn() {
         return new Pos(0.5, 50, 0.5);
diff --git a/src/main/java/eu/mhsl/minenet/minigames/score/Score.java b/src/main/java/eu/mhsl/minenet/minigames/score/Score.java
index 7ad4c15..6b758a2 100644
--- a/src/main/java/eu/mhsl/minenet/minigames/score/Score.java
+++ b/src/main/java/eu/mhsl/minenet/minigames/score/Score.java
@@ -18,7 +18,7 @@ public abstract class Score {
     private int ignoreLastPlayers = 0;
     private boolean isClosed = false;
     protected Game instance;
-    private List<Set<Player>> scores = new ArrayList<>();
+    private final List<Set<Player>> scores = new ArrayList<>();
 
     public Score() {}
 
@@ -40,7 +40,7 @@ public abstract class Score {
         if(instance.getPlayers().isEmpty()) return;
         if(resultCount() >= instance.getPlayers().size() - ignoreLastPlayers) {
             if(ignoreLastPlayers > 0) {
-                insertRemainingPlayers(instance.getPlayers().stream().filter(player -> !hasResult(player)).collect(Collectors.toSet()));
+                insertRemainingPlayers(instance.getPlayers());
             }
             setDone();
         }
@@ -55,9 +55,8 @@ public abstract class Score {
         this.checkGameEnd();
     }
 
-    private void insertRemainingPlayers(Set<Player> p) {
-        if(p.stream().anyMatch(this::hasResult)) return;
-        this.insertResultImplementation((p));
+    private void insertRemainingPlayers(Set<Player> players) {
+        this.insertResultImplementation(players.stream().filter(p -> !hasResult(p)).collect(Collectors.toSet()));
     }
 
     public boolean hasResult(Player p) {
diff --git a/src/main/java/eu/mhsl/minenet/minigames/score/tournament/Tournament.java b/src/main/java/eu/mhsl/minenet/minigames/score/tournament/Tournament.java
new file mode 100644
index 0000000..08e086b
--- /dev/null
+++ b/src/main/java/eu/mhsl/minenet/minigames/score/tournament/Tournament.java
@@ -0,0 +1,28 @@
+package eu.mhsl.minenet.minigames.score.tournament;
+
+import eu.mhsl.minenet.minigames.score.Score;
+import net.minestom.server.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class Tournament {
+    private final List<Score> scores = new ArrayList<>();
+
+    public void addScore(Score score) {
+        this.scores.add(score);
+    }
+
+    public int getScoreCount() {
+        return this.scores.size();
+    }
+
+    public void reset() {
+        this.scores.clear();
+    }
+
+    public List<Map<Player, Integer>> getScores() {
+        return null;
+    }
+}