diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py
index 9ae5405596c1d93f9bbec103c3d2de25eece964e..6c0b658572ca9ba6a718083b07b7314153eb1feb 100644
--- a/overcooked_simulator/counters.py
+++ b/overcooked_simulator/counters.py
@@ -1,10 +1,13 @@
 from __future__ import annotations
 
-import logging
 from typing import TYPE_CHECKING, Optional
 
 if TYPE_CHECKING:
-    from overcooked_simulator.overcooked_environment import GameScore
+    from overcooked_simulator.overcooked_environment import (
+        GameScore,
+        PlateManager,
+        SinkManager,
+    )
 
 import numpy as np
 import numpy.typing as npt
@@ -14,10 +17,10 @@ from overcooked_simulator.game_items import (
     Item,
     CookingEquipment,
     Meal,
+    Plate,
+    ItemInfo,
 )
 
-log = logging.getLogger(__name__)
-
 
 class Counter:
     """Simple class for a counter at a specified position (center of counter). Can hold things on top."""
@@ -115,15 +118,18 @@ class CuttingBoard(Counter):
 
 
 class ServingWindow(Counter):
-    def __init__(self, pos, game_score: GameScore):
+    def __init__(self, pos, game_score: GameScore, plate_manager: PlateManager):
         self.game_score = game_score
+        self.plate_manager = plate_manager
         super().__init__(pos)
 
     def drop_off(self, item) -> Item | None:
         reward = 5
-        log.debug(f"Drop off {item}")
+        print(item)
         # TODO define rewards
         self.game_score.increment_score(reward)
+        self.plate_manager.number_returned_plates += 1
+        self.plate_manager.update_plate_return()
         return None
 
     def can_score(self, item):
@@ -171,6 +177,37 @@ class Dispenser(Counter):
         return f"{self.dispensing.name}Dispenser"
 
 
+class DirtyPlateReturn(Counter):
+    def __init__(self, pos, dispensing, plate_manager: PlateManager):
+        self.plate_manager = plate_manager
+        self.dispensing = dispensing
+        super().__init__(pos)
+        self.occupied_by = [
+            self.dispensing.create_item()
+            for _ in range(self.plate_manager.number_returned_plates)
+        ]
+
+    def pick_up(self, on_hands: bool = True):
+        return_this = self.occupied_by.pop()
+        if self.plate_manager.number_returned_plates > 1:
+            self.plate_manager.number_returned_plates -= 1
+        else:
+            self.occupied_by = []
+        return return_this
+
+    def can_drop_off(self, item: Item) -> bool:
+        return False
+
+    def update(self):
+        if self.plate_manager.number_returned_plates == 0:
+            self.occupied_by = []
+        else:
+            self.occupied_by.append(self.dispensing.create_item())
+
+    def __repr__(self):
+        return "PlateReturn"
+
+
 class Trash(Counter):
     def pick_up(self, on_hands: bool = True):
         pass
@@ -200,3 +237,69 @@ class Stove(Counter):
             and self.occupied_by.can_progress()
         ):
             self.occupied_by.progress()
+
+
+class Sink(Counter):
+    def __init__(self, pos, sink_manager):
+        super().__init__(pos)
+        self.progressing = False
+        self.sink_manager: SinkManager = sink_manager
+        self.occupied_by = None
+
+        # TODO: can put multiple things in here and hold the button to do all.
+
+    def progress(self):
+        """Called by environment step function for time progression"""
+        if self.progressing:
+            if isinstance(self.occupied_by, Plate):
+                self.occupied_by.progress()
+                if self.occupied_by.finished:
+                    self.progressing = False
+                    self.occupied_by = None
+                    self.sink_manager.update_move_plate()
+
+    def start_progress(self):
+        """Starts the cutting process."""
+        self.progressing = True
+
+    def pause_progress(self):
+        """Pauses the cutting process"""
+        self.progressing = False
+
+    def interact_start(self):
+        """Handles player interaction, starting to hold key down."""
+        print(self.occupied_by)
+        if isinstance(self.occupied_by, Plate):
+            print(self.occupied_by.can_progress())
+        self.start_progress()
+
+    def interact_stop(self):
+        """Handles player interaction, stopping to hold key down."""
+        self.pause_progress()
+
+    def can_drop_off(self, item: Item) -> bool:
+        return isinstance(item, Plate) and not item.clean
+
+
+class SinkAddon(Counter):
+    def __init__(self, pos, dispensing: ItemInfo):
+        super().__init__(pos)
+        self.dispensing = dispensing
+        self.number_clean_plates = 0
+        self.occupied_by = [
+            self.dispensing.create_item() for _ in range(self.number_clean_plates)
+        ]
+
+    def can_drop_off(self, item: Item) -> bool:
+        return False
+
+    def add_clean_plate(self):
+        self.number_clean_plates += 1
+        plate = self.dispensing.create_item()
+        if isinstance(plate, Plate):
+            plate.finished_call()
+        self.occupied_by.append(plate)
+
+    def pick_up(self, on_hands: bool = True):
+        return_this = self.occupied_by.pop()
+        return return_this
diff --git a/overcooked_simulator/game_content/environment_config.yaml b/overcooked_simulator/game_content/environment_config.yaml
index d1df66da5d0e0c780ce91c3958061dc8edafe43a..ceaf3f69891ac34444392c8922b0d13f93a1d00b 100644
--- a/overcooked_simulator/game_content/environment_config.yaml
+++ b/overcooked_simulator/game_content/environment_config.yaml
@@ -1,3 +1,4 @@
 counter_side_length: 40
 world_width: 800
 world_height: 600
+max_number_plates: 25
\ No newline at end of file
diff --git a/overcooked_simulator/game_content/item_info.yaml b/overcooked_simulator/game_content/item_info.yaml
index 4693e59d56ecc6eadc4c8086dcbb3b6f82782f77..f0af702310f807fbb6f36a26d834c70e4a27a8b5 100644
--- a/overcooked_simulator/game_content/item_info.yaml
+++ b/overcooked_simulator/game_content/item_info.yaml
@@ -22,14 +22,14 @@ Burger:
 
 Salad:
   type: Meal
-  needs: [ ChoppedLettuce, ChoppedTomato ]
+  needs: [ ChoppedLettuce, Tomato ]
   equipment: Plate
 
 TomatoSoup:
   type: Meal
   finished_progress_name: TomatoSoup
   steps_needed: 500
-  needs: [ ChoppedTomato, ChoppedTomato, ChoppedTomato ]
+  needs: [ Tomato, Tomato, Tomato ]
   equipment: Pot
 
 OnionSoup:
@@ -41,6 +41,8 @@ OnionSoup:
 
 Plate:
   type: Equipment
+  is_cuttable: True
+  steps_needed: 200
 
 Pot:
   type: Equipment
diff --git a/overcooked_simulator/game_content/layouts/basic.layout b/overcooked_simulator/game_content/layouts/basic.layout
index 8d31dac9a5076fa7fccf32ce6f151a87fabd28b1..6c0ad9c2d10fd0bb45f85b65bf757e38a347743a 100644
--- a/overcooked_simulator/game_content/layouts/basic.layout
+++ b/overcooked_simulator/game_content/layouts/basic.layout
@@ -1,11 +1,11 @@
 _________________
-_CCUCTNLCC_______
-_C_______C_______
-_C_______C_______
+_##U#TNL##_______
+_#_______#_______
+_#_______#_______
 _W_______________
-_C__A__A_________
+_#__A__A_________
 _P_______________
-_C_______C_______
-_C_______X_______
-_CCBBCCCCC_______
+_#_______#_______
+_#_______X_______
+_##BB##S+#_______
 _________________
diff --git a/overcooked_simulator/game_items.py b/overcooked_simulator/game_items.py
index 55b6f745620b3a09095d691a5944fd2a5d5ef405..621819dc8209d14c49de37ba04fd866132e6df30 100644
--- a/overcooked_simulator/game_items.py
+++ b/overcooked_simulator/game_items.py
@@ -45,7 +45,16 @@ class ItemInfo:
                     )
                 return Item(name=self.name, item_info=self)
             case ItemType.Equipment:
-                return CookingEquipment(name=self.name, item_info=self)
+                if "Plate" in self.name:
+                    return Plate(
+                        name=self.name,
+                        steps_needed=self.steps_needed,
+                        finished=False,
+                        item_info=self,
+                        clean="Clean" in self.name,
+                    )
+                else:
+                    return CookingEquipment(name=self.name, item_info=self)
             case ItemType.Meal:
                 return Meal(
                     name=self.name,
@@ -153,7 +162,7 @@ class CookingEquipment(Item):
             if isinstance(other, CookingEquipment):
                 return other.can_release_content()
             # TODO check other is start of a meal, create meal
-            if isinstance(other, Meal) and self.name == "Plate":
+            if isinstance(other, Meal) and "Plate" in self.name:
                 return not other.steps_needed or other.finished
             return self.item_info.can_start_meal(other)
         return self.content.can_combine(other)
@@ -163,7 +172,7 @@ class CookingEquipment(Item):
             if isinstance(other, CookingEquipment):
                 self.content = other.release()
                 return other
-            if isinstance(other, Meal) and self.name == "Plate":
+            if isinstance(other, Meal) and "Plate" in self.name:
                 self.content = other
                 return
             # find starting meal for other
@@ -230,3 +239,42 @@ class Meal(ProgressibleItem):
     @property
     def extra_repr(self):
         return self.parts
+
+
+class Plate(CookingEquipment):
+    def __init__(
+        self, clean, steps_needed, finished, content: Meal = None, *args, **kwargs
+    ):
+        super().__init__(content, *args, **kwargs)
+        self.clean = clean
+        self.name = self.__repr__()
+        self.steps_needed = steps_needed
+        self.finished = finished
+        self.progressed_steps = steps_needed if finished else 0
+
+    def finished_call(self):
+        self.name = "CleanPlate"
+        self.clean = True
+
+    def progress(self):
+        """Progresses the item process as long as it is not finished."""
+        if self.progressed_steps >= self.steps_needed:
+            self.finished = True
+            self.finished_call()
+        if not self.finished:
+            self.progressed_steps += 1
+
+    def can_progress(self, counter_type="Sink") -> bool:
+        return not self.clean
+
+    def can_combine(self, other):
+        return super().can_combine(other) and self.clean
+
+    def combine(self, other):
+        return super().combine(other)
+
+    def __repr__(self):
+        if self.clean:
+            return "CleanPlate"
+        else:
+            return "DirtyPlate"
diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py
index 599b35d411082aff10444576665fd54b1cacde4f..7fb7f3fc93c66233a2f1a0e652d5757ab8e8352b 100644
--- a/overcooked_simulator/overcooked_environment.py
+++ b/overcooked_simulator/overcooked_environment.py
@@ -3,6 +3,7 @@ from __future__ import annotations
 import logging
 import random
 from pathlib import Path
+from typing import Optional
 
 import numpy as np
 import numpy.typing as npt
@@ -16,6 +17,9 @@ from overcooked_simulator.counters import (
     Dispenser,
     ServingWindow,
     Stove,
+    Sink,
+    DirtyPlateReturn,
+    SinkAddon,
 )
 from overcooked_simulator.game_items import ItemInfo
 # if TYPE_CHECKING:
@@ -24,18 +28,6 @@ from overcooked_simulator.player import Player
 log = logging.getLogger(__name__)
 
 
-class GameScore:
-    def __init__(self):
-        self.score = 0
-
-    def increment_score(self, score: int):
-        self.score += score
-        log.debug(f"Score: {self.score}")
-
-    def read_score(self):
-        return self.score
-
-
 class Action:
     """Action class, specifies player, action type and action itself."""
 
@@ -53,6 +45,48 @@ class Action:
         return f"Action({self.player},{self.act_type},{self.action})"
 
 
+class GameScore:
+    def __init__(self):
+        self.score = 0
+
+    def increment_score(self, score: int):
+        self.score += score
+        log.debug(f"Score: {self.score}")
+
+    def read_score(self):
+        return self.score
+
+
+class PlateManager:
+    def __init__(self, max_number_plates):
+        self.max_number_plates = max_number_plates
+        self.number_returned_plates = max_number_plates
+        self.plates_out_of_kitchen = 0
+
+        self.dirty_plate_return = None
+
+    def return_plate(self):
+        self.number_returned_plates += 1
+
+    def register_plate_return(self, plate_return: DirtyPlateReturn):
+        self.dirty_plate_return = plate_return
+
+    def update_plate_return(self):
+        self.dirty_plate_return.update()
+
+
+class SinkManager:
+    def __init__(self):
+        self.sink: Optional[Sink] = None
+        self.sink_addon: Optional[SinkAddon] = None
+
+    def register_sink_addon(self, sink_addon: SinkAddon):
+        self.sink_addon = sink_addon
+
+    def update_move_plate(self):
+        self.sink_addon.add_clean_plate()
+
+
 class Environment:
     """Environment class which handles the game logic for the overcooked-inspired environment.
 
@@ -72,14 +106,19 @@ class Environment:
         self.item_info = self.load_item_info()
 
         self.game_score = GameScore()
+        self.plate_manager = PlateManager(environment_config["max_number_plates"])
+        self.sink_manager = SinkManager()
+
         self.SYMBOL_TO_CHARACTER_MAP = {
-            "C": Counter,
+            "#": Counter,  # because # looks a bit like a counter
             "B": CuttingBoard,
             "X": Trash,
-            "W": lambda pos: ServingWindow(pos, self.game_score),
+            "W": lambda pos: ServingWindow(pos, self.game_score, self.plate_manager),
             "T": lambda pos: Dispenser(pos, self.item_info["Tomato"]),
             "L": lambda pos: Dispenser(pos, self.item_info["Lettuce"]),
-            "P": lambda pos: Dispenser(pos, self.item_info["Plate"]),
+            "P": lambda pos: DirtyPlateReturn(
+                pos, self.item_info["Plate"], self.plate_manager
+            ),
             "N": lambda pos: Dispenser(pos, self.item_info["Onion"]),  # N for oNioN
             "_": "Free",
             "A": "Agent",
@@ -87,6 +126,8 @@ class Environment:
                 pos,
                 self.item_info["Pot"].create_item(),
             ),  # Stove with pot: U because it looks like a pot
+            "S": lambda pos: Sink(pos, self.sink_manager),
+            "+": lambda pos: SinkAddon(pos, self.item_info["Plate"]),
         }
 
         (
@@ -126,6 +167,8 @@ class Environment:
         designated_player_positions: list[npt.NDArray] = []
         free_positions: list[npt.NDArray] = []
 
+        # TODO: Sink and sink addon have to be next to each other!
+
         with open(layout_file, "r") as layout_file:
             lines = layout_file.readlines()
         for line in lines:
@@ -137,7 +180,11 @@ class Environment:
                 counter_class = self.SYMBOL_TO_CHARACTER_MAP[character]
                 if not isinstance(counter_class, str):
                     counter = counter_class(pos)
+                    if isinstance(counter, DirtyPlateReturn):
+                        self.plate_manager.register_plate_return(counter)
                     counters.append(counter)
+                    if isinstance(counter, SinkAddon):
+                        self.sink_manager.register_sink_addon(counter)
                 else:
                     if counter_class == "Agent":
                         designated_player_positions.append(
@@ -396,7 +443,7 @@ class Environment:
         and time limits.
         """
         for counter in self.counters:
-            if isinstance(counter, (CuttingBoard, Stove)):
+            if isinstance(counter, (CuttingBoard, Stove, Sink)):
                 counter.progress()
 
     def get_state(self):
diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py
index 5e0fa68804c7513d1b6f081d89f9bec4cd47a806..49317e405e3e1e3688a85eb922af718c412fd4c1 100644
--- a/overcooked_simulator/player.py
+++ b/overcooked_simulator/player.py
@@ -107,7 +107,7 @@ class Player:
         elif counter.can_drop_off(self.holding):
             self.holding = counter.drop_off(self.holding)
 
-        elif self.holding.can_combine(counter.occupied_by):
+        elif not isinstance(counter.occupied_by, list) and self.holding.can_combine(counter.occupied_by):
             returned_by_counter = counter.pick_up(on_hands=False)
             self.holding.combine(returned_by_counter)
 
diff --git a/overcooked_simulator/pygame_gui/images/plate_clean.png b/overcooked_simulator/pygame_gui/images/plate_clean.png
new file mode 100644
index 0000000000000000000000000000000000000000..02c23be7bd183e8efa6222cdbccf11c6f7c2ea20
Binary files /dev/null and b/overcooked_simulator/pygame_gui/images/plate_clean.png differ
diff --git a/overcooked_simulator/pygame_gui/images/plate_dirty.png b/overcooked_simulator/pygame_gui/images/plate_dirty.png
new file mode 100644
index 0000000000000000000000000000000000000000..f19ce7e3448af63ca00c8d0f23c9ce5336a8d211
Binary files /dev/null and b/overcooked_simulator/pygame_gui/images/plate_dirty.png differ
diff --git a/overcooked_simulator/pygame_gui/pygame_gui.py b/overcooked_simulator/pygame_gui/pygame_gui.py
index 24c42107ae6a1064552d08d9b7c0300553586c72..5b0070c208324bec5c24cf8daec27ee0f8154ec6 100644
--- a/overcooked_simulator/pygame_gui/pygame_gui.py
+++ b/overcooked_simulator/pygame_gui/pygame_gui.py
@@ -15,13 +15,14 @@ from overcooked_simulator.game_items import (
     Item,
     CookingEquipment,
     Meal,
+    Plate,
 )
 from overcooked_simulator.overcooked_environment import Action
 from overcooked_simulator.pygame_gui.game_colors import BLUE
 from overcooked_simulator.pygame_gui.game_colors import colors, Color
 from overcooked_simulator.simulation_runner import Simulator
 
-USE_PLAYER_COOK_SPRITES = False
+USE_PLAYER_COOK_SPRITES = True
 SHOW_INTERACTION_RANGE = False
 
 
@@ -324,7 +325,7 @@ class PyGameGUI:
                     pos, self.visualization_config[item.name]["parts"], scale=scale
                 )
 
-        if isinstance(item, ProgressibleItem) and not item.finished:
+        if isinstance(item, (ProgressibleItem, Plate)) and not item.finished:
             self.draw_progress_bar(pos, item.progressed_steps, item.steps_needed)
 
         if isinstance(item, CookingEquipment) and item.content:
diff --git a/overcooked_simulator/pygame_gui/visualization.yaml b/overcooked_simulator/pygame_gui/visualization.yaml
index df6f702c079771a958a53f8230782ee8dce8fbee..05d58ec703de0822559ec9a4e880c7f2e3af49c3 100644
--- a/overcooked_simulator/pygame_gui/visualization.yaml
+++ b/overcooked_simulator/pygame_gui/visualization.yaml
@@ -21,7 +21,7 @@ CuttingBoard:
       center_offset: [ +0.15, -0.2 ]
       color: silver
 
-PlateDispenser:
+DirtyPlateReturn:
   parts:
     - type: rect
       height: 0.95
@@ -76,6 +76,26 @@ Stove:
       type: circle
       radius: 0.25
 
+Sink:
+  parts:
+    - color: black
+      type: rect
+      height: 0.875
+      width: 0.625
+    - color: darkslategray1
+      type: circle
+      radius: 0.4
+
+SinkAddon:
+  parts:
+    - color: black
+      type: rect
+      height: 0.875
+      width: 0.625
+    - color: darkslategray1
+      type: circle
+      radius: 0.4
+
 # Items
 Tomato:
   parts:
@@ -175,11 +195,17 @@ Cook:
       path: images/pixel_cook.png
       size: 1
 
-Plate:
+CleanPlate:
   parts:
     - type: image
-      path: images/plate.png
-      size: 1
+      path: images/plate_clean.png
+      size: 0.8
+
+DirtyPlate:
+  parts:
+    - type: image
+      path: images/plate_dirty.png
+      size: 0.8
 
 Pot:
   parts: