diff --git a/README.md b/README.md
index a70fae97dd3f3f0d4424d1ecfc2576bda5e0745b..7222709f10f94cc0b0ab6343079ab35dfd8f970e 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,21 @@
 # Overcooked Simulator
 
-[API Docs](https://scs.pages.ub.uni-bielefeld.de/cocosy/overcooked-simulator)
+[Documentation](https://scs.pages.ub.uni-bielefeld.de/cocosy/overcooked-simulator)
 
 The real-time overcooked simulation for a cognitive cooperative system.
 
 **The name ist still work in progress and we will probably change it.**
 
 ## Installation
-You have two options to install the environment. Either clone it and install it locally or install it in your site-packages.
+
+You have two options to install the environment. Either clone it and install it locally or install it in your
+site-packages.
 You need a Python 3.10 or higher environment. Either conda or PyEnv.
 
 ### Local Editable Installation
-In your `repo`, `PyCharmProjects` or similiar directory with the correct environment active:
+
+In your `repo`, `PyCharmProjects` or similar directory with the correct environment active:
+
 ```bash
 git clone https://gitlab.ub.uni-bielefeld.de/scs/cocosy/overcooked-simulator.git
 cd overcooked_simulator
@@ -25,29 +29,41 @@ python3 overcooked_simulator/main.py
 ```
 
 ### Library Installation
+
 The correct environment needs to be active:
+
 ```bash
 pip install overcooked-environment@git+https://gitlab.ub.uni-bielefeld.de/scs/cocosy/overcooked-simulator@main
 ```
 
 #### Run
-You can now use the environment and/or simulator in your python code. Just by importing it `import overcooked_environment`
+
+You can now use the environment and/or simulator in your python code. Just by importing
+it `import overcooked_environment`
 
 ## Configuration
+
 The environment configuration is currently done with 3 config files + GUI configuration.
 
 ### Item Config
-The item config defines which ingredients, cooking equipment and meals can exist and how meals and processed ingredients can be cooked/created. 
+
+The item config defines which ingredients, cooking equipment and meals can exist and how meals and processed ingredients
+can be cooked/created.
 
 ### Layout Config
-You can define the layout of the kitchen via a layout file. The position of counters are based on a grid system, even when the playere do not move grid steps but continous steps. Each character defines a different type of counter.
+
+You can define the layout of the kitchen via a layout file. The position of counters are based on a grid system, even
+when the players do not move grid steps but continuous steps. Each character defines a different type of counter.
 
 ### Environment Config
-The environment config defines how a level/environment is defined. Here, the available plates, meals, order and player configraation is done. 
+
+The environment config defines how a level/environment is defined. Here, the available plates, meals, order and player
+configuration is done.
 
 ### PyGame Visualization Config
-Here the visualisation for all objects is defined. Reference the images or define a list of base shapes that represent the counters, ingrredients, meals and players.
 
+Here the visualisation for all objects is defined. Reference the images or define a list of base shapes that represent
+the counters, ingredients, meals and players.
 
 ## Troubleshooting
 
diff --git a/overcooked_simulator/__init__.py b/overcooked_simulator/__init__.py
index 7d983330e5810899308a2e0b5b06990a754af5f6..c5d7d61bd0acf0412b5affe0069c97bbab98bf2e 100644
--- a/overcooked_simulator/__init__.py
+++ b/overcooked_simulator/__init__.py
@@ -1,19 +1,62 @@
 """
 
-This is the documentation of Overcooked Simulator.
-It contains of 
+This is the documentation of the Overcooked Simulator.
 
 # About the package
 
+The package contains of an environment for cooperation between players/agents.
+A PyGameGUI visualizes the game to human or visual agents in 2D.
+A 3D web-enabled version (for example for online studies) can be found in the future [here](https://gitlab.ub.uni-bielefeld.de/scs/cocosy/godot-overcooked-3d-visualization)
+
 # Background / Literature
+The overcooked/cooking domain is a well established cooperation domain/task.
+There exists environments designed for reinforcement learning agents as well as the game and adaptations of the game for human players in a more "real-time" environment.
+They all mostly differ in the visual and graphics dimension. 2D versions like overcooked-ai, ... are most known in the community.
+But more visual appealing 3D versions for cooperation with humans are getting developed more frequently (cite,...).
+Besides, the general adaptations of the original overcooked game.
+
 
 # Usage / Examples
+Our overcooked simulator is designed for real time interaction but also with reinforcement learning in mind (gym environment).
+It focuses on configurability, extensibility and appealing visualization options.
+
+## Human Player
+Start `main.py` in your python/conda environment:
+```bash
+python overcooked_simulator/main.py
+```
+
+## Connect with player and receive game state
+...
+
+## Direct integration into your code.
+Initialize an environment....
+
 
 # Citation
 
+# Structure of the Documentation
+The API documentation follows the file and content structure in the repo.
+On the left you can find the navigation panel that brings you to the implementation of
+- the **counters**, including the kitchen utility objects like dispenser, stove, sink, etc.,
+- the **game items**, the holdable ingredients, cooking equipment, composed ingredients, and meals,
+- in **main**, you find an example how to start a simulation,
+- the **orders**, how to sample incoming orders and their attributes,
+- the **environment**, handles the incoming actions and provides the state,
+- the **player**,
+- a **simulation runner**, that calls the step function of the environment for a real-time interaction,
+- **util**ity code.
+
 
 """
 import os
 from pathlib import Path
 
 ROOT_DIR = Path(os.path.dirname(os.path.abspath(__file__)))  # This is your Project Root
+"""A path variable to get access to the layouts coming with the package. For example,
+```python 
+from overcooked_simulator import ROOT_DIR
+
+environment_config_path = ROOT_DIR / "game_content" / "environment_config.yaml"
+```
+"""
diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py
index 41bd67eeb5c10e23ea15538dd90fe9ca1afce515..2cbbeb4d048a7d113c784ea1792103cdda1bdba1 100644
--- a/overcooked_simulator/counters.py
+++ b/overcooked_simulator/counters.py
@@ -1,3 +1,22 @@
+"""
+All counters are derived from the `Counter` class.
+Counters implement the `Counter.pick_up` method, which defines what should happen when the agent wants to pick something up from the counter.
+On the other side, the `Counter.drop_off` method receives the item what should be put on the counter. Before that the `Counter.can_drop_off` method checked if the item can be put on the counter.
+The progress on Counters or on objects on the counters are handled via the Counters. They have the task to delegate the progress call via the `Counter.progress` method.
+On which type of counter the progress method is called is currently defined in the environment class.
+
+Inside the item_info.yaml, equipment needs to be defined. It includes counters that are part of the interaction/requirements for the interaction.
+```yaml
+CuttingBoard:
+  type: Equipment
+
+Sink:
+  type: Equipment
+
+Stove:
+  type: Equipment
+```
+"""
 from __future__ import annotations
 
 import logging
@@ -96,13 +115,35 @@ class Counter:
 
 
 class CuttingBoard(Counter):
+    """Cutting ingredients on. The requirement in a new object could look like
+
+    ```yaml
+    ChoppedTomato:
+      type: Ingredient
+      needs: [ Tomato ]
+      seconds: 4.0
+      equipment: CuttingBoard
+    ```
+
+
+    """
+
     def __init__(self, pos: np.ndarray, transitions: dict):
         self.progressing = False
         self.transitions = transitions
         super().__init__(pos)
 
     def progress(self, passed_time: timedelta, now: datetime):
-        """Called by environment step function for time progression"""
+        """Called by environment step function for time progression.
+
+        Args:
+            passed_time: the time passed since the last progress call
+            now: the current env time. Not the same as `datetime.now`
+
+        Checks if the item on the board is in the allowed transitions via a Cutting board. Pass the progress call to
+        the item on the board. If the progress on the item reaches 100% it changes the name of the item based on the
+        "goal" name in the transition definition.
+        """
         if (
             self.occupied
             and self.progressing
@@ -139,6 +180,14 @@ class CuttingBoard(Counter):
 
 
 class ServingWindow(Counter):
+    """The orders and scores are updated based on completed and dropped off meals. The plate dispenser is pinged for the info about a plate outside of the kitchen.
+
+    All items in the `item_info.yml` with the type meal are considered to be servable, if they are ordered. Not
+    ordered meals can also be served, if a `serving_not_ordered_meals` function is set in the `environment_config.yml`.
+
+    The plate dispenser will put after some time a dirty plate on itself after a meal was served.
+    """
+
     def __init__(
         self,
         pos,
@@ -175,6 +224,24 @@ class ServingWindow(Counter):
 
 
 class Dispenser(Counter):
+    """The class for all dispenser except plate dispenser. Here ingredients can be graped from the player/agent.
+
+    At the moment all ingredients have an unlimited stock.
+
+    The character for each dispenser in the `layout` file is currently hard coded in the environment class:
+    ```yaml
+    T: Tomato
+    L: Lettuce
+    N: Onion  # N for oNioN
+    B: Bun
+    M: Meat
+    ```
+    The plan is to put the info also in the config.
+
+    In the implementation, an instance of the item to dispense is always on top of the dispenser.
+    Which also is easier for the visualization of the dispenser.
+    """
+
     def __init__(self, pos, dispensing: ItemInfo):
         self.dispensing = dispensing
         super().__init__(
@@ -206,6 +273,21 @@ class Dispenser(Counter):
 
 
 class PlateDispenser(Counter):
+    """At the moment, one and only one plate dispenser must exist in an environment, because only at one place the dirty
+    plates should arrive.
+
+    How many plates should exist at the start of the level on the plate dispenser is defined in the `environment_config.yml`:
+    ```yaml
+    plates:
+      clean_plates: 1
+      dirty_plates: 2
+      plate_delay: [ 5, 10 ]
+      # seconds until the dirty plate arrives.
+    ```
+
+    The character `P` in the `layout` file represents the PlateDispenser.
+    """
+
     def __init__(
         self, pos, dispensing, plate_config, plate_transitions, **kwargs
     ) -> None:
@@ -227,14 +309,8 @@ class PlateDispenser(Counter):
         return not self.occupied_by or self.occupied_by[-1].can_combine(item)
 
     def drop_off(self, item: Item) -> Item | None:
-        """Takes the thing dropped of by the player.
-
-        Args:
-            item: The item to be placed on the counter.
-
-        Returns: TODO Return information, whether the score is affected (Serving Window?)
-
-        """
+        """At the moment items can be put on the top of the plate dispenser or the top plate if it is clean and can
+        be put on a plate."""
         if not self.occupied_by:
             self.occupied_by.append(item)
         elif self.occupied_by[-1].can_combine(item):
@@ -301,7 +377,12 @@ class PlateDispenser(Counter):
         return Plate(**kwargs)
 
 
-class Trash(Counter):
+class Trashcan(Counter):
+    """Ingredients and content on a cooking equipment can be removed from the environment via the trash.
+
+    The character `X` in the `layout` file represents the Trashcan.
+    """
+
     def pick_up(self, on_hands: bool = True):
         pass
 
@@ -316,6 +397,16 @@ class Trash(Counter):
 
 
 class Stove(Counter):
+    """Cooking machine. Currently, the stove which can have a pot and pan on top. In the future one class for stove,
+    deep fryer, and oven.
+
+    The character depends on the cooking equipment on top of it:
+    ```yaml
+    U: Stove with a pot
+    Q: Stove with a pan
+    ```
+    """
+
     def can_drop_off(self, item: Item) -> bool:
         if self.occupied_by is None:
             return isinstance(item, CookingEquipment) and item.name in ["Pot", "Pan"]
@@ -333,11 +424,25 @@ class Stove(Counter):
 
 
 class Sink(Counter):
+    """The counter in which the dirty plates are in.
+
+    Needs a `SinkAddon`. The closest is calculated during initialisation, should not be seperated by each other (needs
+    to touch the sink).
+
+    The logic is similar to the CuttingBoard because there is no additional cooking equipment between the object to
+    progress and the counter. When the progress on the dirty plate is done, it is set to clean and is passed to the
+    `SinkAddon`.
+
+    The character `S` in the `layout` file represents the Sink.
+    """
+
     def __init__(self, pos, transitions, sink_addon=None):
         super().__init__(pos)
         self.progressing = False
         self.sink_addon: SinkAddon = sink_addon
+        """The connected sink addon which will receive the clean plates"""
         self.occupied_by = deque()
+        """The queue of dirty plates. Only the one on the top is progressed."""
         self.transitions = transitions
 
     @property
@@ -399,6 +504,13 @@ class Sink(Counter):
 
 
 class SinkAddon(Counter):
+    """The counter on which the clean plates appear after cleaning them in the `Sink`
+
+    It needs to be set close to/touching the `Sink`.
+
+    The character `+` in the `layout` file represents the SinkAddon.
+    """
+
     def __init__(self, pos, occupied_by=None):
         super().__init__(pos)
         self.occupied_by = deque([occupied_by]) if occupied_by else deque()
diff --git a/overcooked_simulator/game_content/environment_config.yaml b/overcooked_simulator/game_content/environment_config.yaml
index b6b7c579ec950edd189c41e2ec09a5cbda2a239f..1dbb4f5632d2c95d07cdba95970c3990fc768aec 100644
--- a/overcooked_simulator/game_content/environment_config.yaml
+++ b/overcooked_simulator/game_content/environment_config.yaml
@@ -2,7 +2,7 @@ plates:
   clean_plates: 1
   dirty_plates: 2
   plate_delay: [ 5, 10 ]
-  # seconds until the dirty plate arrives.
+  # range of seconds until the dirty plate arrives.
 
 game:
   time_limit_seconds: 180
@@ -17,8 +17,10 @@ meals:
     - Salad
 
 orders:
-  kwargs:
-    duration_sample:
+  order_gen_class: !!python/name:overcooked_simulator.order.RandomOrderGeneration ''
+  # the class to that receives the kwargs. Should be a child class of OrderGeneration in order.py
+  order_gen_kwargs:
+    order_duration_random_func:
       # how long should the orders be alive
       # 'random' library call with getattr, kwargs are passed to the function
       func: uniform
@@ -29,10 +31,7 @@ orders:
     # maximum number of active orders at the same time
     num_start_meals: 3
     # number of orders generated at the start of the environment
-    sample_on_dur: true
-    # if true, the next order is generated based on the sample_on_dur_func method in seconds
-    # if sample_on_serving is also true, the value is sampled after a meal was served, otherwise it is sampled directly after an order generation.
-    sample_on_dur_func:
+    sample_on_dur_random_func:
       # 'random' library call with getattr, kwargs are passed to the function
       func: uniform
       kwargs:
@@ -54,8 +53,6 @@ orders:
       default: -5
   serving_not_ordered_meals: null
   # a func that calcs a store for not ordered but served meals. Input: meal
-  order_gen_class: !!python/name:overcooked_simulator.order.RandomOrderGeneration ''
-  # the class to that receives the kwargs. Should be a child class of OrderGeneration in order.py
 
 player_config:
   radius: 0.4
diff --git a/overcooked_simulator/game_items.py b/overcooked_simulator/game_items.py
index 4592e68bbe4057719b3618fbf7b34513fb4d232b..1699481abb4a8611798b080ce2a173b940bec5b5 100644
--- a/overcooked_simulator/game_items.py
+++ b/overcooked_simulator/game_items.py
@@ -1,3 +1,14 @@
+""""
+The game items that a player can hold.
+
+They have methods that
+- check if items can be combined (`Item.can_combine`): cooking equipment and ingredients, and so on
+- combine the items after a successful check (`Item.combine`),
+- and a method to call the progress on the items (`Item.progress`)
+
+All game items need to be specified in the `item_info.yml`.
+"""
+
 from __future__ import annotations
 
 import collections
@@ -18,42 +29,52 @@ class ItemType(Enum):
 
 @dataclasses.dataclass
 class ItemInfo:
+    """Wrapper for the info in the `item_info.yml`.
+
+    Example:
+        A simple example for the tomato soup with 6 game items.
+        ```yaml
+        CuttingBoard:
+          type: Equipment
+
+        Stove:
+          type: Equipment
+
+        Pot:
+          type: Equipment
+          equipment: Stove
+
+        Tomato:
+          type: Ingredient
+
+        ChoppedTomato:
+          type: Ingredient
+          needs: [ Tomato ]
+          seconds: 4.0
+          equipment: CuttingBoard
+
+        TomatoSoup:
+          type: Meal
+          needs: [ ChoppedTomato, ChoppedTomato, ChoppedTomato ]
+          seconds: 6.0
+          equipment: Pot
+        ```
+    """
+
     type: ItemType = dataclasses.field(compare=False)
+    """Type of the item. Either `Ingredient`, `Meal` or `Equipment`."""
     name: str = dataclasses.field(compare=True)
+    """The name of the item, is set automatically by the "group" name of the item."""
     seconds: float = dataclasses.field(compare=False, default=0)
+    """If a progress is needed this defines how long it takes to complete the process in seconds."""
     needs: list[ItemInfo] = dataclasses.field(compare=False, default_factory=list)
+    """The ingredients/items which are needed to create the item/start the progress."""
     equipment: ItemInfo | None = dataclasses.field(compare=False, default=None)
-
-    _start_meals: list[ItemInfo] = dataclasses.field(
-        compare=False, default_factory=list
-    )
+    """On which the item can be created. `null`, `~` (None) converts to Plate."""
 
     def __post_init__(self):
         self.type = ItemType(self.type)
 
-    def add_start_meal_to_equipment(self, start_item: ItemInfo):
-        self._start_meals.append(start_item)
-
-    def sort_start_meals(self):
-        self._start_meals.sort(key=lambda item_info: len(item_info.needs))
-
-    # def can_start_meal(self, items: list[Item]):
-    #     return items and self._return_start_meal(items) is not None
-
-    # def start_meal(self, items: list[Item]) -> Item:
-    #     return self._return_start_meal(items).create_item(parts=items)
-
-    def _return_start_meal(self, items: list[Item]) -> ItemInfo | None:
-        for meal in self._start_meals:
-            satisfied = [False for _ in range(len(items))]
-            for i, p in enumerate(items):
-                for _, n in enumerate(meal.needs):
-                    if not satisfied[i] and p.name == n:
-                        satisfied[i] = True
-                        break
-            if all(satisfied):
-                return meal
-
 
 class Item:
     """Base class for game items which can be held by a player."""
@@ -102,13 +123,21 @@ class Item:
 
 
 class CookingEquipment(Item):
+    """Pot, Pan, ... that can hold items. It holds the progress of the content (e.g., the soup) in itself (
+    progress_percentage) and not in the items in the content list."""
+
     def __init__(self, transitions: dict, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.transitions = transitions
         self.active_transition: Optional[dict] = None
+        """The info how and when to convert the content_list to a new item."""
 
         self.content_ready: Item | None = None
+        """Helper attribute that can have a ready meal which is also represented via it ingredients in the 
+        content_list. But soups or other processed meals are not covered here. For a Burger or Salad, this attribute 
+        is set."""
         self.content_list: list[Item] = []
+        """The items that the equipment holds."""
 
         log.debug(f"Initialize {self.name}: {self.transitions}")
 
@@ -174,12 +203,6 @@ class CookingEquipment(Item):
 
         # todo set active transition for fire/burnt?
 
-    # def can_release_content(self) -> bool:
-    #     return (
-    #         self.content
-    #         and isinstance(self.content, ProgressibleItem)
-    #         and self.content.finished
-    #     )
     def reset_content(self):
         self.content_list = []
         self.content_ready = None
@@ -206,9 +229,12 @@ class CookingEquipment(Item):
 
 
 class Plate(CookingEquipment):
+    """The plate can have to states: clean and dirty. In the clean state it can hold content/other items."""
+
     def __init__(self, transitions, clean, *args, **kwargs):
         self.clean = clean
         self.meals = set(transitions.keys())
+        """All meals can be hold by a clean plate"""
         super().__init__(
             name=self.create_name(),
             transitions={
@@ -236,6 +262,8 @@ class Plate(CookingEquipment):
                 and not self.content_list
                 and self.clean
             ):
+                # additional check for meals in the content list of another equipment,
+                # e.g., Soups which is not covered by the normal transition checks.
                 return other.content_list[0].name in self.meals
             return False
         elif self.clean:
diff --git a/overcooked_simulator/gui_2d_vis/visualization.yaml b/overcooked_simulator/gui_2d_vis/visualization.yaml
index 8d4d52deb8f111a56dda65c44501aca3414fe979..a4ba4f7ec354aa825fe8eb09b44ee19995015eaa 100644
--- a/overcooked_simulator/gui_2d_vis/visualization.yaml
+++ b/overcooked_simulator/gui_2d_vis/visualization.yaml
@@ -39,7 +39,7 @@ PlateDispenser:
       width: 0.95
       color: cadetblue1
 
-Trash:
+Trashcan:
   parts:
     - type: image
       path: images/trash3.png
diff --git a/overcooked_simulator/order.py b/overcooked_simulator/order.py
index 5d7abbf72cdbbd1a6d2fe110934b8561d342ca44..54c7ef1e7a8b9948df220fe28fa17376c992e7cf 100644
--- a/overcooked_simulator/order.py
+++ b/overcooked_simulator/order.py
@@ -1,10 +1,13 @@
+""""""
+from __future__ import annotations
+
 import dataclasses
 import logging
 import random
 from abc import abstractmethod
 from collections import deque
 from datetime import datetime, timedelta
-from typing import Callable, Tuple, Any, Deque
+from typing import Callable, Tuple, Any, Deque, Protocol, TypedDict
 
 from overcooked_simulator.game_items import Item, Plate, ItemInfo
 
@@ -13,19 +16,29 @@ log = logging.getLogger(__name__)
 
 @dataclasses.dataclass
 class Order:
+    """Datawrapper for Orders"""
+
     meal: ItemInfo
+    """The meal to serve and that should be cooked."""
     start_time: datetime
+    """The start time relative to the env_time. On which the order is returned from the get_orders func."""
     max_duration: timedelta
-    score_calc: Callable[[timedelta, ...], float]
+    """The duration after which the order expires."""
+    score_calc: ScoreCalcFuncType
+    """The function that calculates the score of the served meal/fulfilled order."""
     timed_penalties: list[
         Tuple[timedelta, float] | Tuple[timedelta, float, int, timedelta]
     ]
+    """list of timed penalties when the order is not fulfilled."""
     expired_penalty: float
+    """the penalty to the score if the order expires"""
 
     finished_info: dict[str, Any] = dataclasses.field(default_factory=dict)
+    """Is set after the order is completed."""
     _timed_penalties: list[Tuple[datetime, float]] = dataclasses.field(
         default_factory=list
     )
+    """Converted penalties the env is working with from the `timed_penalties`"""
 
     def order_time(self, env_time: datetime) -> timedelta:
         return self.start_time - env_time
@@ -45,11 +58,24 @@ class Order:
 
 
 class OrderGeneration:
+    """Base class for generating orders.
+
+    You can set your child class via the `environment_config.yml`.
+    Example:
+        ```yaml
+        orders:
+          order_gen_class: !!python/name:overcooked_simulator.order.RandomOrderGeneration ''
+          kwargs:
+            ...
+        ```
+    """
+
     def __init__(self, available_meals: dict[str, ItemInfo], **kwargs):
         self.available_meals: list[ItemInfo] = list(available_meals.values())
 
     @abstractmethod
     def init_orders(self, now) -> list[Order]:
+        """Get the orders the environment starts with."""
         ...
 
     @abstractmethod
@@ -60,30 +86,141 @@ class OrderGeneration:
         new_finished_orders: list[Order],
         expired_orders: list[Order],
     ) -> list[Order]:
+        """Orders for each progress call. Should often be the empty list."""
+        ...
+
+
+class ScoreCalcFuncType(Protocol):
+    """Type with kwargs of the expected `Order.score_calc` function and returned function for the
+    `RandomOrderKwarg.score_calc_gen_func`."""
+
+    def __call__(self, relative_order_time: timedelta, order: Order) -> float:
+        ...
+
+
+class ScoreCalcGenFuncType(Protocol):
+    """Type with kwargs of the expected function for the `RandomOrderKwarg.score_calc_gen_func`."""
+
+    def __call__(
+        self,
+        meal: ItemInfo,
+        duration: timedelta,
+        now: datetime,
+        kwargs: dict,
+        **other_kwargs,
+    ) -> ScoreCalcFuncType:
+        ...
+
+
+class ExpiredPenaltyFuncType(Protocol):
+    """Type with kwargs of the expected function for the `RandomOrderKwarg.expired_penalty_func`.
+
+    An example is the `zero` function."""
+
+    def __call__(self, item: ItemInfo, **kwargs) -> float:
         ...
 
 
 def zero(item: ItemInfo, **kwargs) -> float:
+    """Example and default for the `RandomOrderKwarg.expired_penalty_func` function.
+
+    Just no penalty for expired orders."""
     return 0.0
 
 
+class RandomFuncConfig(TypedDict):
+    """Types of the dict for sampling with different random functions from the `random` library.
+
+    Example:
+        Sampling uniformly between `10` and `20`.
+        ```yaml
+        func: uniform
+        kwargs:
+          a: 10
+          b: 20
+        ```
+        Or in pyton:
+        ```python
+        random_func: RandomFuncConfig = {'func': 'uniform', 'kwargs': {'a': 10, 'b': 20}}
+        ```
+    """
+
+    func: Callable
+    """the name of a functions in the `random` library."""
+    kwargs: dict
+    """the kwargs of the functions in the `random` library."""
+
+
 @dataclasses.dataclass
 class RandomOrderKwarg:
     num_start_meals: int
+    """Number of meals sampled at the start."""
     sample_on_serving: bool
-    sample_on_dur: bool
-    sample_on_dur_func: dict
+    """Only sample the delay for the next order after a meal was served."""
+    sample_on_dur_random_func: RandomFuncConfig
+    """How to sample the delay of the next incoming order. Either after a new meal was served or the last order was 
+    generated (based on the `sample_on_serving` attribute)."""
     max_orders: int
-    duration_sample: dict
-    score_calc_gen_func: Callable[
-        [ItemInfo, timedelta, datetime, Any], Callable[[timedelta, Order], float]
-    ]
+    """How many orders can maximally be active at the same time."""
+    order_duration_random_func: RandomFuncConfig
+    """How long the order is alive until it expires. If `sample_on_serving` is `true` all orders have no expire time."""
+    score_calc_gen_func: ScoreCalcGenFuncType
+    """The function that generates the `Order.score_calc` for each order."""
     score_calc_gen_kwargs: dict
+    """The additional static kwargs for `score_calc_gen_func`."""
     expired_penalty_func: Callable[[ItemInfo], float] = zero
+    """The function that calculates the penalty for a meal that was not served."""
     expired_penalty_kwargs: dict = dataclasses.field(default_factory=dict)
+    """The additional static kwargs for the `expired_penalty_func`."""
 
 
 class RandomOrderGeneration(OrderGeneration):
+    """A simple order generation based on random sampling with two options.
+
+    Either sample the delay when a new order should come in after the last order comes in or after a meals was served
+    (and an order got removed).
+
+    To configure it align your kwargs with the `RandomOrderKwarg` class.
+
+    You can set this order generation in your `environment_config.yml` with
+    ```yaml
+    orders:
+      order_gen_class: !!python/name:overcooked_simulator.order.RandomOrderGeneration ''
+        kwargs:
+            order_duration_random_func:
+              # how long should the orders be alive
+              # 'random' library call with getattr, kwargs are passed to the function
+              func: uniform
+              kwargs:
+                a: 40
+                b: 60
+            max_orders: 6
+            # maximum number of active orders at the same time
+            num_start_meals: 3
+            # number of orders generated at the start of the environment
+            sample_on_dur_random_func:
+              # 'random' library call with getattr, kwargs are passed to the function
+              func: uniform
+              kwargs:
+                a: 10
+                b: 20
+            sample_on_serving: false
+            # The sample time for a new incoming order is only generated after a meal was served.
+            score_calc_gen_func: !!python/name:overcooked_simulator.order.simple_score_calc_gen_func ''
+            score_calc_gen_kwargs:
+              # the kwargs for the score_calc_gen_func
+              other: 0
+              scores:
+                Burger: 15
+                OnionSoup: 10
+                Salad: 5
+                TomatoSoup: 10
+            expired_penalty_func: !!python/name:overcooked_simulator.order.simple_expired_penalty ''
+            expired_penalty_kwargs:
+              default: -5
+    ```
+    """
+
     def __init__(self, available_meals: dict[str, ItemInfo], **kwargs):
         super().__init__(available_meals, **kwargs)
         self.kwargs: RandomOrderKwarg = RandomOrderKwarg(**kwargs["kwargs"])
@@ -94,7 +231,7 @@ class RandomOrderGeneration(OrderGeneration):
 
     def init_orders(self, now) -> list[Order]:
         self.number_cur_orders = self.kwargs.num_start_meals
-        if self.kwargs.sample_on_dur:
+        if not self.kwargs.sample_on_serving:
             self.create_random_next_time_delta(now)
         return self.create_orders_for_meals(
             random.choices(self.available_meals, k=self.kwargs.num_start_meals),
@@ -127,7 +264,7 @@ class RandomOrderGeneration(OrderGeneration):
             if self.number_cur_orders >= self.kwargs.max_orders:
                 self.needed_orders += 1
             else:
-                if self.kwargs.sample_on_dur:
+                if not self.kwargs.sample_on_serving:
                     self.create_random_next_time_delta(now)
                 else:
                     self.next_order_time = datetime.max
@@ -147,9 +284,9 @@ class RandomOrderGeneration(OrderGeneration):
                 duration = datetime.max - now
             else:
                 duration = timedelta(
-                    seconds=getattr(random, self.kwargs.duration_sample["func"])(
-                        **self.kwargs.duration_sample["kwargs"]
-                    )
+                    seconds=getattr(
+                        random, self.kwargs.order_duration_random_func["func"]
+                    )(**self.kwargs.order_duration_random_func["kwargs"])
                 )
             log.info(f"Create order for meal {meal} with duration {duration}")
             orders.append(
@@ -174,8 +311,8 @@ class RandomOrderGeneration(OrderGeneration):
 
     def create_random_next_time_delta(self, now: datetime):
         self.next_order_time = now + timedelta(
-            seconds=getattr(random, self.kwargs.sample_on_dur_func["func"])(
-                **self.kwargs.sample_on_dur_func["kwargs"]
+            seconds=getattr(random, self.kwargs.sample_on_dur_random_func["func"])(
+                **self.kwargs.sample_on_dur_random_func["kwargs"]
             )
         )
         log.info(f"Next order in {self.next_order_time}")
@@ -184,6 +321,21 @@ class RandomOrderGeneration(OrderGeneration):
 def simple_score_calc_gen_func(
     meal: Item, duration: timedelta, now: datetime, kwargs: dict, **other_kwargs
 ) -> Callable:
+    """An example for the `RandomOrderKwarg.score_calc_gen_func` that selects the score for an order based on its meal from a list.
+
+    Example:
+        ```yaml
+        score_calc_gen_func: !!python/name:overcooked_simulator.order.simple_score_calc_gen_func ''
+        score_calc_gen_kwargs:
+          # the kwargs for the score_calc_gen_func
+          other: 0
+          scores:
+            Burger: 15
+            OnionSoup: 10
+            Salad: 5
+            TomatoSoup: 10
+        ```
+    """
     scores = kwargs["scores"]
     other = kwargs["other"]
 
@@ -196,14 +348,27 @@ def simple_score_calc_gen_func(
 
 
 def simple_expired_penalty(item: ItemInfo, default: float, **kwargs) -> float:
+    """Example for the `RandomOrderKwarg.expired_penalty_func` function.
+
+    A static default.
+
+    Example:
+        ```yaml
+        expired_penalty_func: !!python/name:overcooked_simulator.order.simple_expired_penalty ''
+        expired_penalty_kwargs:
+          default: -5
+        ```
+    """
     return default
 
 
 class OrderAndScoreManager:
+    """The Order and Score Manager that is called from the serving window."""
+
     def __init__(self, order_config, available_meals: dict[str, ItemInfo]):
         self.score = 0
         self.order_gen: OrderGeneration = order_config["order_gen_class"](
-            available_meals=available_meals, kwargs=order_config["kwargs"]
+            available_meals=available_meals, kwargs=order_config["order_gen_kwargs"]
         )
         self.kwargs_for_func = order_config["kwargs"]
         self.serving_not_ordered_meals = order_config["serving_not_ordered_meals"]
@@ -240,7 +405,7 @@ class OrderAndScoreManager:
                                 log.info(
                                     f"Serving meal without order {meal.name} with score {score}"
                                 )
-                                self.score += score
+                                self.increment_score(score)
                                 self.served_meals.append((meal, env_time))
                             return accept
                         log.info(
@@ -252,7 +417,7 @@ class OrderAndScoreManager:
                         relative_order_time=env_time - order.start_time,
                         order=order,
                     )
-                    self.score += score
+                    self.increment_score(score)
                     order.finished_info = {
                         "end_time": env_time,
                         "score": score,
@@ -265,15 +430,17 @@ class OrderAndScoreManager:
         log.info(f"Do not serve item {item}")
         return False
 
-    def increment_score(self, score: int):
+    def increment_score(self, score: int | float):
         self.score += score
         log.debug(f"Score: {self.score}")
 
     def create_init_orders(self, env_time):
+        """Create the initial orders in an environment."""
         init_orders = self.order_gen.init_orders(env_time)
         self.open_orders.extend(init_orders)
 
     def progress(self, passed_time: timedelta, now: datetime):
+        """Check expired orders and check order generation."""
         new_orders = self.order_gen.get_orders(
             passed_time=passed_time,
             now=now,
@@ -287,7 +454,7 @@ class OrderAndScoreManager:
             remove_orders = []
             for index, order in enumerate(self.open_orders):
                 if now >= order.start_time + order.max_duration:
-                    self.score += order.expired_penalty
+                    self.increment_score(order.expired_penalty)
                     remove_orders.append(index)
                 remove_penalties = []
                 for i, (penalty_time, penalty) in enumerate(order.timed_penalties):
@@ -314,40 +481,3 @@ class OrderAndScoreManager:
     def setup_penalties(self, new_orders: list[Order], env_time: datetime):
         for order in new_orders:
             order.create_penalties(env_time)
-
-
-if __name__ == "__main__":
-    import yaml
-
-    order_config = yaml.safe_load(
-        """orders:
-  kwargs:
-    duration_sample:
-      func: uniform
-      kwargs:
-        a: 30
-        b: 50
-    max_orders: 5
-    num_start_meals: 3
-    sample_on_dur: false
-    sample_on_dur_func:
-      func: uniform
-      kwargs:
-        a: 30
-        b: 50
-    sample_on_serving: true
-    score_calc_gen_func: null
-    score_calc_gen_kwargs:
-      other: 0
-      scores:
-        Burger: 15
-        OnionSoup: 10
-        Salad: 5
-        TomatoSoup: 10
-    score_calc_gen_func: ~''
-  order_gen_class: ~
-  serving_not_ordered_meals: null"""
-    )
-    order_config["orders"]["order_gen_class"] = RandomOrderGeneration
-    order_config["orders"]["kwargs"]["score_calc_gen_func"] = simple_score_calc_gen_func
-    print(yaml.dump(order_config))
diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py
index 3eaf84e14abfee0b6bc2931b00c54a1b0a5c6be5..f4bd59de451d5f02b9d1f99ab24c13490f7b7b40 100644
--- a/overcooked_simulator/overcooked_environment.py
+++ b/overcooked_simulator/overcooked_environment.py
@@ -14,7 +14,7 @@ from scipy.spatial import distance_matrix
 from overcooked_simulator.counters import (
     Counter,
     CuttingBoard,
-    Trash,
+    Trashcan,
     Dispenser,
     ServingWindow,
     Stove,
@@ -110,7 +110,7 @@ class Environment:
                     and info.equipment.name == "CuttingBoard"
                 },
             ),
-            "X": Trash,
+            "X": Trashcan,
             "W": lambda pos: ServingWindow(
                 pos,
                 self.order_and_score,
@@ -210,11 +210,6 @@ class Environment:
         for item_name, item_info in item_lookup.items():
             if item_info.equipment:
                 item_info.equipment = item_lookup[item_info.equipment]
-                item_info.equipment.add_start_meal_to_equipment(item_info)
-        for item_name, item_info in item_lookup.items():
-            if item_info.type == ItemType.Equipment:
-                # first select meals with smaller needs / ingredients
-                item_info.sort_start_meals()
         return item_lookup
 
     def validate_item_info(self):