diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py
index 41bd67eeb5c10e23ea15538dd90fe9ca1afce515..d62109ebaf861a8daf05e1e10740d80cfe5dc441 100644
--- a/overcooked_simulator/counters.py
+++ b/overcooked_simulator/counters.py
@@ -1,7 +1,9 @@
 from __future__ import annotations
 
 import logging
+import uuid
 from collections import deque
+from collections.abc import Iterable
 from datetime import datetime, timedelta
 from typing import TYPE_CHECKING, Optional, Callable
 
@@ -23,11 +25,19 @@ from overcooked_simulator.game_items import (
 
 log = logging.getLogger(__name__)
 
+COUNTER_CATEGORY = "Counter"
+
 
 class Counter:
     """Simple class for a counter at a specified position (center of counter). Can hold things on top."""
 
-    def __init__(self, pos: npt.NDArray[float], occupied_by: Optional[Item] = None):
+    def __init__(
+        self,
+        pos: npt.NDArray[float],
+        occupied_by: Optional[Item] = None,
+        uid: hex = None,
+    ):
+        self.uuid = uuid.uuid4().hex if uid is None else None
         self.pos: npt.NDArray[float] = pos
         self.occupied_by: Optional[Item] = occupied_by
 
@@ -94,6 +104,21 @@ class Counter:
             f"{self.__class__.__name__}(pos={self.pos},occupied_by={self.occupied_by})"
         )
 
+    def to_dict(self) -> dict:
+        return {
+            "id": self.uuid,
+            "category": COUNTER_CATEGORY,
+            "type": self.__class__.__name__,
+            "pos": self.pos.tolist(),
+            "occupied_by": None
+            if self.occupied_by is None
+            else (
+                [o.to_dict() for o in self.occupied_by]
+                if isinstance(self.occupied_by, Iterable)
+                else self.occupied_by.to_dict()
+            ),
+        }
+
 
 class CuttingBoard(Counter):
     def __init__(self, pos: np.ndarray, transitions: dict):
@@ -137,6 +162,11 @@ class CuttingBoard(Counter):
         """Handles player interaction, stopping to hold key down."""
         self.pause_progress()
 
+    def to_dict(self) -> dict:
+        d = super().to_dict()
+        d.update((("progressing", self.progressing),))
+        return d
+
 
 class ServingWindow(Counter):
     def __init__(
@@ -204,6 +234,11 @@ class Dispenser(Counter):
         }
         return Item(**kwargs)
 
+    def to_dict(self) -> dict:
+        d = super().to_dict()
+        d.update((("type", self.__repr__()),))
+        return d
+
 
 class PlateDispenser(Counter):
     def __init__(
@@ -360,7 +395,6 @@ class Sink(Counter):
             )
             if self.occupied_by[-1].progress_percentage == 1.0:
                 self.occupied_by[-1].reset()
-                print(self.transitions[self.occupied_by[-1].name]["result"])
                 self.occupied_by[-1].name = self.transitions[self.occupied_by[-1].name][
                     "result"
                 ]
@@ -397,6 +431,11 @@ class Sink(Counter):
     def set_addon(self, sink_addon):
         self.sink_addon = sink_addon
 
+    def to_dict(self) -> dict:
+        d = super().to_dict()
+        d.update((("progressing", self.progressing),))
+        return d
+
 
 class SinkAddon(Counter):
     def __init__(self, pos, occupied_by=None):
diff --git a/overcooked_simulator/game_items.py b/overcooked_simulator/game_items.py
index 4592e68bbe4057719b3618fbf7b34513fb4d232b..ac244df9660d113248437c27d5911a12b880051e 100644
--- a/overcooked_simulator/game_items.py
+++ b/overcooked_simulator/game_items.py
@@ -4,11 +4,15 @@ import collections
 import dataclasses
 import datetime
 import logging
+import uuid
 from enum import Enum
 from typing import Optional
 
 log = logging.getLogger(__name__)
 
+ITEM_CATEGORY = "Item"
+COOKING_EQUIPMENT_ITEM_CATEGORY = "ItemCookingEquipment"
+
 
 class ItemType(Enum):
     Ingredient = "Ingredient"
@@ -58,11 +62,16 @@ class ItemInfo:
 class Item:
     """Base class for game items which can be held by a player."""
 
-    def __init__(self, name: str, item_info: ItemInfo, *args, **kwargs):
+    item_category = ITEM_CATEGORY
+
+    def __init__(
+        self, name: str, item_info: ItemInfo, uid: str = None, *args, **kwargs
+    ):
         self.name = self.__class__.__name__ if name is None else name
         self.item_info = item_info
         self.progress_equipment = None
         self.progress_percentage = 0.0
+        self.uuid = uuid.uuid4().hex if uid is None else uid
 
     def __repr__(self):
         if self.progress_equipment is None:
@@ -100,13 +109,24 @@ class Item:
         self.progress_equipment = None
         self.progress_percentage = 0.0
 
+    def to_dict(self) -> dict:
+        return {
+            "id": self.uuid,
+            "category": self.item_category,
+            "type": self.name,
+            "progress_percentage": self.progress_percentage,
+        }
+
 
 class CookingEquipment(Item):
+    item_category = "Cooking Equipment"
+
     def __init__(self, transitions: dict, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.transitions = transitions
         self.active_transition: Optional[dict] = None
 
+        # TODO change content ready just to str (name of the item)?
         self.content_ready: Item | None = None
         self.content_list: list[Item] = []
 
@@ -129,7 +149,6 @@ class CookingEquipment(Item):
         ingredients = collections.Counter(
             item.name for item in self.content_list + other
         )
-        print(ingredients)
         return any(
             ingredients <= recipe["recipe"] for recipe in self.transitions.values()
         )
@@ -156,7 +175,6 @@ class CookingEquipment(Item):
                         "seconds": transition["seconds"],
                         "result": Item(name=result, item_info=transition["info"]),
                     }
-                    print(f"{self.name} {self.active_transition}, {self.content_list}")
                 break
         else:
             self.content_ready = None
@@ -204,6 +222,21 @@ class CookingEquipment(Item):
             return self.content_list[0]
         return None
 
+    def to_dict(self) -> dict:
+        d = super().to_dict()
+        d.update(
+            (
+                ("content_list", [c.to_dict() for c in self.content_list]),
+                (
+                    "content_ready",
+                    self.content_ready.to_dict()
+                    if self.content_ready is not None
+                    else None,
+                ),
+            )
+        )
+        return d
+
 
 class Plate(CookingEquipment):
     def __init__(self, transitions, clean, *args, **kwargs):
diff --git a/overcooked_simulator/game_server.py b/overcooked_simulator/game_server.py
index 30ae33140122dd66e90bfede32a312597ea1f720..92aaad5af0a9703805d431577dac8069b8425b72 100644
--- a/overcooked_simulator/game_server.py
+++ b/overcooked_simulator/game_server.py
@@ -149,7 +149,7 @@ class EnvironmentHandler:
             # TODO normal json state
             return self.envs[
                 self.player_data[player_hash].env_id
-            ].environment.get_state_simple_json()
+            ].environment.get_json_state()
 
     def pause_env(self, manager_id: str, env_id: str, reason: str):
         if (
@@ -195,6 +195,9 @@ class EnvironmentHandler:
 
     def set_player_disconnected(self, client_id: str) -> bool:
         if client_id in self.client_ids_to_player_hashes:
+            log.warning(
+                f"Player {self.player_data[self.client_ids_to_player_hashes[client_id]].player_id} in env {self.player_data[self.client_ids_to_player_hashes[client_id]].env_id} disconnected"
+            )
             self.player_data[
                 self.client_ids_to_player_hashes[client_id]
             ].connected = False
diff --git a/overcooked_simulator/gui_2d_vis/drawing.py b/overcooked_simulator/gui_2d_vis/drawing.py
index 26b19a85f382e7d4b34cc1ef5e7f692b08863cb7..00f5990c0bce8124ef56b56e61803b358febd6b5 100644
--- a/overcooked_simulator/gui_2d_vis/drawing.py
+++ b/overcooked_simulator/gui_2d_vis/drawing.py
@@ -1,5 +1,6 @@
 import colorsys
 import math
+from datetime import datetime, timedelta
 from pathlib import Path
 
 import numpy as np
@@ -9,7 +10,6 @@ from scipy.spatial import KDTree
 
 from overcooked_simulator import ROOT_DIR
 from overcooked_simulator.gui_2d_vis.game_colors import colors
-from overcooked_simulator.order import Order
 
 
 def create_polygon(n, length):
@@ -139,7 +139,7 @@ class Visualizer:
         for p_idx, player_dict in enumerate(state_dict["players"]):
             pos = np.array(player_dict["pos"]) * grid_size
 
-            facing = np.array(player_dict["facing"])
+            facing = np.array(player_dict["facing_direction"])
 
             if USE_PLAYER_COOK_SPRITES:
                 img_path = self.config["Cook"]["parts"][0]["path"]
@@ -193,27 +193,26 @@ class Visualizer:
 
             if player_dict["holding"] is not None:
                 holding_item_pos = pos + (20 * facing)
-
-                self.draw_thing(
-                    holding_item_pos,
-                    self.config[player_dict["holding"]]["parts"],
+                self.draw_item(
+                    pos=holding_item_pos,
+                    grid_size=grid_size,
+                    item=player_dict["holding"],
+                    screen=screen,
                 )
-                
-                # TODO MAKE THIS WORK
-                # if player.current_nearest_counter:
-                #     counter: Counter = player.current_nearest_counter
-                #     pos = counter.pos * self.grid_size
-                #     pygame.draw.rect(
-                #         self.game_screen,
-                #         colors[self.player_colors[p_idx]],
-                #         rect=pygame.Rect(
-                #             pos[0] - (self.grid_size // 2),
-                #             pos[1] - (self.grid_size // 2),
-                #             self.grid_size,
-                #             self.grid_size,
-                #         ),
-                #         width=2,
-                #     )
+
+                if player_dict["current_nearest_counter_pos"]:
+                    pos = player_dict["current_nearest_counter_pos"]
+                    pygame.draw.rect(
+                        screen,
+                        colors[self.player_colors[p_idx]],
+                        rect=pygame.Rect(
+                            pos[0] * grid_size - (grid_size // 2),
+                            pos[1] * grid_size - (grid_size // 2),
+                            grid_size,
+                            grid_size,
+                        ),
+                        width=2,
+                    )
 
     def draw_thing(
         self,
@@ -267,18 +266,17 @@ class Visualizer:
                         pygame.draw.circle(
                             screen,
                             color,
-                            pos + (np.array(part["center_offset"]) * grid_size),
+                            np.array(pos)
+                            + (np.array(part["center_offset"]) * grid_size),
                             radius,
                         )
                     else:
                         pygame.draw.circle(screen, color, pos, radius)
 
-    # TODO MAKE THIS WORK
     def draw_item(
         self,
         pos: npt.NDArray[float],
         grid_size,
-        config,
         item,
         scale: float = 1.0,
         plate=False,
@@ -297,40 +295,47 @@ class Visualizer:
         """
 
         if not isinstance(item, list):
-            if item.name in config:
-                item_key = item.name
-                if "Soup" in item.name and plate:
+            if item["type"] in self.config:
+                item_key = item["type"]
+                if "Soup" in item_key and plate:
                     item_key += "Plate"
                 self.draw_thing(
-                    pos,
-                    config[item_key]["parts"],
+                    pos=pos,
+                    parts=self.config[item_key]["parts"],
                     scale=scale,
                     screen=screen,
+                    grid_size=grid_size,
                 )
                 #
-        if isinstance(item, (Item, Plate)) and item.progress_percentage > 0.0:
-            self.draw_progress_bar(screen, pos, item.progress_percentage)
+        if "progress_percentage" in item and item["progress_percentage"] > 0.0:
+            self.draw_progress_bar(
+                screen, pos, item["progress_percentage"], grid_size=grid_size
+            )
 
-        if isinstance(item, CookingEquipment) and item.content_list:
-            if item.content_ready and item.content_ready.name in config:
-                self.draw_thing(
-                    pos,
-                    config[item.content_ready.name]["parts"],
+        if (
+            "content_ready" in item
+            and item["content_ready"]
+            and item["content_ready"]["type"] in self.config
+        ):
+            self.draw_thing(
+                pos=pos,
+                parts=self.config[item["content_ready"]["type"]]["parts"],
+                screen=screen,
+                grid_size=grid_size,
+            )
+        elif "content_list" in item and item["content_list"]:
+            triangle_offsets = create_polygon(len(item["content_list"]), length=10)
+            scale = 1 if len(item["content_list"]) == 1 else 0.6
+            for idx, o in enumerate(item["content_list"]):
+                self.draw_item(
+                    pos=np.array(pos) + triangle_offsets[idx],
+                    item=o,
+                    scale=scale,
+                    plate="Plate" in item["type"],
                     screen=screen,
+                    grid_size=grid_size,
                 )
-            else:
-                triangle_offsets = create_polygon(len(item.content_list), length=10)
-                scale = 1 if len(item.content_list) == 1 else 0.6
-                for idx, o in enumerate(item.content_list):
-                    self.draw_item(
-                        pos + triangle_offsets[idx],
-                        o,
-                        scale=scale,
-                        plate=isinstance(item, Plate),
-                        screen=screen,
-                    )
 
-    # TODO MAKE THIS WORK
     def draw_progress_bar(
         self,
         screen: pygame.Surface,
@@ -364,27 +369,31 @@ class Visualizer:
             self.draw_thing(screen, pos, grid_size, self.config[counter_type]["parts"])
         else:
             self.draw_thing(
-                screen,
-                pos,
-                self.config[counter_type]["parts"],
+                screen=screen,
+                pos=pos,
+                parts=self.config[counter_type]["parts"],
+                grid_size=grid_size,
             )
 
         occupied_by = counter_dict["occupied_by"]
         if occupied_by is not None:
             # Multiple plates on plate return:
-            # if isinstance(occupied_by, (list, deque)):
-            #     with self.simulator.env.lock:
-            #
-            #     for i, o in enumerate(occupied_by):
-            #             self.draw_item(np.abs([pos[0], pos[1] - (i * 3)]), o)
-            # # All other items:
-            # else:
-            self.draw_thing(
-                screen,
-                pos,
-                grid_size,
-                self.config[occupied_by]["parts"],
-            )
+            if isinstance(occupied_by, list):
+                for i, o in enumerate(occupied_by):
+                    self.draw_item(
+                        screen=screen,
+                        pos=np.abs([pos[0], pos[1] - (i * 3)]),
+                        grid_size=grid_size,
+                        item=o,
+                    )
+            # All other items:
+            else:
+                self.draw_item(
+                    pos=pos,
+                    grid_size=grid_size,
+                    item=occupied_by,
+                    screen=screen,
+                )
 
     def draw_counters(
         self, screen: pygame, state, grid_size, SHOW_COUNTER_CENTERS=False
@@ -398,13 +407,11 @@ class Visualizer:
             if SHOW_COUNTER_CENTERS:
                 pygame.draw.circle(screen, colors["green1"], counter.pos, 3)
 
-    # TODO MAKE THIS WORK
     def draw_orders(
         self, screen, state, grid_size, width, height, screen_margin, config
     ):
         orders_width = width - 100
         orders_height = screen_margin
-
         order_screen = pygame.Surface(
             (orders_width, orders_height),
         )
@@ -414,9 +421,8 @@ class Visualizer:
 
         order_rects_start = (orders_height // 2) - (grid_size // 2)
         for idx, order in enumerate(state["orders"]):
-            order: Order
             order_upper_left = [
-                order_rects_start + idx * self.grid_size * 1.2,
+                order_rects_start + idx * grid_size * 1.2,
                 order_rects_start,
             ]
             pygame.draw.rect(
@@ -425,31 +431,42 @@ class Visualizer:
                 pygame.Rect(
                     order_upper_left[0],
                     order_upper_left[1],
-                    self.grid_size,
-                    self.grid_size,
+                    grid_size,
+                    grid_size,
                 ),
                 width=2,
             )
             center = np.array(order_upper_left) + np.array(
-                [self.grid_size / 2, self.grid_size / 2]
+                [grid_size / 2, grid_size / 2]
             )
             self.draw_thing(
-                center,
-                config["Plate"]["parts"],
+                pos=center,
+                parts=config["Plate"]["parts"],
                 screen=order_screen,
+                grid_size=grid_size,
             )
             self.draw_item(
-                center,
-                order.meal,
+                pos=center,
+                item={"type": order["meal"]},
                 plate=True,
                 screen=order_screen,
+                grid_size=grid_size,
             )
             order_done_seconds = (
-                (order.start_time + order.max_duration) - state["env_time"]
+                (
+                    datetime.fromisoformat(order["start_time"])
+                    + timedelta(seconds=order["max_duration"])
+                )
+                - datetime.fromisoformat(state["env_time"])
             ).total_seconds()
 
-            percentage = order_done_seconds / order.max_duration.total_seconds()
-            self.draw_progress_bar(center, percentage, screen=order_screen)
+            percentage = order_done_seconds / order["max_duration"]
+            self.draw_progress_bar(
+                pos=center,
+                percent=percentage,
+                screen=order_screen,
+                grid_size=grid_size,
+            )
 
         orders_rect = order_screen.get_rect()
         orders_rect.center = [
diff --git a/overcooked_simulator/gui_2d_vis/overcooked_gui.py b/overcooked_simulator/gui_2d_vis/overcooked_gui.py
index da414675aaea7fed35422a7f7953d95447f5deb8..1b4695f9fa4e98471116a5285616ee73ce78b587 100644
--- a/overcooked_simulator/gui_2d_vis/overcooked_gui.py
+++ b/overcooked_simulator/gui_2d_vis/overcooked_gui.py
@@ -340,7 +340,15 @@ class PyGameGUI:
         # self.manager.draw_ui(self.main_window)
         self.update_remaining_time(state["remaining_time"])
 
-        # self.draw_orders(state)
+        self.vis.draw_orders(
+            screen=self.game_screen,
+            state=state,
+            grid_size=self.grid_size,
+            width=self.game_width,
+            height=self.game_height,
+            screen_margin=self.screen_margin,
+            config=self.visualization_config,
+        )
         self.update_score_label(state)
 
     def set_window_size(self):
@@ -416,7 +424,7 @@ class PyGameGUI:
 
         environment_config_path = ROOT_DIR / "game_content" / "environment_config.yaml"
         layout_path = ROOT_DIR / "game_content" / "layouts" / "basic.layout"
-        item_info_path = ROOT_DIR / "game_content" / "item_info.yaml"
+        item_info_path = ROOT_DIR / "game_content" / "item_info_debug.yaml"
         with open(item_info_path, "r") as file:
             item_info = file.read()
         with open(layout_path, "r") as file:
@@ -585,7 +593,7 @@ class PyGameGUI:
                                 self.disconnect_websockets()
                             case self.reset_button:
                                 self.reset_button_press()
-                                self.disconnect_websockets()
+                                self.start_button_press()
 
                         self.manage_button_visibility()
 
diff --git a/overcooked_simulator/order.py b/overcooked_simulator/order.py
index 5d7abbf72cdbbd1a6d2fe110934b8561d342ca44..13ce34c391152499782c9439bfcd6115cbc84521 100644
--- a/overcooked_simulator/order.py
+++ b/overcooked_simulator/order.py
@@ -1,6 +1,7 @@
 import dataclasses
 import logging
 import random
+import uuid
 from abc import abstractmethod
 from collections import deque
 from datetime import datetime, timedelta
@@ -10,6 +11,8 @@ from overcooked_simulator.game_items import Item, Plate, ItemInfo
 
 log = logging.getLogger(__name__)
 
+ORDER_CATEGORY = "Order"
+
 
 @dataclasses.dataclass
 class Order:
@@ -21,6 +24,7 @@ class Order:
         Tuple[timedelta, float] | Tuple[timedelta, float, int, timedelta]
     ]
     expired_penalty: float
+    uuid: str = dataclasses.field(default_factory=lambda: uuid.uuid4().hex)
 
     finished_info: dict[str, Any] = dataclasses.field(default_factory=dict)
     _timed_penalties: list[Tuple[datetime, float]] = dataclasses.field(
@@ -315,6 +319,18 @@ class OrderAndScoreManager:
         for order in new_orders:
             order.create_penalties(env_time)
 
+    def order_state(self) -> list[dict]:
+        return [
+            {
+                "id": order.uuid,
+                "category": ORDER_CATEGORY,
+                "meal": order.meal.name,
+                "start_time": order.start_time.isoformat(),
+                "max_duration": order.max_duration.total_seconds(),
+            }
+            for order in self.open_orders
+        ]
+
 
 if __name__ == "__main__":
     import yaml
diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py
index ba97fbe2c7d24f353e3eb222b0847efbdf830f75..d4b2bdee8af7e20e78ddaa41ff33e64a8aae3f4c 100644
--- a/overcooked_simulator/overcooked_environment.py
+++ b/overcooked_simulator/overcooked_environment.py
@@ -33,6 +33,7 @@ from overcooked_simulator.game_items import (
 )
 from overcooked_simulator.order import OrderAndScoreManager
 from overcooked_simulator.player import Player
+from overcooked_simulator.state_representation import StateRepresentation
 from overcooked_simulator.utils import create_init_env_time
 
 log = logging.getLogger(__name__)
@@ -200,7 +201,7 @@ class Environment:
 
         self.env_time: datetime.datetime = create_init_env_time()
         self.order_and_score.create_init_orders(self.env_time)
-        self.beginning_time = self.env_time
+        self.start_time = self.env_time
         self.env_time_end = self.env_time + timedelta(
             seconds=self.environment_config["game"]["time_limit_seconds"]
         )
@@ -617,6 +618,22 @@ class Environment:
             "remaining_time": max(self.env_time_end - self.env_time, timedelta(0)),
         }
 
+    def get_json_state(self, player_id: str | int = None):
+        state = {
+            "players": [p.to_dict() for p in self.players.values()],
+            "counters": [c.to_dict() for c in self.counters],
+            "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(),
+        }
+        json_data = json.dumps(state)
+        assert StateRepresentation.model_validate_json(json_data=json_data)
+        return json_data
+
     def get_state_simple_json(self):
         """Get the current state of the game environment as a json-like nested dictionary.
 
diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py
index ed1c29a950b423c5d673683dc676e9313035b292..4283e76f43b77725b7410d279f5859456548c998 100644
--- a/overcooked_simulator/player.py
+++ b/overcooked_simulator/player.py
@@ -144,3 +144,18 @@ class Player:
 
     def __repr__(self):
         return f"Player(name:{self.name},pos:{str(self.pos)},holds:{self.holding})"
+
+    def to_dict(self):
+        # TODO add color to player class for vis independent player color
+        return {
+            "id": self.name,
+            "pos": self.pos.tolist(),
+            "facing_direction": self.facing_direction.tolist(),
+            "holding": self.holding.to_dict() if self.holding else None,
+            "current_nearest_counter_pos": self.current_nearest_counter.pos.tolist()
+            if self.current_nearest_counter
+            else None,
+            "current_nearest_counter_id": self.current_nearest_counter.uuid
+            if self.current_nearest_counter
+            else None,
+        }
diff --git a/overcooked_simulator/state_representation.py b/overcooked_simulator/state_representation.py
new file mode 100644
index 0000000000000000000000000000000000000000..e8ad5d17a79b4db29c2977934f0127c7a09c83f9
--- /dev/null
+++ b/overcooked_simulator/state_representation.py
@@ -0,0 +1,68 @@
+from datetime import datetime
+
+from pydantic import BaseModel
+from typing_extensions import Literal, TypedDict
+
+
+class OrderState(TypedDict):
+    id: str
+    category: Literal["Order"]
+    meal: str
+    start_time: datetime  # isoformat str
+    max_duration: float
+
+
+class ItemState(TypedDict):
+    id: str
+    category: Literal["Item"] | Literal["ItemCookingEquipment"]
+    type: str
+    progress_percentage: float | int
+    # add ItemType Meal ?
+
+
+class CookingEquipmentState(TypedDict):
+    content_list: list[ItemState]
+    content_ready: None | ItemState
+
+
+class CounterState(TypedDict):
+    id: str
+    category: Literal["Counter"]
+    type: str
+    pos: list[float]
+    occupied_by: None | list[
+        ItemState | CookingEquipmentState
+    ] | ItemState | CookingEquipmentState
+    # list[ItemState] -> type in ["Sink", "PlateDispenser"]
+
+
+class CuttingBoardAndSinkState(TypedDict):
+    type: Literal["CuttingBoard"] | Literal["Sink"]
+    progressing: bool
+
+
+class PlayerState(TypedDict):
+    id: str
+    pos: list[float]
+    facing_direction: list[float]
+    holding: ItemState | CookingEquipmentState | None
+    current_nearest_counter_pos: list[float] | None
+    current_nearest_counter_id: str | None
+
+
+class StateRepresentation(BaseModel):
+    players: list[PlayerState]
+    counters: list[CounterState]
+    score: float | int
+    orders: list[OrderState]
+    ended: bool
+    env_time: datetime  # isoformat str
+    remaining_time: float
+
+
+def create_json_schema():
+    return StateRepresentation.model_json_schema()
+
+
+if __name__ == "__main__":
+    print(create_json_schema())
diff --git a/tests/test_start.py b/tests/test_start.py
index 0f71d0e7c7feb9605cbc926b112627d7b1a20a66..3dc676af7bc5c79d6a2d4bb1b78643c50f6b1721 100644
--- a/tests/test_start.py
+++ b/tests/test_start.py
@@ -291,7 +291,7 @@ def test_time_limit():
     assert not env.game_ended, "Game has not ended yet"
 
     passed_time_2 = timedelta(
-        seconds=(env.env_time_end - env.beginning_time).total_seconds()
+        seconds=(env.env_time_end - env.start_time).total_seconds()
     )
     env.step(passed_time_2)