diff --git a/overcooked_simulator/game_content/environment_config.yaml b/overcooked_simulator/game_content/environment_config.yaml
index 6e58cec45fa0d7c81701afe42a427e8475102447..fdbe1db23264984fa1521d2641c1b49dc2915b41 100644
--- a/overcooked_simulator/game_content/environment_config.yaml
+++ b/overcooked_simulator/game_content/environment_config.yaml
@@ -87,7 +87,8 @@ player_config:
   radius: 0.4
   player_speed_units_per_seconds: 6
   interaction_range: 1.6
-
+  restricted_view: False
+  view_angle: 95
 
 effect_manager:
   FireManager:
diff --git a/overcooked_simulator/game_server.py b/overcooked_simulator/game_server.py
index b6c2675bb1c74c8a750d12c65cb7717f5f70f8d6..c5bb5d2577dd0dde98a76f54474893fd0a838b56 100644
--- a/overcooked_simulator/game_server.py
+++ b/overcooked_simulator/game_server.py
@@ -238,7 +238,7 @@ class EnvironmentHandler:
         ):
             return self.envs[
                 self.player_data[player_hash].env_id
-            ].environment.get_json_state()
+            ].environment.get_json_state(self.player_data[player_hash].player_id)
         if player_hash not in self.player_data:
             return 1
         if self.player_data[player_hash].env_id not in self.envs:
diff --git a/overcooked_simulator/gui_2d_vis/drawing.py b/overcooked_simulator/gui_2d_vis/drawing.py
index 4c6bd198404743e6d3a2179d803015e57a582b94..d9e5e8e22b0c3ad16df665e496c759178cd26262 100644
--- a/overcooked_simulator/gui_2d_vis/drawing.py
+++ b/overcooked_simulator/gui_2d_vis/drawing.py
@@ -146,6 +146,39 @@ class Visualizer:
             grid_size,
         )
 
+        if "view_restriction" in state and state["view_restriction"]:
+            # rotate direction vector in both direction with the angel
+            # draw 2 large rect which are rotated so that one edge is the viewing border
+
+            direction = pygame.math.Vector2(state["view_restriction"]["direction"])
+            pos = pygame.math.Vector2(state["view_restriction"]["position"])
+            angle = state["view_restriction"]["angle"] / 2
+
+            pos = pos * grid_size + pygame.math.Vector2([grid_size / 2, grid_size / 2])
+
+            rect_scale = max(width, height)
+
+            left_beam = pos + (direction.rotate(angle) * rect_scale * 2)
+            right_beam = pos + (direction.rotate(-angle) * rect_scale * 2)
+
+            pygame.draw.polygon(
+                screen,
+                colors["black"],
+                (
+                    pos - (direction * grid_size * 0.6),
+                    left_beam - (direction * grid_size * 0.6),
+                    left_beam + (direction.rotate(90) * rect_scale),
+                    pos
+                    - (direction * rect_scale * 2)
+                    + (direction.rotate(90) * rect_scale),
+                    pos
+                    - (direction * rect_scale * 2)
+                    + (direction.rotate(-90) * rect_scale),
+                    right_beam + (direction.rotate(-90) * rect_scale),
+                    right_beam - (direction * grid_size * 0.6),
+                ),
+            )
+
     def draw_background(
         self, surface: pygame.Surface, width: int, height: int, grid_size: int
     ):
diff --git a/overcooked_simulator/gui_2d_vis/overcooked_gui.py b/overcooked_simulator/gui_2d_vis/overcooked_gui.py
index 9f66332533000c02de2a640d8e55e4884e684588..a4d28c5cb9fe468683db502766b2f2f0c37a7371 100644
--- a/overcooked_simulator/gui_2d_vis/overcooked_gui.py
+++ b/overcooked_simulator/gui_2d_vis/overcooked_gui.py
@@ -28,7 +28,6 @@ from overcooked_simulator.utils import (
     url_and_port_arguments,
     disable_websocket_logging_arguments,
     add_list_of_manager_ids_arguments,
-    setup_logging,
 )
 
 
@@ -936,7 +935,7 @@ class PyGameGUI:
             json.dumps(
                 {
                     "type": "get_state",
-                    "player_hash": self.player_info[self.state_player_id][
+                    "player_hash": self.player_info[str(self.key_sets[0].current_idx)][
                         "player_hash"
                     ],
                 }
diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py
index d11aae3e77b2295a37d9ba943ee437f50398a2c0..3db6ca2f6a610f1c30cb7415bf3f5a83b094abf0 100644
--- a/overcooked_simulator/overcooked_environment.py
+++ b/overcooked_simulator/overcooked_environment.py
@@ -55,6 +55,8 @@ from overcooked_simulator.utils import create_init_env_time, get_closest
 
 log = logging.getLogger(__name__)
 
+FOG_OF_WAR = True
+
 
 PREVENT_SQUEEZING_INTO_OTHER_PLAYERS = False
 
@@ -158,6 +160,14 @@ class Environment:
         )
         """The config of the environment. All environment specific attributes is configured here."""
 
+        self.player_view_restricted = self.environment_config["player_config"][
+            "restricted_view"
+        ]
+        if self.player_view_restricted:
+            self.player_view_angle = self.environment_config["player_config"][
+                "view_angle"
+            ]
+
         self.extra_setup_functions()
 
         self.layout_config = layout_config
@@ -750,25 +760,35 @@ class Environment:
             "remaining_time": max(self.env_time_end - self.env_time, timedelta(0)),
         }
 
-    def get_json_state(self, player_id: str = None):
-        self.hook(PRE_STATE, player_id=player_id)
-        state = {
-            "players": [p.to_dict() for p in self.players.values()],
-            "counters": [c.to_dict() for c in self.counters],
-            "kitchen": {"width": self.kitchen_width, "height": self.kitchen_height},
-            "score": self.order_and_score.score,
-            "orders": self.order_and_score.order_state(),
-            "ended": self.game_ended,
-            "env_time": self.env_time.isoformat(),
-            "remaining_time": max(
-                self.env_time_end - self.env_time, timedelta(0)
-            ).total_seconds(),
-        }
-        self.hook(STATE_DICT, state=state, player_id=player_id)
-        json_data = json.dumps(state)
-        self.hook(JSON_STATE, json_data=json_data, player_id=player_id)
-        assert StateRepresentation.model_validate_json(json_data=json_data)
-        return json_data
+    def get_json_state(self, player_id: str = None) -> str:
+        if player_id in self.players:
+            self.hook(PRE_STATE, player_id=player_id)
+            state = {
+                "players": [p.to_dict() for p in self.players.values()],
+                "counters": [c.to_dict() for c in self.counters],
+                "kitchen": {"width": self.kitchen_width, "height": self.kitchen_height},
+                "score": self.order_and_score.score,
+                "orders": self.order_and_score.order_state(),
+                "ended": self.game_ended,
+                "env_time": self.env_time.isoformat(),
+                "remaining_time": max(
+                    self.env_time_end - self.env_time, timedelta(0)
+                ).total_seconds(),
+                "view_restriction": {
+                    "direction": self.players[player_id].facing_direction.tolist(),
+                    "position": self.players[player_id].pos.tolist(),
+                    "angle": self.player_view_angle,
+                    "counter_mask": None,
+                }
+                if self.player_view_restricted
+                else None,
+            }
+            self.hook(STATE_DICT, state=state, player_id=player_id)
+            json_data = json.dumps(state)
+            self.hook(JSON_STATE, json_data=json_data, player_id=player_id)
+            assert StateRepresentation.model_validate_json(json_data=json_data)
+            return json_data
+        raise ValueError(f"No valid {player_id=}")
 
     def reset_env_time(self):
         """Reset the env time to the initial time, defined by `create_init_env_time`."""
diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py
index 5633a491248ae8b9448d457607b86b8e74121c08..c367561e98862425ecc1590087ef7deb982e608e 100644
--- a/overcooked_simulator/player.py
+++ b/overcooked_simulator/player.py
@@ -33,7 +33,10 @@ class PlayerConfig:
     """The move distance/speed of the player per action call."""
     interaction_range: float = 1.6
     """How far player can interact with counters."""
-
+    restricted_view: bool = False
+    """Whether or not the player can see the entire map at once or just a view frustrum."""
+    view_angle: int | None = None
+    """Angle of the players view if restricted."""
 
 class Player:
     """Class representing a player in the game environment. A player consists of a name, their position and what
diff --git a/overcooked_simulator/state_representation.py b/overcooked_simulator/state_representation.py
index a35f8cd0577e0c231d63e55bcec080c46d39385b..9d4e7427f092fb77769873dd570988e1e3c94f4d 100644
--- a/overcooked_simulator/state_representation.py
+++ b/overcooked_simulator/state_representation.py
@@ -66,6 +66,13 @@ class KitchenInfo(BaseModel):
     height: float
 
 
+class ViewRestriction(BaseModel):
+    direction: list[float]
+    position: list[float]
+    angle: int  # degrees
+    counter_mask: None | list[bool]
+
+
 class StateRepresentation(BaseModel):
     """The format of the returned state representation."""
 
@@ -77,6 +84,7 @@ class StateRepresentation(BaseModel):
     ended: bool
     env_time: datetime  # isoformat str
     remaining_time: float
+    view_restriction: None | ViewRestriction
 
 
 def create_json_schema():