diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py
index b77bc0ca4e2d110022183c039fafe9f81d3e5417..b480c1c109d390defd848f9d1727bb713c4696d3 100644
--- a/overcooked_simulator/counters.py
+++ b/overcooked_simulator/counters.py
@@ -15,7 +15,7 @@ from overcooked_simulator.game_items import (
     Plate,
     Tomato,
     Pot,
-    Pan,
+    CookingEquipment,
 )
 
 
@@ -33,9 +33,17 @@ class Counter:
         Returns: The item which the counter is occupied by. None if nothing is there.
 
         """
-        give_player = self.occupied_by
+        if on_hands:
+            if self.occupied_by:
+                occupied_by = self.occupied_by
+                self.occupied_by = None
+                return occupied_by
+            return None
+        if self.occupied_by and isinstance(self.occupied_by, CookingEquipment):
+            return self.occupied_by.release()
+        occupied_by = self.occupied_by
         self.occupied_by = None
-        return give_player
+        return occupied_by
 
     def can_drop_off(self, item: Item) -> bool:
         """Checks whether an item by the player can be dropped of. More relevant for example with
@@ -61,7 +69,7 @@ class Counter:
         if self.occupied_by is None:
             self.occupied_by = item
         elif self.occupied_by.can_combine(item):
-            self.occupied_by.combine(item)
+            return self.occupied_by.combine(item)
         return None
 
     def interact_start(self):
@@ -160,8 +168,7 @@ class PlateReturn(Counter):
             self.occupied_by.append(item)
             return None
         if self.occupied_by[-1].can_combine(item):
-            self.occupied_by[-1].combine(item)
-            return None
+            return self.occupied_by[-1].combine(item)
         return item
 
     def can_drop_off(self, item: Item) -> bool:
@@ -201,6 +208,9 @@ class Trash(Counter):
         if isinstance(item, Plate):
             item.holds = None
             return item
+        if isinstance(item, CookingEquipment):
+            item.content = None
+            return item
         return None
 
     def can_drop_off(self, item: Item) -> bool:
@@ -213,32 +223,25 @@ class Stove(Counter):
             occupied_by = Pot()
         super().__init__(pos, occupied_by)
 
-    def pick_up(self, on_hands: bool = True):
-        if on_hands:
-            if self.occupied_by:
-                occupied_by = self.occupied_by
-                self.occupied_by = None
-                return occupied_by
-            return None
-        if self.occupied_by and self.occupied_by.holds:
-            soup = self.occupied_by.holds.pop(0)
-            return soup
-
-    def drop_off(self, item) -> Item | None:
-        if isinstance(item, (Pot, Pan)):
-            self.occupied_by = item
-        else:
-            self.occupied_by.combine(item)
-        return None
-
-    def can_drop_off(self, item) -> bool:
-        if isinstance(item, (Pot, Pan)):
-            return not self.occupied_by
-        if self.occupied_by:
-            return self.occupied_by.can_combine(item)
-        return False
+    # def drop_off(self, item) -> Item | None:
+    #     if isinstance(item, (Pot, Pan)):
+    #         self.occupied_by = item
+    #     else:
+    #         self.occupied_by.combine(item)
+    #     return None
+    #
+    # def can_drop_off(self, item) -> bool:
+    #     if isinstance(item, (Pot, Pan)):
+    #         return not self.occupied_by
+    #     if self.occupied_by:
+    #         return self.occupied_by.can_combine(item)
+    #     return False
 
     def progress(self):
         """Called by environment step function for time progression"""
-        if self.occupied_by and self.occupied_by.can_cook():
+        if (
+            self.occupied_by
+            and isinstance(self.occupied_by, CookingEquipment)
+            and self.occupied_by.can_progress()
+        ):
             self.occupied_by.progress()
diff --git a/overcooked_simulator/game_items.py b/overcooked_simulator/game_items.py
index dc2375a2cab8fa9f9957a62522458b03ddd96b84..1d5098de7b8923d316851859430221a53554abea 100644
--- a/overcooked_simulator/game_items.py
+++ b/overcooked_simulator/game_items.py
@@ -1,46 +1,69 @@
+from __future__ import annotations
+
+
 class Item:
     """Base class for game items which can be held by a player."""
 
+    def __init__(self, name: str = None, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.name = self.__class__.__name__ if name is None else name
+
     def can_combine(self, other):
         return False
 
-    def combine(self, other):
+    def combine(self, other) -> Item | None:
         pass
 
     def __repr__(self):
-        return self.__class__.__name__
+        return f"{self.name}({self.extra_repr})"
+
+    @property
+    def extra_repr(self):
+        return ""
 
 
 class Plate(Item):
     def __init__(self, holds: Item = None):
+        super().__init__()
         self.clean = True
         self.holds = holds
 
-        super().__init__()
-
     def can_combine(self, other: Item) -> bool:
         if self.holds is None:
-            if isinstance(other, (Pot, Pan)):
-                return other.finished
+            if isinstance(other, CookingEquipment):
+                return other.can_release_content()
             return not isinstance(other, Plate)
         return False
 
     def combine(self, other):
+        if isinstance(other, CookingEquipment):
+            self.holds = other.release()
+            return other
         self.holds = other
 
-    def __repr__(self):
-        return f"Plate({self.holds})"
+    @property
+    def extra_repr(self):
+        return self.holds
 
 
-class ProgressibleItem(Item):
+class ProgressibleItem:
     """Class for items which need to be processed (cut, cooked, ...)"""
 
-    def __init__(self, finished: bool = False, steps_needed: int = 1500):
+    def __init__(
+        self,
+        finished: bool = False,
+        steps_needed: int = 1500,
+        finished_name: str = None,
+        *args,
+        **kwargs,
+    ):
+        super().__init__(*args, **kwargs)
         self.progressed_steps = steps_needed if finished else 0
         self.steps_needed = steps_needed
         self.finished = finished
-        self.finished_name = "Cutted"
-        super().__init__()
+        self.finished_name = (
+            f"Cutted{self.name}" if finished_name is None else finished_name
+        )
 
     def progress(self):
         """Progresses the item process as long as it is not finished."""
@@ -50,14 +73,21 @@ class ProgressibleItem(Item):
         if not self.finished:
             self.progressed_steps += 1
 
+    def can_progress(self) -> bool:
+        return True
+
     def finished_call(self):
-        pass
+        self.name = self.finished_name
+
+    def reset(self):
+        self.finished = False
+        self.progressed_steps = 0
 
     def __repr__(self):
         if self.finished:
-            return f"{self.finished_name}{self.__class__.__name__}()"
+            return f"{self.name}({self.extra_repr})"
         else:
-            return f"{self.__class__.__name__}(progress={int(self.progressed_steps / self.steps_needed * 100)}%)"
+            return f"{self.name}(progress={int(self.progressed_steps / self.steps_needed * 100)}%,{self.extra_repr})"
 
 
 class CuttableItem(ProgressibleItem):
@@ -66,7 +96,7 @@ class CuttableItem(ProgressibleItem):
     pass
 
 
-class Tomato(CuttableItem):
+class Tomato(CuttableItem, Item):
     """Item class representing a tomato. Can be cut on the cutting board"""
 
     def can_combine(self, other):
@@ -76,42 +106,82 @@ class Tomato(CuttableItem):
         super().__init__(steps_needed=1500)
 
 
-class Pot(ProgressibleItem):
-    def __init__(self, holds: Item = None):
-        self.holds = [] if holds is None else holds
-        super().__init__(steps_needed=1500)
-        self.finished_name = "Cooked"
+class CookingEquipment(Item):
+    def __init__(self, content: Meal = None, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.content = content
 
     def can_combine(self, other):
-        # TODO based on recipes
+        if self.content is None:
+            # TODO check other is start of a meal, create meal
+            return True
+        return self.content.can_combine(other)
+
+    def combine(self, other):
+        if not self.content:
+            # find starting meal for other
+            self.content = Soup()
+        self.content.combine(other)
+
+    def can_progress(self, counter_type="Stove") -> bool:
         return (
-            isinstance(other, Tomato)
-            # and other.finished
-            and len(self.holds) < 3
-            and all([isinstance(h, Tomato) for h in self.holds])
+            self.content
+            and isinstance(self.content, ProgressibleItem)
+            and self.content.can_progress()
         )
 
-    def finished_call(self):
-        self.holds = [TomatoSoup()]
+    def progress(self):
+        self.content.progress()
 
-    def combine(self, other):
-        self.holds.append(other)
+    def can_release_content(self) -> bool:
+        return (
+            self.content
+            and isinstance(self.content, ProgressibleItem)
+            and self.content.finished
+        )
 
-    def can_cook(self) -> bool:
-        return self.holds and len(self.holds) == 3
+    def release(self):
+        content = self.content
+        self.content = None
+        return content
 
-    def __repr__(self):
-        if self.finished:
-            return f"{self.finished_name}{self.__class__.__name__}({self.holds})"
-        else:
-            return f"{self.__class__.__name__}({self.holds},progress={int(self.progressed_steps / self.steps_needed * 100)}%)"
+    @property
+    def extra_repr(self):
+        return self.content
+
+
+class Pot(CookingEquipment):
+    def __init__(self, holds: Meal = None):
+        super().__init__()
+
+
+class Meal(Item):
+    def __init__(self, parts=None, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.parts = [] if parts is None else parts
+        # self.rules ...
+
+    def can_combine(self, other) -> bool:
+        return (
+            isinstance(other, Tomato)
+            and all([isinstance(o, other.__class__) for o in self.parts])
+            and len(self.parts) < 3
+        )  # rules
+
+    def combine(self, other):
+        self.parts.append(other)
+
+    @property
+    def extra_repr(self):
+        return self.parts
 
 
-class TomatoSoup(Item):
-    ...
+class Soup(ProgressibleItem, Meal):
+    def can_progress(self) -> bool:
+        return len(self.parts) == 3
 
 
-class Pan(ProgressibleItem):
+class Pan(CookingEquipment):
     def __init__(self):
         super().__init__(steps_needed=1500)
 
diff --git a/overcooked_simulator/pygame_gui/pygame_gui.py b/overcooked_simulator/pygame_gui/pygame_gui.py
index b1f9d75b19da4d6edb4af2c80519c250ffc9a98d..df41500fcfdbe366ff8c5e48b0dcc373b85c0318 100644
--- a/overcooked_simulator/pygame_gui/pygame_gui.py
+++ b/overcooked_simulator/pygame_gui/pygame_gui.py
@@ -18,7 +18,7 @@ from overcooked_simulator.game_items import (
     Plate,
     Item,
     Pot,
-    TomatoSoup,
+    Soup,
 )
 from overcooked_simulator.game_items import Tomato
 from overcooked_simulator.overcooked_environment import Action
@@ -231,8 +231,11 @@ class PyGameGUI:
         if isinstance(item, Pot):
             pot_size = 15
             pygame.draw.circle(self.screen, GREY, pos, pot_size)
+            if item.content:
+                self.draw_item(pos, item.content)
+        if isinstance(item, Soup):
             if not item.finished:
-                match len(item.holds):
+                match len(item.parts):
                     case 1:
                         pygame.draw.circle(self.screen, RED, pos, 4)
                     case 2:
@@ -240,17 +243,14 @@ class PyGameGUI:
                     case 3:
                         pygame.draw.circle(self.screen, RED, pos, 12)
             else:
-                print(item.holds)
-                self.draw_item(pos, item.holds[0])
-        if isinstance(item, TomatoSoup):
-            """https://www.readersdigest.ca/wp-content/uploads/2020/11/The-Best-Ever-Tomato-Soup_EXPS_THSO18_222724_D03_06_5b-4.jpg"""
-            image = pygame.image.load(
-                self.images_path / "tomato_soup.png"
-            ).convert_alpha()
-            image = pygame.transform.scale(image, (24, 24))
-            rect = image.get_rect()
-            rect.center = pos
-            self.screen.blit(image, rect)
+                """https://www.readersdigest.ca/wp-content/uploads/2020/11/The-Best-Ever-Tomato-Soup_EXPS_THSO18_222724_D03_06_5b-4.jpg"""
+                image = pygame.image.load(
+                    self.images_path / "tomato_soup.png"
+                ).convert_alpha()
+                image = pygame.transform.scale(image, (24, 24))
+                rect = image.get_rect()
+                rect.center = pos
+                self.screen.blit(image, rect)
 
         if isinstance(item, ProgressibleItem) and not item.finished:
             self.draw_progress_bar(pos, item.progressed_steps, item.steps_needed)