diff --git a/overcooked_simulator/__main__.py b/overcooked_simulator/__main__.py
new file mode 100644
index 0000000000000000000000000000000000000000..a85f150ac7d4de61e1c4d8344e5e0fbee86658d6
--- /dev/null
+++ b/overcooked_simulator/__main__.py
@@ -0,0 +1,70 @@
+import argparse
+import time
+from multiprocessing import Process
+
+parser = argparse.ArgumentParser(
+    prog="Overcooked Simulator",
+    description="Game Engine Server + PyGameGUI: Starts overcooked game engine server and a PyGame 2D Visualization window in two processes.",
+    epilog="For further information, see https://scs.pages.ub.uni-bielefeld.de/cocosy/overcooked-simulator/overcooked_simulator.html",
+)
+
+parser.add_argument(
+    "-url",
+    "--url",
+    "--host",
+    type=str,
+    default="localhost",
+    help="Overcooked game server host url.",
+)
+parser.add_argument(
+    "-p",
+    "--port",
+    type=int,
+    default=8000,
+    help="Port number for the game engine server",
+)
+
+
+def start_game_server(cli_args):
+    from overcooked_simulator.game_server import main
+
+    main(cli_args.url, cli_args.port)
+
+
+def start_pygame_gui(cli_args):
+    from overcooked_simulator.gui_2d_vis.overcooked_gui import main
+
+    main()
+
+
+def main(cli_args=None):
+    if cli_args is None:
+        cli_args = parser.parse_args()
+    game_server = None
+    pygame_gui = None
+    try:
+        print("Start game engine:")
+        game_server = Process(target=start_game_server, args=(cli_args,))
+        game_server.start()
+        time.sleep(1)
+        print("Start PyGame GUI:")
+        pygame_gui = Process(target=start_pygame_gui, args=(cli_args,))
+        pygame_gui.start()
+        while pygame_gui.is_alive() and game_server.is_alive():
+            time.sleep(1)
+    except KeyboardInterrupt:
+        print("Received Keyboard interrupt")
+    finally:
+        if game_server is not None and game_server.is_alive():
+            print("Terminate game server")
+            game_server.terminate()
+        if pygame_gui is not None and pygame_gui.is_alive():
+            print("Terminate pygame gui")
+            game_server.terminate()
+        time.sleep(0.1)
+
+
+if __name__ == "__main__":
+    args = parser.parse_args()
+    print(args)
+    main(args)
diff --git a/overcooked_simulator/game_server.py b/overcooked_simulator/game_server.py
index 43dc2e39485dcac8ec5ddb959bcb60ca6fcb0797..cb118cb2e11b50fa129397cab974c8f172f77063 100644
--- a/overcooked_simulator/game_server.py
+++ b/overcooked_simulator/game_server.py
@@ -704,11 +704,11 @@ async def websocket_player_endpoint(websocket: WebSocket, client_id: str):
         log.debug(f"Client #{client_id} disconnected")
 
 
-def main():
+def main(host: str = WEBSOCKET_URL, port: int = WEBSOCKET_PORT):
     loop = asyncio.new_event_loop()
     asyncio.set_event_loop(loop)
     loop.create_task(environment_handler.environment_steps())
-    config = uvicorn.Config(app, host=WEBSOCKET_URL, port=WEBSOCKET_PORT, loop=loop)
+    config = uvicorn.Config(app, host=host, port=port, loop=loop)
     server = uvicorn.Server(config)
     loop.run_until_complete(server.serve())
 
diff --git a/overcooked_simulator/gui_2d_vis/overcooked_gui.py b/overcooked_simulator/gui_2d_vis/overcooked_gui.py
index 5dd4326f00cee70039b35a50bce29d21ae321b5c..3c51e41a8f5ce255f00ca1821c4cdf789ee2284e 100644
--- a/overcooked_simulator/gui_2d_vis/overcooked_gui.py
+++ b/overcooked_simulator/gui_2d_vis/overcooked_gui.py
@@ -446,9 +446,7 @@ class PyGameGUI:
             websocket.send(
                 json.dumps({"type": "ready", "player_hash": player_info["player_hash"]})
             )
-            assert websocket.recv() == json.dumps(
-                {"status": "ready accepted", "player_hash": player_info["player_hash"]}
-            ), "not accepted player"
+            assert json.loads(websocket.recv())["status"] == 200, "not accepted player"
             self.websockets[player_id] = websocket
         self.state_player_id = player_id
         websocket.send(
@@ -478,6 +476,7 @@ class PyGameGUI:
 
     def quit_button_press(self):
         self.running = False
+        self.menu_state = MenuStates.Start
         log.debug("Pressed quit button")
 
     def reset_button_press(self):
@@ -633,7 +632,7 @@ class PyGameGUI:
                 self.manager.update(time_delta)
                 pygame.display.flip()
 
-            except KeyboardInterrupt:
+            except (KeyboardInterrupt, SystemExit):
                 self.running = False
 
         pygame.quit()
diff --git a/setup.py b/setup.py
index 42a864479e98731dac6894e324ef95b2ae66fcff..d57d47c30a8eefd7e427ff97be2c4884bd1a4cfb 100644
--- a/setup.py
+++ b/setup.py
@@ -40,6 +40,9 @@ setup(
         "Programming Language :: Python :: 3.10",
     ],
     description="The real-time overcooked simulation for a cognitive cooperative system",
+    entry_points={
+        "console_scripts": ["overcooked-sim = overcooked_simulator.__main__:main"]
+    },
     install_requires=requirements,
     license="MIT license",
     long_description=readme + "\n\n" + history,