diff --git a/overcooked_simulator/game_content/agents/arch_config.yml b/overcooked_simulator/game_content/agents/arch_config.yml
new file mode 100644
index 0000000000000000000000000000000000000000..60d20c0d2c2af5ffc6b1d5ca1351317582c96456
--- /dev/null
+++ b/overcooked_simulator/game_content/agents/arch_config.yml
@@ -0,0 +1,23 @@
+concurrency: MultiProcessing
+
+communication:
+  communication_prefs:
+   - !name:ipaacar_com_service.communications.ipaacar_com.IPAACARInfo
+
+modules:
+  connection:
+    module_info: !name:cocosy_agent.modules.connection_module.ConnectionModule
+    mean_frequency_step: 2  # 2: every 0.5 seconds
+  working_memory:
+    module_info: !name:cocosy_agent.modules.working_memory_module.WorkingMemoryModule
+  subtask_selection:
+    module_info: !name:cocosy_agent.modules.random_subtask_module.RandomSubtaskModule
+  action_execution:
+    module_info: !name:cocosy_agent.modules.action_execution_module.ActionExecutionModule
+    mean_frequency_step: 10  # 2: every 0.5 seconds
+  gui:
+    module_info: !name:aaambos.std.guis.pysimplegui.pysimplegui_window.PySimpleGUIWindowModule
+    window_title: Counting GUI
+    topics_to_show: [["SubtaskDecision", "cocosy_agent.conventions.communication.SubtaskDecision", ["task_type"]], ["ActionControl", "cocosy_agent.conventions.communication.ActionControl", ["action_type"]]]
+  status_manager:
+    module_info: !name:aaambos.std.modules.module_status_manager.ModuleStatusManager
\ No newline at end of file
diff --git a/overcooked_simulator/game_content/agents/run_config.yml b/overcooked_simulator/game_content/agents/run_config.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f9c6cdf64e2133ae910dd13d90a8ec734368cd00
--- /dev/null
+++ b/overcooked_simulator/game_content/agents/run_config.yml
@@ -0,0 +1,15 @@
+general:
+  agent_name: cocosy_agent
+  instance: _dev
+  local_agent_directories: ~/aaambos_agents
+  plus:
+    agent_websocket: ws://localhost:8000:/ws/player/MY_CLIENT_ID
+    player_hash: abcdefghijklmnopqrstuvwxyz
+    agent_id: 1
+
+logging:
+    log_level_command_line: INFO
+
+supervisor:
+  run_time_manager_class: !name:aaambos.std.supervision.instruction_run_time_manager.instruction_run_time_manager.InstructionRunTimeManager
+
diff --git a/overcooked_simulator/game_server.py b/overcooked_simulator/game_server.py
index 95e8e18fb6733f319d85fc58dfcef18471e66521..03679cc4a293913f7df494ab92282df3994ef086 100644
--- a/overcooked_simulator/game_server.py
+++ b/overcooked_simulator/game_server.py
@@ -219,7 +219,9 @@ class EnvironmentHandler:
             self.envs[env_id].last_step_time = time.time_ns()
             self.envs[env_id].environment.reset_env_time()
 
-    def get_state(self, player_hash: str) -> str:  # -> StateRepresentation as json
+    def get_state(
+        self, player_hash: str
+    ) -> str | int:  # -> StateRepresentation as json
         """Get the current state representation of the environment for a player.
 
         Args:
@@ -236,6 +238,10 @@ class EnvironmentHandler:
             return self.envs[
                 self.player_data[player_hash].env_id
             ].environment.get_json_state()
+        if player_hash not in self.player_data:
+            return 1
+        if self.player_data[player_hash].env_id not in self.envs:
+            return 2
 
     def pause_env(self, manager_id: str, env_id: str, reason: str):
         """Pause the specified environment.
@@ -598,7 +604,17 @@ def manage_websocket_message(message: str, client_id: str) -> PlayerRequestResul
                 }
 
             case PlayerRequestType.GET_STATE:
-                return environment_handler.get_state(message_dict["player_hash"])
+                state = environment_handler.get_state(message_dict["player_hash"])
+                if isinstance(state, int):
+                    return {
+                        "request_type": message_dict["type"],
+                        "status": 400,
+                        "msg": "env id of player not in running envs"
+                        if state == 2
+                        else "player hash unknown",
+                        "player_hash": None,
+                    }
+                return state
 
             case PlayerRequestType.ACTION:
                 assert (
diff --git a/overcooked_simulator/gui_2d_vis/overcooked_gui.py b/overcooked_simulator/gui_2d_vis/overcooked_gui.py
index 3260d1eff7dab10d4334891558976f8e2a3e8117..b5db493c42724e0588d026e05a1b8368e076ae00 100644
--- a/overcooked_simulator/gui_2d_vis/overcooked_gui.py
+++ b/overcooked_simulator/gui_2d_vis/overcooked_gui.py
@@ -2,9 +2,12 @@ import argparse
 import dataclasses
 import json
 import logging
+import os
 import random
+import signal
 import sys
 from enum import Enum
+from subprocess import Popen
 
 import numpy as np
 import pygame
@@ -97,7 +100,7 @@ class PyGameGUI:
         self.running = True
 
         self.reset_gui_values()
-        self.key_sets: list[PlayerKeySet] = self.setup_player_keys(1)
+        self.key_sets: list[PlayerKeySet] = []
 
         self.websocket_url = f"ws://{url}:{port}/ws/player/"
         self.websockets = {}
@@ -135,6 +138,8 @@ class PyGameGUI:
 
         self.vis = Visualizer(self.visualization_config)
 
+        self.sub_processes = []
+
     def get_window_sizes(self, state: dict):
         kitchen_width = state["kitchen"]["width"]
         kitchen_height = state["kitchen"]["height"]
@@ -177,29 +182,32 @@ class PyGameGUI:
         )
 
     def setup_player_keys(self, n=1, disjunct=False):
-        key_set1 = PlayerKeySet(
-            move_keys=[pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s],
-            interact_key=pygame.K_f,
-            pickup_key=pygame.K_e,
-            switch_key=pygame.K_SPACE,
-            players=list(range(self.number_humans_to_be_added)),
-        )
-        key_set2 = PlayerKeySet(
-            move_keys=[pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN],
-            interact_key=pygame.K_i,
-            pickup_key=pygame.K_o,
-            switch_key=pygame.K_p,
-            players=list(range(self.number_humans_to_be_added)),
-        )
-        key_sets = [key_set1, key_set2]
-
-        if disjunct:
-            split_idx = int(np.ceil(self.number_humans_to_be_added / 2))
-            key_set1.set_controlled_players(list(range(0, split_idx)))
-            key_set2.set_controlled_players(
-                list(range(split_idx, self.number_humans_to_be_added))
+        if n:
+            key_set1 = PlayerKeySet(
+                move_keys=[pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s],
+                interact_key=pygame.K_f,
+                pickup_key=pygame.K_e,
+                switch_key=pygame.K_SPACE,
+                players=list(range(self.number_humans_to_be_added)),
+            )
+            key_set2 = PlayerKeySet(
+                move_keys=[pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN],
+                interact_key=pygame.K_i,
+                pickup_key=pygame.K_o,
+                switch_key=pygame.K_p,
+                players=list(range(self.number_humans_to_be_added)),
             )
-        return key_sets[:n]
+            key_sets = [key_set1, key_set2]
+
+            if disjunct:
+                split_idx = int(np.ceil(self.number_humans_to_be_added / 2))
+                key_set1.set_controlled_players(list(range(0, split_idx)))
+                key_set2.set_controlled_players(
+                    list(range(split_idx, self.number_humans_to_be_added))
+                )
+            return key_sets[:n]
+        else:
+            return []
 
     def handle_keys(self):
         """Handles keyboard inputs. Sends action for the respective players. When a key is held down, every frame
@@ -697,18 +705,72 @@ class PyGameGUI:
         assert isinstance(env_info, dict), "Env info must be a dictionary"
         self.current_env_id = env_info["env_id"]
         self.player_info = env_info["player_info"]
-        for player_id, player_info in env_info["player_info"].items():
+
+        state = None
+        for p, (player_id, player_info) in enumerate(env_info["player_info"].items()):
+            if p < self.number_humans_to_be_added:
+                websocket = connect(self.websocket_url + player_info["client_id"])
+                websocket.send(
+                    json.dumps(
+                        {"type": "ready", "player_hash": player_info["player_hash"]}
+                    )
+                )
+                assert (
+                    json.loads(websocket.recv())["status"] == 200
+                ), "not accepted player"
+                self.websockets[player_id] = websocket
+            else:
+                player_hash = player_info["player_hash"]
+                print(
+                    f'--general_plus="agent_websocket:{self.websocket_url + player_info["client_id"]};player_hash:{player_hash};agent_id:{player_id}"'
+                )
+                sub = Popen(
+                    " ".join(
+                        [
+                            "exec",
+                            "aaambos",
+                            "run",
+                            "--arch_config",
+                            str(
+                                ROOT_DIR / "game_content" / "agents" / "arch_config.yml"
+                            ),
+                            "--run_config",
+                            str(
+                                ROOT_DIR / "game_content" / "agents" / "run_config.yml"
+                            ),
+                            f'--general_plus="agent_websocket:{self.websocket_url + player_info["client_id"]};player_hash:{player_hash};agent_id:{player_id}"',
+                            f"--instance={player_hash}",
+                        ]
+                    ),
+                    shell=True,
+                )
+                self.sub_processes.append(sub)
+
+            if p + 1 == self.number_humans_to_be_added:
+                self.state_player_id = player_id
+                websocket.send(
+                    json.dumps(
+                        {"type": "get_state", "player_hash": player_info["player_hash"]}
+                    )
+                )
+                state = json.loads(websocket.recv())
+
+        if not self.number_humans_to_be_added:
+            player_id = "0"
+            player_info = env_info["player_info"][player_id]
             websocket = connect(self.websocket_url + player_info["client_id"])
             websocket.send(
                 json.dumps({"type": "ready", "player_hash": player_info["player_hash"]})
             )
             assert json.loads(websocket.recv())["status"] == 200, "not accepted player"
             self.websockets[player_id] = websocket
-        self.state_player_id = player_id
-        websocket.send(
-            json.dumps({"type": "get_state", "player_hash": player_info["player_hash"]})
-        )
-        state = json.loads(websocket.recv())
+            self.state_player_id = player_id
+            websocket.send(
+                json.dumps(
+                    {"type": "get_state", "player_hash": player_info["player_hash"]}
+                )
+            )
+            state = json.loads(websocket.recv())
 
         (
             self.window_width,
@@ -732,7 +794,7 @@ class PyGameGUI:
             ), "Not enough players for key configuration."
         num_key_set = 2 if self.multiple_keysets else 1
         self.key_sets = self.setup_player_keys(
-            max(self.number_players, num_key_set), self.split_players
+            min(self.number_humans_to_be_added, num_key_set), self.split_players
         )
 
         self.setup_environment()
@@ -849,6 +911,18 @@ class PyGameGUI:
         return state
 
     def disconnect_websockets(self):
+        for sub in self.sub_processes:
+            try:
+                sub.kill()
+                pgrp = os.getpgid(sub.pid)
+                os.killpg(pgrp, signal.SIGINT)
+                # subprocess.run(
+                #     "kill $(ps aux | grep 'aaambos' | awk '{print $2}')", shell=True
+                # )
+            except ProcessLookupError:
+                pass
+
+        self.sub_processes = []
         for websocket in self.websockets.values():
             websocket.close()
 
@@ -882,6 +956,11 @@ class PyGameGUI:
                     if event.type == pygame_gui.UI_BUTTON_PRESSED:
                         match event.ui_element:
                             case self.start_button:
+                                if not (
+                                    self.number_humans_to_be_added
+                                    + self.number_bots_to_be_added
+                                ):
+                                    continue
                                 self.start_button_press()
                             case self.back_button:
                                 self.back_button_press()