diff --git a/src/GameServer.spec.ts b/src/GameServer.spec.ts
new file mode 100644
index 0000000..b105065
--- /dev/null
+++ b/src/GameServer.spec.ts
@@ -0,0 +1,106 @@
+// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
+// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
+
+import {expect} from "chai";
+import {GameServer} from "./GameServer";
+import { Direction, MazeMap, MazeTile } from "./MazeMap";
+// import { describe, it } from "mocha";
+
+function createTrivialMap(): MazeMap
+{
+    const maze = new MazeMap("lvl1");
+    let tile = new MazeTile("1");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.bottom);
+    maze.layout.push([tile]);
+    tile = new MazeTile("2");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.bottom);
+    maze.layout[0].push(tile);
+
+    tile = new MazeTile("3");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.top);
+    maze.layout.push([tile]);
+    tile = new MazeTile("4");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.top);
+    maze.layout[1].push(tile);
+
+    return maze;
+}
+
+function createGameServer(): GameServer
+{
+    const server = new GameServer();
+    server.addMap(createTrivialMap());
+    return server;
+}
+
+describe("Scenario: Starting the game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    describe("when a user starts an existing valid level", function(){
+        const games = createGameServer();
+        const position = games.startGame(userID, mapID);
+
+        it("then the start position must exist", function(){
+            expect(position).to.be.not.null;
+        });
+
+        it("then the start position must be remembered for the user", function(){
+            const current = games.currentPosition(userID);
+            expect(current.id).to.equal(position.id);
+        });
+    });
+});
+
+describe("Scenario: Navigating in ongoing game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    const games = createGameServer();
+    const startPosition = games.startGame(userID, mapID);
+
+    describe("When player navigates in existing direction", function(){
+        const naviagtionDirection = startPosition.paths[0];
+        const nextPosition = games.navigate(userID, startPosition.id, naviagtionDirection);
+        it("then the new position has to have a different id", function(){
+            expect(nextPosition.id).to.not.equal(startPosition.id);
+        });
+
+        it("then the new position must have pathway back", function(){
+            let hasOpposite:boolean = false;
+            for (const dir of nextPosition.paths) {
+                switch (dir) {
+                    case Direction.top:
+                        if(naviagtionDirection === Direction.bottom)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.left:
+                        if(naviagtionDirection === Direction.right)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.bottom:
+                        if(naviagtionDirection === Direction.top)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.right:
+                        if(naviagtionDirection === Direction.left)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    default:
+                        throw new Error(`Direction "${dir}" not recognized.`);
+                }
+            }
+            expect(hasOpposite).to.be.true;
+        });
+    });
+});

diff --git a/src/GameServer.spec.ts b/src/GameServer.spec.ts
new file mode 100644
index 0000000..b105065
--- /dev/null
+++ b/src/GameServer.spec.ts
@@ -0,0 +1,106 @@
+// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
+// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
+
+import {expect} from "chai";
+import {GameServer} from "./GameServer";
+import { Direction, MazeMap, MazeTile } from "./MazeMap";
+// import { describe, it } from "mocha";
+
+function createTrivialMap(): MazeMap
+{
+    const maze = new MazeMap("lvl1");
+    let tile = new MazeTile("1");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.bottom);
+    maze.layout.push([tile]);
+    tile = new MazeTile("2");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.bottom);
+    maze.layout[0].push(tile);
+
+    tile = new MazeTile("3");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.top);
+    maze.layout.push([tile]);
+    tile = new MazeTile("4");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.top);
+    maze.layout[1].push(tile);
+
+    return maze;
+}
+
+function createGameServer(): GameServer
+{
+    const server = new GameServer();
+    server.addMap(createTrivialMap());
+    return server;
+}
+
+describe("Scenario: Starting the game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    describe("when a user starts an existing valid level", function(){
+        const games = createGameServer();
+        const position = games.startGame(userID, mapID);
+
+        it("then the start position must exist", function(){
+            expect(position).to.be.not.null;
+        });
+
+        it("then the start position must be remembered for the user", function(){
+            const current = games.currentPosition(userID);
+            expect(current.id).to.equal(position.id);
+        });
+    });
+});
+
+describe("Scenario: Navigating in ongoing game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    const games = createGameServer();
+    const startPosition = games.startGame(userID, mapID);
+
+    describe("When player navigates in existing direction", function(){
+        const naviagtionDirection = startPosition.paths[0];
+        const nextPosition = games.navigate(userID, startPosition.id, naviagtionDirection);
+        it("then the new position has to have a different id", function(){
+            expect(nextPosition.id).to.not.equal(startPosition.id);
+        });
+
+        it("then the new position must have pathway back", function(){
+            let hasOpposite:boolean = false;
+            for (const dir of nextPosition.paths) {
+                switch (dir) {
+                    case Direction.top:
+                        if(naviagtionDirection === Direction.bottom)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.left:
+                        if(naviagtionDirection === Direction.right)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.bottom:
+                        if(naviagtionDirection === Direction.top)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.right:
+                        if(naviagtionDirection === Direction.left)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    default:
+                        throw new Error(`Direction "${dir}" not recognized.`);
+                }
+            }
+            expect(hasOpposite).to.be.true;
+        });
+    });
+});
diff --git a/src/GameServer.ts b/src/GameServer.ts
new file mode 100644
index 0000000..c0479cf
--- /dev/null
+++ b/src/GameServer.ts
@@ -0,0 +1,94 @@
+import {
+    Direction,
+    MazeMap,
+    MazeTile,
+} from "./MazeMap";
+
+class GameState
+{
+    public userID: string;
+    public mapID: string;
+    public tileID: string;
+
+    constructor(userID: string, mapID: string, tileID: string)
+    {
+        this.userID = userID;
+        this.mapID = mapID;
+        this.tileID = tileID;
+    }
+}
+
+export class GameServer
+{
+    private mapList: MazeMap[];
+    private states: GameState[];
+
+    constructor()
+    {
+        this.mapList = [];
+        this.states = [];
+    }
+
+    public addMap(newMap: MazeMap): boolean
+    {
+        const validationResult = newMap.validate();
+        if(validationResult.length > 0){
+            let message = "Cannot add invalid map:";
+            for (const e of validationResult) {
+                message += "\n\t" + e;
+            }
+            throw new Error(message);
+        }
+
+        if(-1 === this.mapList.findIndex(m => m.id === newMap.id))
+        {
+            this.mapList.push(newMap);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public startGame(userID: string, mapID: string): MazeTile
+    {
+        const map = this.mapList.find(m => m.id === mapID);
+        if(map == null){
+            throw new Error(`Map "${mapID}" does not exist.`);
+        }
+        const start = map.getStartTile();
+
+        let state = this.states.find(s => s.userID === userID);
+        if(state == null)
+        {
+            state = new GameState(userID, map.id, start.id);
+            this.states.push(state);
+        }
+        else
+        {
+            state.mapID = map.id;
+            state.tileID = start.id;
+        }
+
+        return start;
+    }
+
+    public navigate(userID: string, currentTile:string, direction:Direction): MazeTile
+    {
+        const newPosition = new MazeTile("");
+        newPosition.paths.push(Direction.left);
+        return newPosition;
+    }
+
+    public currentPosition(userID: string): MazeTile
+    {
+        const state = this.states.find(s => s.userID === userID);
+        if(state == null){
+            return null;
+        }
+
+        const map = this.mapList.find(m => m.id === state.mapID);
+        const tile = map.getTile(state.tileID);
+        return tile;
+    }
+}

diff --git a/src/GameServer.spec.ts b/src/GameServer.spec.ts
new file mode 100644
index 0000000..b105065
--- /dev/null
+++ b/src/GameServer.spec.ts
@@ -0,0 +1,106 @@
+// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
+// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
+
+import {expect} from "chai";
+import {GameServer} from "./GameServer";
+import { Direction, MazeMap, MazeTile } from "./MazeMap";
+// import { describe, it } from "mocha";
+
+function createTrivialMap(): MazeMap
+{
+    const maze = new MazeMap("lvl1");
+    let tile = new MazeTile("1");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.bottom);
+    maze.layout.push([tile]);
+    tile = new MazeTile("2");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.bottom);
+    maze.layout[0].push(tile);
+
+    tile = new MazeTile("3");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.top);
+    maze.layout.push([tile]);
+    tile = new MazeTile("4");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.top);
+    maze.layout[1].push(tile);
+
+    return maze;
+}
+
+function createGameServer(): GameServer
+{
+    const server = new GameServer();
+    server.addMap(createTrivialMap());
+    return server;
+}
+
+describe("Scenario: Starting the game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    describe("when a user starts an existing valid level", function(){
+        const games = createGameServer();
+        const position = games.startGame(userID, mapID);
+
+        it("then the start position must exist", function(){
+            expect(position).to.be.not.null;
+        });
+
+        it("then the start position must be remembered for the user", function(){
+            const current = games.currentPosition(userID);
+            expect(current.id).to.equal(position.id);
+        });
+    });
+});
+
+describe("Scenario: Navigating in ongoing game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    const games = createGameServer();
+    const startPosition = games.startGame(userID, mapID);
+
+    describe("When player navigates in existing direction", function(){
+        const naviagtionDirection = startPosition.paths[0];
+        const nextPosition = games.navigate(userID, startPosition.id, naviagtionDirection);
+        it("then the new position has to have a different id", function(){
+            expect(nextPosition.id).to.not.equal(startPosition.id);
+        });
+
+        it("then the new position must have pathway back", function(){
+            let hasOpposite:boolean = false;
+            for (const dir of nextPosition.paths) {
+                switch (dir) {
+                    case Direction.top:
+                        if(naviagtionDirection === Direction.bottom)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.left:
+                        if(naviagtionDirection === Direction.right)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.bottom:
+                        if(naviagtionDirection === Direction.top)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.right:
+                        if(naviagtionDirection === Direction.left)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    default:
+                        throw new Error(`Direction "${dir}" not recognized.`);
+                }
+            }
+            expect(hasOpposite).to.be.true;
+        });
+    });
+});
diff --git a/src/GameServer.ts b/src/GameServer.ts
new file mode 100644
index 0000000..c0479cf
--- /dev/null
+++ b/src/GameServer.ts
@@ -0,0 +1,94 @@
+import {
+    Direction,
+    MazeMap,
+    MazeTile,
+} from "./MazeMap";
+
+class GameState
+{
+    public userID: string;
+    public mapID: string;
+    public tileID: string;
+
+    constructor(userID: string, mapID: string, tileID: string)
+    {
+        this.userID = userID;
+        this.mapID = mapID;
+        this.tileID = tileID;
+    }
+}
+
+export class GameServer
+{
+    private mapList: MazeMap[];
+    private states: GameState[];
+
+    constructor()
+    {
+        this.mapList = [];
+        this.states = [];
+    }
+
+    public addMap(newMap: MazeMap): boolean
+    {
+        const validationResult = newMap.validate();
+        if(validationResult.length > 0){
+            let message = "Cannot add invalid map:";
+            for (const e of validationResult) {
+                message += "\n\t" + e;
+            }
+            throw new Error(message);
+        }
+
+        if(-1 === this.mapList.findIndex(m => m.id === newMap.id))
+        {
+            this.mapList.push(newMap);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public startGame(userID: string, mapID: string): MazeTile
+    {
+        const map = this.mapList.find(m => m.id === mapID);
+        if(map == null){
+            throw new Error(`Map "${mapID}" does not exist.`);
+        }
+        const start = map.getStartTile();
+
+        let state = this.states.find(s => s.userID === userID);
+        if(state == null)
+        {
+            state = new GameState(userID, map.id, start.id);
+            this.states.push(state);
+        }
+        else
+        {
+            state.mapID = map.id;
+            state.tileID = start.id;
+        }
+
+        return start;
+    }
+
+    public navigate(userID: string, currentTile:string, direction:Direction): MazeTile
+    {
+        const newPosition = new MazeTile("");
+        newPosition.paths.push(Direction.left);
+        return newPosition;
+    }
+
+    public currentPosition(userID: string): MazeTile
+    {
+        const state = this.states.find(s => s.userID === userID);
+        if(state == null){
+            return null;
+        }
+
+        const map = this.mapList.find(m => m.id === state.mapID);
+        const tile = map.getTile(state.tileID);
+        return tile;
+    }
+}
diff --git a/src/MazeMap.ts b/src/MazeMap.ts
index 5265cdf..7110157 100644
--- a/src/MazeMap.ts
+++ b/src/MazeMap.ts
@@ -124,6 +124,23 @@
         return output;
     }
 
+    public getTile(tileID: string): MazeTile
+    {
+        for (const row of this.layout) {
+            for (const tile of row) {
+                if(tile.id === tileID){
+                    return tile;
+                }
+            }
+        }
+        return null;
+    }
+
+    public getStartTile(): MazeTile
+    {
+        return this.layout[this.startPosition[0]][this.startPosition[1]];
+    }
+
     public validate(): MazeValidationError[]
     {
         const errors:MazeValidationError[] = [];

diff --git a/src/GameServer.spec.ts b/src/GameServer.spec.ts
new file mode 100644
index 0000000..b105065
--- /dev/null
+++ b/src/GameServer.spec.ts
@@ -0,0 +1,106 @@
+// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
+// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
+
+import {expect} from "chai";
+import {GameServer} from "./GameServer";
+import { Direction, MazeMap, MazeTile } from "./MazeMap";
+// import { describe, it } from "mocha";
+
+function createTrivialMap(): MazeMap
+{
+    const maze = new MazeMap("lvl1");
+    let tile = new MazeTile("1");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.bottom);
+    maze.layout.push([tile]);
+    tile = new MazeTile("2");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.bottom);
+    maze.layout[0].push(tile);
+
+    tile = new MazeTile("3");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.top);
+    maze.layout.push([tile]);
+    tile = new MazeTile("4");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.top);
+    maze.layout[1].push(tile);
+
+    return maze;
+}
+
+function createGameServer(): GameServer
+{
+    const server = new GameServer();
+    server.addMap(createTrivialMap());
+    return server;
+}
+
+describe("Scenario: Starting the game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    describe("when a user starts an existing valid level", function(){
+        const games = createGameServer();
+        const position = games.startGame(userID, mapID);
+
+        it("then the start position must exist", function(){
+            expect(position).to.be.not.null;
+        });
+
+        it("then the start position must be remembered for the user", function(){
+            const current = games.currentPosition(userID);
+            expect(current.id).to.equal(position.id);
+        });
+    });
+});
+
+describe("Scenario: Navigating in ongoing game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    const games = createGameServer();
+    const startPosition = games.startGame(userID, mapID);
+
+    describe("When player navigates in existing direction", function(){
+        const naviagtionDirection = startPosition.paths[0];
+        const nextPosition = games.navigate(userID, startPosition.id, naviagtionDirection);
+        it("then the new position has to have a different id", function(){
+            expect(nextPosition.id).to.not.equal(startPosition.id);
+        });
+
+        it("then the new position must have pathway back", function(){
+            let hasOpposite:boolean = false;
+            for (const dir of nextPosition.paths) {
+                switch (dir) {
+                    case Direction.top:
+                        if(naviagtionDirection === Direction.bottom)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.left:
+                        if(naviagtionDirection === Direction.right)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.bottom:
+                        if(naviagtionDirection === Direction.top)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.right:
+                        if(naviagtionDirection === Direction.left)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    default:
+                        throw new Error(`Direction "${dir}" not recognized.`);
+                }
+            }
+            expect(hasOpposite).to.be.true;
+        });
+    });
+});
diff --git a/src/GameServer.ts b/src/GameServer.ts
new file mode 100644
index 0000000..c0479cf
--- /dev/null
+++ b/src/GameServer.ts
@@ -0,0 +1,94 @@
+import {
+    Direction,
+    MazeMap,
+    MazeTile,
+} from "./MazeMap";
+
+class GameState
+{
+    public userID: string;
+    public mapID: string;
+    public tileID: string;
+
+    constructor(userID: string, mapID: string, tileID: string)
+    {
+        this.userID = userID;
+        this.mapID = mapID;
+        this.tileID = tileID;
+    }
+}
+
+export class GameServer
+{
+    private mapList: MazeMap[];
+    private states: GameState[];
+
+    constructor()
+    {
+        this.mapList = [];
+        this.states = [];
+    }
+
+    public addMap(newMap: MazeMap): boolean
+    {
+        const validationResult = newMap.validate();
+        if(validationResult.length > 0){
+            let message = "Cannot add invalid map:";
+            for (const e of validationResult) {
+                message += "\n\t" + e;
+            }
+            throw new Error(message);
+        }
+
+        if(-1 === this.mapList.findIndex(m => m.id === newMap.id))
+        {
+            this.mapList.push(newMap);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public startGame(userID: string, mapID: string): MazeTile
+    {
+        const map = this.mapList.find(m => m.id === mapID);
+        if(map == null){
+            throw new Error(`Map "${mapID}" does not exist.`);
+        }
+        const start = map.getStartTile();
+
+        let state = this.states.find(s => s.userID === userID);
+        if(state == null)
+        {
+            state = new GameState(userID, map.id, start.id);
+            this.states.push(state);
+        }
+        else
+        {
+            state.mapID = map.id;
+            state.tileID = start.id;
+        }
+
+        return start;
+    }
+
+    public navigate(userID: string, currentTile:string, direction:Direction): MazeTile
+    {
+        const newPosition = new MazeTile("");
+        newPosition.paths.push(Direction.left);
+        return newPosition;
+    }
+
+    public currentPosition(userID: string): MazeTile
+    {
+        const state = this.states.find(s => s.userID === userID);
+        if(state == null){
+            return null;
+        }
+
+        const map = this.mapList.find(m => m.id === state.mapID);
+        const tile = map.getTile(state.tileID);
+        return tile;
+    }
+}
diff --git a/src/MazeMap.ts b/src/MazeMap.ts
index 5265cdf..7110157 100644
--- a/src/MazeMap.ts
+++ b/src/MazeMap.ts
@@ -124,6 +124,23 @@
         return output;
     }
 
+    public getTile(tileID: string): MazeTile
+    {
+        for (const row of this.layout) {
+            for (const tile of row) {
+                if(tile.id === tileID){
+                    return tile;
+                }
+            }
+        }
+        return null;
+    }
+
+    public getStartTile(): MazeTile
+    {
+        return this.layout[this.startPosition[0]][this.startPosition[1]];
+    }
+
     public validate(): MazeValidationError[]
     {
         const errors:MazeValidationError[] = [];
diff --git a/src/NavigationEndpoint.spec.ts b/src/NavigationEndpoint.spec.ts
deleted file mode 100644
index 83588f1..0000000
--- a/src/NavigationEndpoint.spec.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
-// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
-
-import {expect} from "chai";
-import { Direction } from "./MazeMap";
-// import { describe, it } from "mocha";
-import {navigate, startGame} from "./NavigationEndpoint";
-
-describe("Scenario: Starting the game", function(){
-    describe("when the game is started", function(){
-        const position = startGame();
-
-        it("then the start position must exist", function(){
-            expect(position).to.be.not.null;
-        });
-
-        it("then the position must have at least one pathway", function(){
-            expect(position.paths.length).to.be.greaterThan(0);
-        });
-    });
-});
-
-describe("Scenario: Navigating in ongoing game", function(){
-    const startPosition = startGame();
-
-    describe("When player navigates in existing direction", function(){
-        const naviagtionDirection = startPosition.paths[0];
-        const nextPosition = navigate(startPosition.id, naviagtionDirection);
-        it("then the new position has to have a different id", function(){
-            expect(nextPosition.id).to.not.equal(startPosition.id);
-        });
-
-        it("then the new position must have pathway back", function(){
-            let hasOpposite:boolean = false;
-            for (const dir of nextPosition.paths) {
-                switch (dir) {
-                    case Direction.top:
-                        if(naviagtionDirection === Direction.bottom)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.left:
-                        if(naviagtionDirection === Direction.right)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.bottom:
-                        if(naviagtionDirection === Direction.top)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.right:
-                        if(naviagtionDirection === Direction.left)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    default:
-                        throw new Error(`Direction "${dir}" not recognized.`);
-                }
-            }
-            expect(hasOpposite).to.be.true;
-        });
-    });
-});

diff --git a/src/GameServer.spec.ts b/src/GameServer.spec.ts
new file mode 100644
index 0000000..b105065
--- /dev/null
+++ b/src/GameServer.spec.ts
@@ -0,0 +1,106 @@
+// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
+// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
+
+import {expect} from "chai";
+import {GameServer} from "./GameServer";
+import { Direction, MazeMap, MazeTile } from "./MazeMap";
+// import { describe, it } from "mocha";
+
+function createTrivialMap(): MazeMap
+{
+    const maze = new MazeMap("lvl1");
+    let tile = new MazeTile("1");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.bottom);
+    maze.layout.push([tile]);
+    tile = new MazeTile("2");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.bottom);
+    maze.layout[0].push(tile);
+
+    tile = new MazeTile("3");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.top);
+    maze.layout.push([tile]);
+    tile = new MazeTile("4");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.top);
+    maze.layout[1].push(tile);
+
+    return maze;
+}
+
+function createGameServer(): GameServer
+{
+    const server = new GameServer();
+    server.addMap(createTrivialMap());
+    return server;
+}
+
+describe("Scenario: Starting the game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    describe("when a user starts an existing valid level", function(){
+        const games = createGameServer();
+        const position = games.startGame(userID, mapID);
+
+        it("then the start position must exist", function(){
+            expect(position).to.be.not.null;
+        });
+
+        it("then the start position must be remembered for the user", function(){
+            const current = games.currentPosition(userID);
+            expect(current.id).to.equal(position.id);
+        });
+    });
+});
+
+describe("Scenario: Navigating in ongoing game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    const games = createGameServer();
+    const startPosition = games.startGame(userID, mapID);
+
+    describe("When player navigates in existing direction", function(){
+        const naviagtionDirection = startPosition.paths[0];
+        const nextPosition = games.navigate(userID, startPosition.id, naviagtionDirection);
+        it("then the new position has to have a different id", function(){
+            expect(nextPosition.id).to.not.equal(startPosition.id);
+        });
+
+        it("then the new position must have pathway back", function(){
+            let hasOpposite:boolean = false;
+            for (const dir of nextPosition.paths) {
+                switch (dir) {
+                    case Direction.top:
+                        if(naviagtionDirection === Direction.bottom)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.left:
+                        if(naviagtionDirection === Direction.right)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.bottom:
+                        if(naviagtionDirection === Direction.top)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.right:
+                        if(naviagtionDirection === Direction.left)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    default:
+                        throw new Error(`Direction "${dir}" not recognized.`);
+                }
+            }
+            expect(hasOpposite).to.be.true;
+        });
+    });
+});
diff --git a/src/GameServer.ts b/src/GameServer.ts
new file mode 100644
index 0000000..c0479cf
--- /dev/null
+++ b/src/GameServer.ts
@@ -0,0 +1,94 @@
+import {
+    Direction,
+    MazeMap,
+    MazeTile,
+} from "./MazeMap";
+
+class GameState
+{
+    public userID: string;
+    public mapID: string;
+    public tileID: string;
+
+    constructor(userID: string, mapID: string, tileID: string)
+    {
+        this.userID = userID;
+        this.mapID = mapID;
+        this.tileID = tileID;
+    }
+}
+
+export class GameServer
+{
+    private mapList: MazeMap[];
+    private states: GameState[];
+
+    constructor()
+    {
+        this.mapList = [];
+        this.states = [];
+    }
+
+    public addMap(newMap: MazeMap): boolean
+    {
+        const validationResult = newMap.validate();
+        if(validationResult.length > 0){
+            let message = "Cannot add invalid map:";
+            for (const e of validationResult) {
+                message += "\n\t" + e;
+            }
+            throw new Error(message);
+        }
+
+        if(-1 === this.mapList.findIndex(m => m.id === newMap.id))
+        {
+            this.mapList.push(newMap);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public startGame(userID: string, mapID: string): MazeTile
+    {
+        const map = this.mapList.find(m => m.id === mapID);
+        if(map == null){
+            throw new Error(`Map "${mapID}" does not exist.`);
+        }
+        const start = map.getStartTile();
+
+        let state = this.states.find(s => s.userID === userID);
+        if(state == null)
+        {
+            state = new GameState(userID, map.id, start.id);
+            this.states.push(state);
+        }
+        else
+        {
+            state.mapID = map.id;
+            state.tileID = start.id;
+        }
+
+        return start;
+    }
+
+    public navigate(userID: string, currentTile:string, direction:Direction): MazeTile
+    {
+        const newPosition = new MazeTile("");
+        newPosition.paths.push(Direction.left);
+        return newPosition;
+    }
+
+    public currentPosition(userID: string): MazeTile
+    {
+        const state = this.states.find(s => s.userID === userID);
+        if(state == null){
+            return null;
+        }
+
+        const map = this.mapList.find(m => m.id === state.mapID);
+        const tile = map.getTile(state.tileID);
+        return tile;
+    }
+}
diff --git a/src/MazeMap.ts b/src/MazeMap.ts
index 5265cdf..7110157 100644
--- a/src/MazeMap.ts
+++ b/src/MazeMap.ts
@@ -124,6 +124,23 @@
         return output;
     }
 
+    public getTile(tileID: string): MazeTile
+    {
+        for (const row of this.layout) {
+            for (const tile of row) {
+                if(tile.id === tileID){
+                    return tile;
+                }
+            }
+        }
+        return null;
+    }
+
+    public getStartTile(): MazeTile
+    {
+        return this.layout[this.startPosition[0]][this.startPosition[1]];
+    }
+
     public validate(): MazeValidationError[]
     {
         const errors:MazeValidationError[] = [];
diff --git a/src/NavigationEndpoint.spec.ts b/src/NavigationEndpoint.spec.ts
deleted file mode 100644
index 83588f1..0000000
--- a/src/NavigationEndpoint.spec.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
-// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
-
-import {expect} from "chai";
-import { Direction } from "./MazeMap";
-// import { describe, it } from "mocha";
-import {navigate, startGame} from "./NavigationEndpoint";
-
-describe("Scenario: Starting the game", function(){
-    describe("when the game is started", function(){
-        const position = startGame();
-
-        it("then the start position must exist", function(){
-            expect(position).to.be.not.null;
-        });
-
-        it("then the position must have at least one pathway", function(){
-            expect(position.paths.length).to.be.greaterThan(0);
-        });
-    });
-});
-
-describe("Scenario: Navigating in ongoing game", function(){
-    const startPosition = startGame();
-
-    describe("When player navigates in existing direction", function(){
-        const naviagtionDirection = startPosition.paths[0];
-        const nextPosition = navigate(startPosition.id, naviagtionDirection);
-        it("then the new position has to have a different id", function(){
-            expect(nextPosition.id).to.not.equal(startPosition.id);
-        });
-
-        it("then the new position must have pathway back", function(){
-            let hasOpposite:boolean = false;
-            for (const dir of nextPosition.paths) {
-                switch (dir) {
-                    case Direction.top:
-                        if(naviagtionDirection === Direction.bottom)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.left:
-                        if(naviagtionDirection === Direction.right)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.bottom:
-                        if(naviagtionDirection === Direction.top)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.right:
-                        if(naviagtionDirection === Direction.left)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    default:
-                        throw new Error(`Direction "${dir}" not recognized.`);
-                }
-            }
-            expect(hasOpposite).to.be.true;
-        });
-    });
-});
diff --git a/src/NavigationEndpoint.ts b/src/NavigationEndpoint.ts
deleted file mode 100644
index 514cf98..0000000
--- a/src/NavigationEndpoint.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import {
-    Direction,
-    MazeTile,
-} from "./MazeMap";
-
-export function startGame(): MazeTile
-{
-    const StartingPoint = new MazeTile("start");
-    StartingPoint.paths.push(Direction.right);
-    return StartingPoint;
-}
-
-export function navigate(currentPosition:string, direction:Direction): MazeTile
-{
-    const newPosition = new MazeTile("");
-    newPosition.paths.push(Direction.left);
-    return newPosition;
-}

diff --git a/src/GameServer.spec.ts b/src/GameServer.spec.ts
new file mode 100644
index 0000000..b105065
--- /dev/null
+++ b/src/GameServer.spec.ts
@@ -0,0 +1,106 @@
+// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
+// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
+
+import {expect} from "chai";
+import {GameServer} from "./GameServer";
+import { Direction, MazeMap, MazeTile } from "./MazeMap";
+// import { describe, it } from "mocha";
+
+function createTrivialMap(): MazeMap
+{
+    const maze = new MazeMap("lvl1");
+    let tile = new MazeTile("1");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.bottom);
+    maze.layout.push([tile]);
+    tile = new MazeTile("2");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.bottom);
+    maze.layout[0].push(tile);
+
+    tile = new MazeTile("3");
+    tile.paths.push(Direction.right);
+    tile.paths.push(Direction.top);
+    maze.layout.push([tile]);
+    tile = new MazeTile("4");
+    tile.paths.push(Direction.left);
+    tile.paths.push(Direction.top);
+    maze.layout[1].push(tile);
+
+    return maze;
+}
+
+function createGameServer(): GameServer
+{
+    const server = new GameServer();
+    server.addMap(createTrivialMap());
+    return server;
+}
+
+describe("Scenario: Starting the game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    describe("when a user starts an existing valid level", function(){
+        const games = createGameServer();
+        const position = games.startGame(userID, mapID);
+
+        it("then the start position must exist", function(){
+            expect(position).to.be.not.null;
+        });
+
+        it("then the start position must be remembered for the user", function(){
+            const current = games.currentPosition(userID);
+            expect(current.id).to.equal(position.id);
+        });
+    });
+});
+
+describe("Scenario: Navigating in ongoing game", function(){
+    const userID = "UserID";
+    const mapID = "lvl1";
+    const games = createGameServer();
+    const startPosition = games.startGame(userID, mapID);
+
+    describe("When player navigates in existing direction", function(){
+        const naviagtionDirection = startPosition.paths[0];
+        const nextPosition = games.navigate(userID, startPosition.id, naviagtionDirection);
+        it("then the new position has to have a different id", function(){
+            expect(nextPosition.id).to.not.equal(startPosition.id);
+        });
+
+        it("then the new position must have pathway back", function(){
+            let hasOpposite:boolean = false;
+            for (const dir of nextPosition.paths) {
+                switch (dir) {
+                    case Direction.top:
+                        if(naviagtionDirection === Direction.bottom)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.left:
+                        if(naviagtionDirection === Direction.right)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.bottom:
+                        if(naviagtionDirection === Direction.top)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    case Direction.right:
+                        if(naviagtionDirection === Direction.left)
+                        {
+                            hasOpposite = true;
+                        }
+                        break;
+                    default:
+                        throw new Error(`Direction "${dir}" not recognized.`);
+                }
+            }
+            expect(hasOpposite).to.be.true;
+        });
+    });
+});
diff --git a/src/GameServer.ts b/src/GameServer.ts
new file mode 100644
index 0000000..c0479cf
--- /dev/null
+++ b/src/GameServer.ts
@@ -0,0 +1,94 @@
+import {
+    Direction,
+    MazeMap,
+    MazeTile,
+} from "./MazeMap";
+
+class GameState
+{
+    public userID: string;
+    public mapID: string;
+    public tileID: string;
+
+    constructor(userID: string, mapID: string, tileID: string)
+    {
+        this.userID = userID;
+        this.mapID = mapID;
+        this.tileID = tileID;
+    }
+}
+
+export class GameServer
+{
+    private mapList: MazeMap[];
+    private states: GameState[];
+
+    constructor()
+    {
+        this.mapList = [];
+        this.states = [];
+    }
+
+    public addMap(newMap: MazeMap): boolean
+    {
+        const validationResult = newMap.validate();
+        if(validationResult.length > 0){
+            let message = "Cannot add invalid map:";
+            for (const e of validationResult) {
+                message += "\n\t" + e;
+            }
+            throw new Error(message);
+        }
+
+        if(-1 === this.mapList.findIndex(m => m.id === newMap.id))
+        {
+            this.mapList.push(newMap);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public startGame(userID: string, mapID: string): MazeTile
+    {
+        const map = this.mapList.find(m => m.id === mapID);
+        if(map == null){
+            throw new Error(`Map "${mapID}" does not exist.`);
+        }
+        const start = map.getStartTile();
+
+        let state = this.states.find(s => s.userID === userID);
+        if(state == null)
+        {
+            state = new GameState(userID, map.id, start.id);
+            this.states.push(state);
+        }
+        else
+        {
+            state.mapID = map.id;
+            state.tileID = start.id;
+        }
+
+        return start;
+    }
+
+    public navigate(userID: string, currentTile:string, direction:Direction): MazeTile
+    {
+        const newPosition = new MazeTile("");
+        newPosition.paths.push(Direction.left);
+        return newPosition;
+    }
+
+    public currentPosition(userID: string): MazeTile
+    {
+        const state = this.states.find(s => s.userID === userID);
+        if(state == null){
+            return null;
+        }
+
+        const map = this.mapList.find(m => m.id === state.mapID);
+        const tile = map.getTile(state.tileID);
+        return tile;
+    }
+}
diff --git a/src/MazeMap.ts b/src/MazeMap.ts
index 5265cdf..7110157 100644
--- a/src/MazeMap.ts
+++ b/src/MazeMap.ts
@@ -124,6 +124,23 @@
         return output;
     }
 
+    public getTile(tileID: string): MazeTile
+    {
+        for (const row of this.layout) {
+            for (const tile of row) {
+                if(tile.id === tileID){
+                    return tile;
+                }
+            }
+        }
+        return null;
+    }
+
+    public getStartTile(): MazeTile
+    {
+        return this.layout[this.startPosition[0]][this.startPosition[1]];
+    }
+
     public validate(): MazeValidationError[]
     {
         const errors:MazeValidationError[] = [];
diff --git a/src/NavigationEndpoint.spec.ts b/src/NavigationEndpoint.spec.ts
deleted file mode 100644
index 83588f1..0000000
--- a/src/NavigationEndpoint.spec.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
-// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346
-
-import {expect} from "chai";
-import { Direction } from "./MazeMap";
-// import { describe, it } from "mocha";
-import {navigate, startGame} from "./NavigationEndpoint";
-
-describe("Scenario: Starting the game", function(){
-    describe("when the game is started", function(){
-        const position = startGame();
-
-        it("then the start position must exist", function(){
-            expect(position).to.be.not.null;
-        });
-
-        it("then the position must have at least one pathway", function(){
-            expect(position.paths.length).to.be.greaterThan(0);
-        });
-    });
-});
-
-describe("Scenario: Navigating in ongoing game", function(){
-    const startPosition = startGame();
-
-    describe("When player navigates in existing direction", function(){
-        const naviagtionDirection = startPosition.paths[0];
-        const nextPosition = navigate(startPosition.id, naviagtionDirection);
-        it("then the new position has to have a different id", function(){
-            expect(nextPosition.id).to.not.equal(startPosition.id);
-        });
-
-        it("then the new position must have pathway back", function(){
-            let hasOpposite:boolean = false;
-            for (const dir of nextPosition.paths) {
-                switch (dir) {
-                    case Direction.top:
-                        if(naviagtionDirection === Direction.bottom)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.left:
-                        if(naviagtionDirection === Direction.right)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.bottom:
-                        if(naviagtionDirection === Direction.top)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    case Direction.right:
-                        if(naviagtionDirection === Direction.left)
-                        {
-                            hasOpposite = true;
-                        }
-                        break;
-                    default:
-                        throw new Error(`Direction "${dir}" not recognized.`);
-                }
-            }
-            expect(hasOpposite).to.be.true;
-        });
-    });
-});
diff --git a/src/NavigationEndpoint.ts b/src/NavigationEndpoint.ts
deleted file mode 100644
index 514cf98..0000000
--- a/src/NavigationEndpoint.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import {
-    Direction,
-    MazeTile,
-} from "./MazeMap";
-
-export function startGame(): MazeTile
-{
-    const StartingPoint = new MazeTile("start");
-    StartingPoint.paths.push(Direction.right);
-    return StartingPoint;
-}
-
-export function navigate(currentPosition:string, direction:Direction): MazeTile
-{
-    const newPosition = new MazeTile("");
-    newPosition.paths.push(Direction.left);
-    return newPosition;
-}
diff --git a/tslint.json b/tslint.json
index 13e0631..1ad9eda 100644
--- a/tslint.json
+++ b/tslint.json
@@ -13,7 +13,8 @@
         "max-classes-per-file":false,
         "only-arrow-functions": false,
         "no-unused-expression": false,
-        "typedef": [true, "parameter", "member-variable-declaration"]
+        "typedef": [true, "parameter", "member-variable-declaration"],
+        "arrow-parens": false
     },
     "rulesDirectory": [],
     "linterOptions": {