diff --git a/cooperative_cuisine/counters.py b/cooperative_cuisine/counters.py
index 01421b2137f238b8413eee3194a227c2c87e8576..cd84be94e982e3c6e49ecefd501dbe075be84237 100644
--- a/cooperative_cuisine/counters.py
+++ b/cooperative_cuisine/counters.py
@@ -684,10 +684,10 @@ class PlateDispenser(Counter):
 
     def progress(self, passed_time: timedelta, now: datetime):
         """Check if plates arrive from outside the kitchen and add a dirty plate accordingly"""
-        if self.next_plate_time < now:
+        if self.next_plate_time <= now:
             idx_delete = []
             for i, times in enumerate(self.out_of_kitchen_timer):
-                if times < now:
+                if times <= now:
                     self.hook(DIRTY_PLATE_ARRIVES, counter=self, times=times, now=now)
                     idx_delete.append(i)
                     log.debug("Add dirty plate")
diff --git a/cooperative_cuisine/effects.py b/cooperative_cuisine/effects.py
index 3688ce649ef10ddbddb1671709a75db41f5a1fe6..53989c0916dd9d8f2fe82b44ef2be4f971e1da29 100644
--- a/cooperative_cuisine/effects.py
+++ b/cooperative_cuisine/effects.py
@@ -163,9 +163,9 @@ class FireEffectManager(EffectManager):
                 self.active_effects.append((effect, target))
             # reset new effects
             self.new_effects = []
-        if self.next_finished_timer < now:
+        if self.next_finished_timer <= now:
             for effect, target in self.active_effects:
-                if self.effect_to_timer[effect.uuid] < now:
+                if self.effect_to_timer[effect.uuid] <= now:
                     if isinstance(target, Item):
                         target = find_item_on_counters(target.uuid, self.counters)
                     if target:
diff --git a/cooperative_cuisine/info_msg.py b/cooperative_cuisine/info_msg.py
index 3d6d95257a0e138282e32b8666a72627f12cb974..7899e9cee58554d40bda22669d467dba1df1deba 100644
--- a/cooperative_cuisine/info_msg.py
+++ b/cooperative_cuisine/info_msg.py
@@ -95,7 +95,7 @@ class InfoMsgManager(HookCallbackClass):
         for player_id, msgs in env.info_msgs_per_player.items():
             delete_msgs = []
             for idx, msg in enumerate(msgs):
-                if msg["end_time"] < env.env_time:
+                if msg["end_time"] <= env.env_time:
                     delete_msgs.append(idx)
             for idx in reversed(delete_msgs):
                 msgs.pop(idx)
diff --git a/cooperative_cuisine/pygame_2d_vis/drawing.py b/cooperative_cuisine/pygame_2d_vis/drawing.py
index f9a994625856c4ee3a2bee92e208c0df7b6a6d3c..0c67eaf1549e8e45510832cc5c9296591883715c 100644
--- a/cooperative_cuisine/pygame_2d_vis/drawing.py
+++ b/cooperative_cuisine/pygame_2d_vis/drawing.py
@@ -2,6 +2,7 @@ import argparse
 import colorsys
 import json
 import os
+import sys
 from datetime import datetime, timedelta
 from pathlib import Path
 
@@ -1002,7 +1003,21 @@ def generate_recipe_images(config: dict, folder_path: str | Path):
         pygame.image.save(screen, f"{folder_path}/{graph_dict['meal']}.png")
 
 
-if __name__ == "__main__":
+def main(args):
+    """
+
+    Runs the Cooperative Cuisine Image Generation process.
+
+    This method takes command line arguments to specify the state file, visualization configuration file, and output file for the generated image. It then reads the visualization configuration
+    * file and state file, and calls the 'save_screenshot' and 'generate_recipe_images' methods to generate the image.
+
+    Args:
+        -s, --state: A command line argument of type `argparse.FileType("r", encoding="UTF-8")`. Specifies the state file to use for image generation. If not provided, the default value is 'ROOT_DIR / "pygame_2d_vis" / "sample_state.json"'.
+
+        -v, --visualization_config: A command line argument of type `argparse.FileType("r", encoding="UTF-8")`. Specifies the visualization configuration file to use for image generation. If not provided, the default value is 'ROOT_DIR / "pygame_2d_vis" / "visualization.yaml"'.
+
+        -o, --output_file: A command line argument of type `str`. Specifies the output file path for the generated image. If not provided, the default value is 'ROOT_DIR / "generated" / "screenshot.jpg"'.
+    """
     parser = argparse.ArgumentParser(
         prog="Cooperative Cuisine Image Generation",
         description="Generate images for a state in json.",
@@ -1024,12 +1039,16 @@ if __name__ == "__main__":
         "-o",
         "--output_file",
         type=str,
-        default=ROOT_DIR / "pygame_2d_vis" / "generated" / "screenshot.jpg",
+        default=ROOT_DIR / "generated" / "screenshot.jpg",
     )
-    args = parser.parse_args()
+    args = parser.parse_args(args)
     with open(args.visualization_config, "r") as f:
         viz_config = yaml.safe_load(f)
     with open(args.state, "r") as f:
         state = json.load(f)
     save_screenshot(state, viz_config, args.output_file)
     generate_recipe_images(viz_config, args.output_file.parent)
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
diff --git a/cooperative_cuisine/scores.py b/cooperative_cuisine/scores.py
index 5ae2c6ce83146b3d190f67e3e8236e3637a1b244..948d28f6d1e3ceb4685f9a2b17432481aaba0745 100644
--- a/cooperative_cuisine/scores.py
+++ b/cooperative_cuisine/scores.py
@@ -94,13 +94,13 @@ class ScoreViaHooks(HookCallbackClass):
             **kwargs: Additional keyword arguments to be passed to the parent class.
         """
         super().__init__(name, env, **kwargs)
-        self.score_map = score_map
+        self.score_map: dict[str, float] = score_map
         """Mapping of hook references to scores."""
-        self.static_score = static_score
+        self.static_score: float = static_score
         """The static score to be added if no other conditions are met."""
-        self.kwarg_filter = kwarg_filter
+        self.kwarg_filter: dict[str, Any] = kwarg_filter
         """Filtering condition for keyword arguments."""
-        self.score_on_specific_kwarg = score_on_specific_kwarg
+        self.score_on_specific_kwarg: str = score_on_specific_kwarg
         """The specific keyword argument to score on."""
 
     def __call__(self, hook_ref: str, env: Environment, **kwargs):
@@ -114,7 +114,7 @@ class ScoreViaHooks(HookCallbackClass):
                 self.env.increment_score(self.static_score, info=hook_ref)
         elif self.score_map and hook_ref in self.score_map:
             if self.kwarg_filter:
-                if kwargs.items() <= self.kwarg_filter.items():
+                if self.kwarg_filter.items() <= kwargs.items():
                     self.env.increment_score(
                         self.score_map[hook_ref],
                         info=f"{hook_ref} - {self.kwarg_filter}",
diff --git a/tests/test_game_server.py b/tests/test_game_server.py
index f072fed2dd5413ad016e64406146262c93723e53..84271ad77196e85aef512ce9994e0d8926130a0e 100644
--- a/tests/test_game_server.py
+++ b/tests/test_game_server.py
@@ -282,3 +282,10 @@ def test_websocket_wrong_inputs(create_env_config):
         finally:
             task.cancel()
             loop.close()
+
+
+def test_root():
+    with TestClient(app) as client:
+        res = client.get("/")
+        assert res.status_code == status.HTTP_200_OK
+        assert res.json() == {"Cooperative": "Cuisine"}
diff --git a/tests/test_pygame.py b/tests/test_pygame.py
index c44569519c406ec433d6b1ea1395109b86ca50be..9df43e0813184f20a159001c91684f149bc17fbb 100644
--- a/tests/test_pygame.py
+++ b/tests/test_pygame.py
@@ -1,7 +1,10 @@
+import json
+import os
+
 import yaml
 
 from cooperative_cuisine import ROOT_DIR
-from cooperative_cuisine.pygame_2d_vis.drawing import calc_angle, Visualizer
+from cooperative_cuisine.pygame_2d_vis.drawing import calc_angle, Visualizer, main
 from cooperative_cuisine.pygame_2d_vis.game_colors import RGB, WHITE, colors
 
 
@@ -16,6 +19,11 @@ def test_calc_angle():
     assert calc_angle([1.0, 1.0], [1.0, -1.0]) == -90.0
 
 
+def test_drawing():
+    main([])
+    assert os.path.exists(os.path.join(ROOT_DIR, "generated", "screenshot.jpg"))
+
+
 def test_visualizer():
     with open(ROOT_DIR / "pygame_2d_vis" / "visualization.yaml", "r") as file:
         visualization_config = yaml.safe_load(file)
@@ -25,3 +33,8 @@ def test_visualizer():
     vis.create_player_colors(10)
     assert len(vis.player_colors) >= 10
     assert len(set(vis.player_colors)) >= 10
+
+    with open(ROOT_DIR / "pygame_2d_vis" / "sample_state.json", "r") as file:
+        state = json.load(file)
+    image = vis.get_state_image(40, state)
+    assert image.shape == (480, 360, 3)
diff --git a/tests/test_start.py b/tests/test_start.py
index fec31349ac50c39f3d02019c66f1a7f802389a33..744bf6869590ad55b70c7dfb3cf0f3dd6e86af83 100644
--- a/tests/test_start.py
+++ b/tests/test_start.py
@@ -2,16 +2,32 @@ from datetime import timedelta
 
 import numpy as np
 import pytest
+import yaml
 
 from cooperative_cuisine import ROOT_DIR
 from cooperative_cuisine.action import ActionType, InterActionData, Action
-from cooperative_cuisine.counters import Counter, CuttingBoard
+from cooperative_cuisine.counters import (
+    Counter,
+    CuttingBoard,
+    CookingCounter,
+    ServingWindow,
+    Trashcan,
+)
+from cooperative_cuisine.effects import FireEffectManager
 from cooperative_cuisine.environment import (
     Environment,
 )
 from cooperative_cuisine.game_server import PlayerRequestType
-from cooperative_cuisine.hooks import Hooks
-from cooperative_cuisine.items import Item, ItemInfo, ItemType
+from cooperative_cuisine.hooks import (
+    Hooks,
+    SERVE_NOT_ORDERED_MEAL,
+    hooks_via_callback_class,
+    PLAYER_ADDED,
+    POST_STEP,
+)
+from cooperative_cuisine.info_msg import InfoMsgManager
+from cooperative_cuisine.items import Item, ItemInfo, ItemType, Plate, CookingEquipment
+from cooperative_cuisine.scores import ScoreViaHooks
 from cooperative_cuisine.server_results import (
     PlayerInfo,
     CreateEnvResult,
@@ -21,7 +37,7 @@ from cooperative_cuisine.state_representation import (
     StateRepresentation,
     create_json_schema,
 )
-from cooperative_cuisine.utils import create_init_env_time
+from cooperative_cuisine.utils import create_init_env_time, get_touching_counters
 
 layouts_folder = ROOT_DIR / "configs" / "layouts"
 environment_config_path = ROOT_DIR / "configs" / "environment_config.yaml"
@@ -54,7 +70,6 @@ def layout_config():
     with open(layout_path, "r") as file:
         layout = file.read()
     return layout
-    env.add_player("0")
 
 
 @pytest.fixture
@@ -218,6 +233,7 @@ def test_processing(env_config, layout_config, item_info):
         },
     )
     env.counters.append(counter)
+    env.overwrite_counters(env.counters)
 
     tomato = Item(name="Tomato", item_info=None)
     env.add_player("1", np.array([2, 3]))
@@ -308,3 +324,237 @@ def test_server_result_definition():
         msg="123",
         player_hash="1234324",
     )
+
+
+def test_fire(env_config, layout_config, item_info):
+    env = Environment(env_config, layout_config, item_info, as_files=False)
+    env.add_player("0")
+    oven = None
+    for c in env.counters:
+        if (
+            isinstance(c, CookingCounter)
+            and c.name == "Stove"
+            and c.occupied_by.name == "Pan"
+        ):
+            oven = c
+            break
+    assert oven is not None
+
+    raw_patty = Item(name="RawPatty", item_info=env.item_info["RawPatty"])
+
+    assert oven.can_drop_off(raw_patty)
+
+    oven.drop_off(raw_patty, "0")
+    assert isinstance(oven.occupied_by, CookingEquipment)
+    assert oven.occupied_by.content_list == [raw_patty]
+
+    env.step(timedelta(seconds=env.item_info["CookedPatty"].seconds))
+    assert oven.occupied_by.content_list[0].name == "CookedPatty"
+    env.step(timedelta(seconds=env.item_info["BurntCookedPatty"].seconds))
+    assert oven.occupied_by.content_list[0].name == "BurntCookedPatty"
+    env.step(timedelta(seconds=env.item_info["Fire"].seconds))
+    assert len(oven.occupied_by.active_effects) != 0
+    assert oven.occupied_by.active_effects[0].name == "Fire"
+
+    fire_manager = env.effect_manager["FireManager"]
+    assert isinstance(fire_manager, FireEffectManager)
+    env.step(fire_manager.next_finished_timer - env.env_time)
+
+    touching_counters = get_touching_counters(oven, env.counters)
+    next_empty = None
+    connect_counter = None
+    for c in touching_counters:
+        if c.occupied_by:
+            assert len(c.occupied_by.active_effects) == 1
+        else:
+            assert len(c.active_effects) == 1
+            next_touching = get_touching_counters(c, env.counters)
+            for a in next_touching:
+                if a not in touching_counters and a.__class__.__name__ == "Counter":
+                    a.occupied_by = None
+                    next_empty = a
+                    connect_counter = c
+    env.step(timedelta(seconds=0.01))
+    assert next_empty is not None
+    next_empty.occupied_by = Item(name="Tomato", item_info=env.item_info["Tomato"])
+    env.step(
+        fire_manager.effect_to_timer[connect_counter.active_effects[0].uuid]
+        - env.env_time
+    )
+    assert len(next_empty.occupied_by.active_effects) == 1
+
+    fire_extinguisher = None
+    for c in env.counters:
+        if c.occupied_by and c.occupied_by.name == "Extinguisher":
+            fire_extinguisher = c.occupied_by
+            c.occupied_by = None
+            break
+
+    assert fire_extinguisher is not None
+    env.players["0"].holding = fire_extinguisher
+    env.players["0"].pos = oven.pos
+    env.players["0"].pos[1] -= 1.0
+    env.perform_action(
+        Action(
+            player="0",
+            action_type=ActionType.MOVEMENT,
+            action_data=np.array([0.0, -1.0]),
+            duration=0.1,
+        )
+    )
+    env.step(timedelta(seconds=0.1))
+
+    env.perform_action(
+        Action(
+            player="0",
+            action_type=ActionType.INTERACT,
+            action_data=InterActionData.START,
+        )
+    )
+    env.step(timedelta(seconds=env.item_info["Extinguisher"].seconds))
+    env.step(timedelta(seconds=env.item_info["Extinguisher"].seconds))
+
+    assert len(oven.occupied_by.active_effects) == 0
+
+
+def test_score(env_config, layout_config, item_info):
+    def incr_score_callback(hook_ref, env: Environment, meal, meal_name, **kwargs):
+        assert isinstance(meal, Item)
+        assert isinstance(meal_name, str)
+        assert meal_name == "TomatoSoup"
+        env.increment_score(1_000, "Soup Soup")
+
+    env = Environment(env_config, layout_config, item_info, as_files=False)
+    assert env.score == 0.0
+    env.add_player("0")
+    env.register_callback_for_hook(SERVE_NOT_ORDERED_MEAL, incr_score_callback)
+    env.register_callback_for_hook(
+        SERVE_NOT_ORDERED_MEAL,
+        ScoreViaHooks(
+            name="123",
+            env=env,
+            score_on_specific_kwarg="meal_name",
+            score_map={"TomatoSoup": 2_000},
+        ),
+    )
+    env.register_callback_for_hook(
+        SERVE_NOT_ORDERED_MEAL,
+        ScoreViaHooks(name="124", env=env, score_map={SERVE_NOT_ORDERED_MEAL: 4_000}),
+    )
+    env.register_callback_for_hook(
+        SERVE_NOT_ORDERED_MEAL,
+        ScoreViaHooks(
+            name="124",
+            env=env,
+            score_map={SERVE_NOT_ORDERED_MEAL: 8_000},
+            kwarg_filter={"meal_name": "TomatoSoup"},
+        ),
+    )
+    env.register_callback_for_hook(
+        SERVE_NOT_ORDERED_MEAL,
+        ScoreViaHooks(
+            name="123",
+            env=env,
+            score_on_specific_kwarg="meal_name",
+            static_score=16_000,
+            score_map={},
+        ),
+    )
+    serving_window = None
+    for c in env.counters:
+        if isinstance(c, ServingWindow):
+            serving_window = c
+            break
+    assert serving_window is not None
+    env.order_manager.serving_not_ordered_meals = True
+    env.order_manager.open_orders = []
+    plate = Plate(
+        transitions=env.counter_factory.filter_item_info(
+            by_item_type=ItemType.Meal, add_effects=True
+        ),
+        clean=True,
+        item_info=env.item_info["Plate"],
+        hook=env.hook,
+    )
+    plate.content_list = [
+        Item(name="TomatoSoup", item_info=env.item_info["TomatoSoup"])
+    ]
+    assert serving_window.can_drop_off(plate)
+
+    returned = serving_window.drop_off(plate, "0")
+    assert returned is None
+
+    plates_prev = len(serving_window.plate_dispenser.occupied_by)
+    assert env.score >= 31_000
+    assert len(serving_window.plate_dispenser.out_of_kitchen_timer) == 1
+    env.step(serving_window.plate_dispenser.out_of_kitchen_timer[0] - env.env_time)
+    assert len(serving_window.plate_dispenser.out_of_kitchen_timer) == 0
+    assert len(serving_window.plate_dispenser.occupied_by) == plates_prev + 1
+    assert (
+        serving_window.plate_dispenser.occupied_by[0].clean
+        != serving_window.plate_dispenser.plate_config.return_dirty
+    )
+
+
+def test_info_msgs(env_config, layout_config, item_info):
+    env_config_dict = yaml.load(env_config, Loader=yaml.Loader)
+    # TODO change after merge with 115
+    env_config_dict["extra_setup_functions"]["dummy_msg"] = {
+        "func": hooks_via_callback_class,
+        "kwargs": {
+            "hooks": [PLAYER_ADDED],
+            "callback_class": InfoMsgManager,
+            "callback_class_kwargs": {"msg": "hello there"},
+        },
+    }
+
+    env_config_dict["extra_setup_functions"]["dummy_msg_2"] = {
+        "func": hooks_via_callback_class,
+        "kwargs": {
+            "hooks": [POST_STEP],
+            "callback_class": InfoMsgManager,
+            "callback_class_kwargs": {"msg": "step step"},
+        },
+    }
+
+    env_config = yaml.dump(env_config_dict)
+
+    env = Environment(env_config, layout_config, item_info, as_files=False)
+    env.add_player("0")
+    assert env.info_msgs_per_player["0"][0]["msg"] == "hello there"
+    env.step(timedelta(seconds=0.1))
+    assert env.info_msgs_per_player["0"][1]["msg"] == "step step"
+    env.step(env.info_msgs_per_player["0"][0]["end_time"] - env.env_time)
+    assert len(env.info_msgs_per_player["0"]) == 2
+    assert env.info_msgs_per_player["0"][0]["msg"] == "step step"
+
+
+def test_trashcan(env_config, layout_config, item_info):
+    env = Environment(env_config, layout_config, item_info, as_files=False)
+    env.add_player("0")
+    trash = None
+    for c in env.counters:
+        if isinstance(c, Trashcan):
+            trash = c
+            break
+    assert trash is not None
+
+    item = Item(name="Tomato", item_info=env.item_info["Tomato"])
+    assert trash.can_drop_off(item)
+    assert trash.drop_off(item, "0") is None
+
+    plate = Plate(
+        transitions=env.counter_factory.filter_item_info(
+            by_item_type=ItemType.Meal, add_effects=True
+        ),
+        clean=True,
+        item_info=env.item_info["Plate"],
+        hook=env.hook,
+    )
+    plate.content_list = [
+        Item(name="TomatoSoup", item_info=env.item_info["TomatoSoup"])
+    ]
+
+    assert trash.can_drop_off(plate)
+    assert trash.drop_off(plate, "0") == plate
+    assert plate.content_list == []