diff --git a/Assets/Resources.meta b/Assets/Resources.meta
new file mode 100644
index 0000000000000000000000000000000000000000..3886a8abc32e5ae605ab2c72b53d3c0d197f3f53
--- /dev/null
+++ b/Assets/Resources.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 780ca0a004a37ad4da79df2418a084a3
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Prefabs.meta b/Assets/Resources/Prefabs.meta
similarity index 77%
rename from Assets/Prefabs.meta
rename to Assets/Resources/Prefabs.meta
index 4b4059607318bf285e7f945980d7b62e9aa6909c..94e07611f3e55108ef7b26ab1c55cc1e9def87cb 100644
--- a/Assets/Prefabs.meta
+++ b/Assets/Resources/Prefabs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 6e7f2ce1b93e054448a962070d372d0d
+guid: 72da1ceec4d574b4cb94df3c670dac08
 folderAsset: yes
 DefaultImporter:
   externalObjects: {}
diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity
index 2a92e186c7296127355e4c11d026b4f89fd6d1a2..f05fbfc028ff8c6942a4a721ff458a1547288000 100644
--- a/Assets/Scenes/SampleScene.unity
+++ b/Assets/Scenes/SampleScene.unity
@@ -123,6 +123,52 @@ NavMeshSettings:
     debug:
       m_Flags: 0
   m_NavMeshData: {fileID: 0}
+--- !u!1 &6125821
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 6125823}
+  - component: {fileID: 6125822}
+  m_Layer: 0
+  m_Name: GameControls
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &6125822
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6125821}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 277e6d37ad3220543a05009070b3a2b8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  backButton: 27
+  attackButton: 122
+--- !u!4 &6125823
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6125821}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 --- !u!1 &117855954
 GameObject:
   m_ObjectHideFlags: 0
@@ -222,6 +268,7 @@ MonoBehaviour:
   knockbackResistance: 0
   maxHealth: 0
   health: 0
+  baseDamage: 0
 --- !u!1 &239523005
 GameObject:
   m_ObjectHideFlags: 0
@@ -251,6 +298,8 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 354f6ba1c1428a04da1f256d1da9f51e, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+  player: {fileID: 0}
+  data: {fileID: 0}
 --- !u!4 &239523007
 Transform:
   m_ObjectHideFlags: 0
@@ -325,7 +374,7 @@ GameObject:
   - component: {fileID: 521822200}
   - component: {fileID: 521822199}
   m_Layer: 0
-  m_Name: GameData
+  m_Name: GameSaveData
   m_TagString: Untagged
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
@@ -343,6 +392,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 1e57b66e76eeafd4bb8ea101ee7598ae, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+  difficulty: 1
 --- !u!4 &521822200
 Transform:
   m_ObjectHideFlags: 0
@@ -372,7 +422,7 @@ GameObject:
   - component: {fileID: 675919036}
   m_Layer: 0
   m_Name: Model
-  m_TagString: Model
+  m_TagString: Untagged
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
@@ -462,7 +512,7 @@ MeshFilter:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 675919034}
-  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+  m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
 --- !u!1 &705507993
 GameObject:
   m_ObjectHideFlags: 0
@@ -779,9 +829,10 @@ GameObject:
   serializedVersion: 6
   m_Component:
   - component: {fileID: 1093326602}
+  - component: {fileID: 1093326603}
   m_Layer: 0
-  m_Name: Weapon
-  m_TagString: Weapon
+  m_Name: TestWeapon
+  m_TagString: Untagged
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
@@ -803,6 +854,19 @@ Transform:
   - {fileID: 2105743491}
   m_Father: {fileID: 117855957}
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1093326603
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1093326601}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 68705b8ed948aae4d98ef6e87b6f6961, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  baseDamage: 10
 --- !u!1 &1098815286
 GameObject:
   m_ObjectHideFlags: 0
@@ -1048,8 +1112,9 @@ GameObject:
   m_Component:
   - component: {fileID: 2105743491}
   - component: {fileID: 2105743492}
+  - component: {fileID: 2105743493}
   m_Layer: 0
-  m_Name: Hitbox
+  m_Name: WeaponHitbox
   m_TagString: Untagged
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
@@ -1091,9 +1156,24 @@ BoxCollider:
   serializedVersion: 3
   m_Size: {x: 1, y: 1, z: 1}
   m_Center: {x: 0, y: 0, z: 0}
+--- !u!114 &2105743493
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2105743490}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d305728f9c09ee84d861e4d2a18c0be0, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  damage: 10
+  knockbackPower: 500
 --- !u!1660057539 &9223372036854775807
 SceneRoots:
   m_ObjectHideFlags: 0
   m_Roots:
   - {fileID: 239523007}
   - {fileID: 521822200}
+  - {fileID: 6125823}
diff --git a/Assets/Scripts/Config/EnvironmentConfig.cs b/Assets/Scripts/Config/EnvironmentConfig.cs
deleted file mode 100644
index 20f5a33f8e0bea506a928f6616c3c06ea4d1c1a7..0000000000000000000000000000000000000000
--- a/Assets/Scripts/Config/EnvironmentConfig.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-public static class EnvironmentConfig{
-    // Tags
-    public static string GROUND_TAG = "Ground";
-}
\ No newline at end of file
diff --git a/Assets/Scripts/Config/GameConfig.cs b/Assets/Scripts/Config/GameConfig.cs
index 8c9270b8075423cf5a4549999b3b298e242b1bd7..60c7f44ed10c3b917a0d88465f123b40a55aed65 100644
--- a/Assets/Scripts/Config/GameConfig.cs
+++ b/Assets/Scripts/Config/GameConfig.cs
@@ -1,8 +1,12 @@
 using System.Collections.Generic;
 
 public static class GameConfig{
+    // Default damaged state delay value
+    public static float DAMAGED_DELAY_DURATION = 1.0f;
+
     // Movement lerp constants
     public static float MOVEMENT_SMOOTHING = 0.14f;
+    public static float MOVEMENT_SMOOTHING_JUMP_SNAPSHOT = 0.14f;
     public static float ROTATION_SMOOTHING = 720;
 
     // Difficulty multipliers
@@ -24,7 +28,7 @@ public static class GameConfig{
         PlayerDamageMultiplier = 0.5f,
         PlayerHealthMultiplier = 0.5f,
     };
-    
+
     public static Dictionary<DifficultyType, DifficultyData> DIFFICULTY_MODIFIERS = new(){
         { DifficultyType.EASY, EasyData},
         { DifficultyType.NORMAL, MediumData},
diff --git a/Assets/Scripts/Config/GameEnvironmentConfig.cs b/Assets/Scripts/Config/GameEnvironmentConfig.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f7088ea7fa12c3ccb08bca042f09759fb73d4db0
--- /dev/null
+++ b/Assets/Scripts/Config/GameEnvironmentConfig.cs
@@ -0,0 +1,8 @@
+public static class GameEnvironmentConfig{
+    // Tags
+    public static string UNTAGGED_TAG = "Untagged";
+    public static string PLAYER_TAG = "Player";
+    public static string ENEMY_TAG = "Enemy";
+    public static string COLLECTIBLES_TAG = "Collectibles";
+    public static string GROUND_TAG = "Ground";
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Config/EnvironmentConfig.cs.meta b/Assets/Scripts/Config/GameEnvironmentConfig.cs.meta
similarity index 100%
rename from Assets/Scripts/Config/EnvironmentConfig.cs.meta
rename to Assets/Scripts/Config/GameEnvironmentConfig.cs.meta
diff --git a/Assets/Scripts/Core/Entities/Mobs/AccompaniableEnemyEntity.cs b/Assets/Scripts/Core/Entities/Mobs/AccompaniableEnemyEntity.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c94d7533b220ce00810f112f0d96c8595a564a46
--- /dev/null
+++ b/Assets/Scripts/Core/Entities/Mobs/AccompaniableEnemyEntity.cs
@@ -0,0 +1,7 @@
+using System.Collections.Generic;
+
+public abstract class AccompaniableEnemyObject : EnemyEntity, IAccompaniable{
+    // Attributes
+    private readonly List<Companions> companionList = new();    
+    public List<Companions> Companions => companionList;
+}
diff --git a/Assets/Scripts/Core/Entities/Mobs/AccompaniableEnemyEntity.cs.meta b/Assets/Scripts/Core/Entities/Mobs/AccompaniableEnemyEntity.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..2a9f879bc8c3b47b5d9482a4fbcdf8e8087226cd
--- /dev/null
+++ b/Assets/Scripts/Core/Entities/Mobs/AccompaniableEnemyEntity.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e8f8664fc9280974c8995cf856525826
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Entities/Mobs/Dummy/Dummy.cs b/Assets/Scripts/Core/Entities/Mobs/Dummy/Dummy.cs
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..84a354a2dfe878ea65c611a28ad42ca0db01e387 100644
--- a/Assets/Scripts/Core/Entities/Mobs/Dummy/Dummy.cs
+++ b/Assets/Scripts/Core/Entities/Mobs/Dummy/Dummy.cs
@@ -0,0 +1,3 @@
+public class Dummy : EnemyEntity{
+    
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Entities/Mobs/Dummy/DummyStateController.cs b/Assets/Scripts/Core/Entities/Mobs/Dummy/DummyStateController.cs
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e66250dd719e0ea1014ec30ecab036c4e394e1e8 100644
--- a/Assets/Scripts/Core/Entities/Mobs/Dummy/DummyStateController.cs
+++ b/Assets/Scripts/Core/Entities/Mobs/Dummy/DummyStateController.cs
@@ -0,0 +1,5 @@
+public class DummyStateController : EntityStateController{
+    public override int UpdateState(){
+        throw new System.NotImplementedException();
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs b/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b3727e740b2677da28901faa3315d32998c336eb
--- /dev/null
+++ b/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs
@@ -0,0 +1,9 @@
+public abstract class EnemyEntity : Combatant {
+    // Functions
+    new void Start(){
+        base.Start();
+        Health *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].EnemyHealthMultiplier;
+        BaseDamage *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].EnemyDamageMultiplier;
+        tag = GameEnvironmentConfig.ENEMY_TAG;
+    }
+}
diff --git a/Assets/Scripts/Core/Entities/Mobs/EnemyObject.cs.meta b/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs.meta
similarity index 100%
rename from Assets/Scripts/Core/Entities/Mobs/EnemyObject.cs.meta
rename to Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs.meta
diff --git a/Assets/Scripts/Core/Entities/Mobs/EnemyObject.cs b/Assets/Scripts/Core/Entities/Mobs/EnemyObject.cs
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/Assets/Scripts/Core/Game/Data.meta b/Assets/Scripts/Core/Game/Data.meta
new file mode 100644
index 0000000000000000000000000000000000000000..26fc8ee5de8146a190f1a6b1e62523b2b71ee4e1
--- /dev/null
+++ b/Assets/Scripts/Core/Game/Data.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 37b61c2c546ff8a42a03da536564d42e
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Game/Data/GameControls.cs b/Assets/Scripts/Core/Game/Data/GameControls.cs
new file mode 100644
index 0000000000000000000000000000000000000000..3e86ad3f207b8856008231154b6df5ab12fd7114
--- /dev/null
+++ b/Assets/Scripts/Core/Game/Data/GameControls.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+
+public class GameControls : MonoBehaviour {
+    // Attributes
+    public static GameControls instance;
+    public KeyCode backButton = KeyCode.Escape;
+    public KeyCode attackButton = KeyCode.Z;
+
+    // Constructor
+    private void Awake(){
+        instance = this;
+        DontDestroyOnLoad(gameObject);
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Game/Data/GameControls.cs.meta b/Assets/Scripts/Core/Game/Data/GameControls.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..be4708d209cf1947b2d2a93a5010f88ede40e57f
--- /dev/null
+++ b/Assets/Scripts/Core/Game/Data/GameControls.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 277e6d37ad3220543a05009070b3a2b8
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Game/GameData.cs b/Assets/Scripts/Core/Game/Data/GameSaveData.cs
similarity index 50%
rename from Assets/Scripts/Core/Game/GameData.cs
rename to Assets/Scripts/Core/Game/Data/GameSaveData.cs
index 2bcb2f6282a2f534c6d962072b3dd774fd8afee4..9bed0027dd6e0fdba119e6a553f711a49fb7f5b9 100644
--- a/Assets/Scripts/Core/Game/GameData.cs
+++ b/Assets/Scripts/Core/Game/Data/GameSaveData.cs
@@ -3,20 +3,15 @@ using System.Collections.Generic;
 using Unity.VisualScripting;
 using UnityEngine;
 
-public class GameData : MonoBehaviour {
+public class GameSaveData : MonoBehaviour {
     // Attributes
-    public static GameData instance;
+    public static GameSaveData instance;
+
+    public DifficultyType difficulty = DifficultyType.NORMAL;
 
-    public static DifficultyType difficulty = DifficultyType.NORMAL;
-    
     // Constructor
     private void Awake(){
         instance = this;
         DontDestroyOnLoad(gameObject);
     }
-
-    // Functions
-    public void Save(PlayerStats playerStats){
-    
-    }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Core/Game/GameData.cs.meta b/Assets/Scripts/Core/Game/Data/GameSaveData.cs.meta
similarity index 100%
rename from Assets/Scripts/Core/Game/GameData.cs.meta
rename to Assets/Scripts/Core/Game/Data/GameSaveData.cs.meta
diff --git a/Assets/Scripts/Core/Game/GameCameraController.cs b/Assets/Scripts/Core/Game/GameCameraController.cs
index 147cb6cfff3a56c5ed9ab7ad5363012ff11c40b3..257868a304877aecd9152f605acc30ade08acfa9 100644
--- a/Assets/Scripts/Core/Game/GameCameraController.cs
+++ b/Assets/Scripts/Core/Game/GameCameraController.cs
@@ -30,17 +30,12 @@ public class GameCameraController {
     public void SetCameraBehaviour(CameraBehaviourType cameraBehaviourType){
         GameObject.Destroy(activeCamera.GetComponent<CameraBehaviour>());
 
-        switch (cameraBehaviourType){
-            case CameraBehaviourType.STATIC:
-                behaviour = activeCamera.AddComponent<CameraStatic>();                
-                break;
-            case CameraBehaviourType.FOLLOW:
-                behaviour = activeCamera.AddComponent<CameraFollowObject>();                
-                break;
-            
-            default:
-                throw new Exception("Invalid cameraBehaviourType set, please refer to enum CameraBehaviourType for valid types");
-        }
+        behaviour = cameraBehaviourType switch{
+            CameraBehaviourType.STATIC => activeCamera.AddComponent<CameraStatic>(),
+            CameraBehaviourType.FOLLOW => activeCamera.AddComponent<CameraFollowObject>(),
+            _ => throw new Exception("Invalid cameraBehaviourType set, please refer to enum CameraBehaviourType for valid types")
+        };
+
         behaviourType = cameraBehaviourType;
     }
 }
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Game/GameController.cs b/Assets/Scripts/Core/Game/GameController.cs
index 8de3b00afc21868c36684021409b9cb6889a6c2a..61234df29cee5116044a9cb6947082b424515382 100644
--- a/Assets/Scripts/Core/Game/GameController.cs
+++ b/Assets/Scripts/Core/Game/GameController.cs
@@ -4,9 +4,10 @@ using UnityEngine;
 public class GameController : MonoBehaviour {
     // Attributes
     public static GameController instance;
-    public static GameCameraController mainCamera;
-    public static GameStateController stateController;
-    public static GameData data;
+    public Player player;
+    public GameCameraController mainCamera;
+    public GameStateController stateController;
+    public GameSaveData data;
     public bool IsPaused => Time.timeScale == 0;
 
     // Constructor
@@ -14,13 +15,13 @@ public class GameController : MonoBehaviour {
         if(instance == null) instance = this;
         mainCamera = new GameCameraController(GetComponentInChildren<Camera>());
         stateController = new GameStateController();
-        data = GameData.instance;
+        data = GameSaveData.instance;
     }
 
     // Functions
     void Update(){
-         if(Input.GetKeyDown(KeyCode.Escape)){
+         if(Input.GetKeyDown(GameControls.instance.backButton)){
             stateController.HandleEscape();
          }
     }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Core/Game/GameStateController.cs b/Assets/Scripts/Core/Game/GameStateController.cs
index 29bb07cbc7cf5a610b2eeb2fbe6934fa88392abc..2f73522629ddc0c84adce3e1364956898505cc7d 100644
--- a/Assets/Scripts/Core/Game/GameStateController.cs
+++ b/Assets/Scripts/Core/Game/GameStateController.cs
@@ -3,11 +3,11 @@ using System.Collections.Generic;
 using Unity.VisualScripting;
 using UnityEngine;
 
-public class GameStateController {
+public class GameStateController{
     // Attributes
     private readonly Stack<GameState> gameStateStack = new();
     event GameStateChangeEvent OnGameStateChange;
-    event Action OnPaused;
+    event Action OnPausedEvent;
 
     // Constructor
     public GameStateController(){
@@ -17,29 +17,20 @@ public class GameStateController {
     }
 
     // Functions
-    private void LogGameStateStack(StackChangeEventArgs<GameState> e){
-        Debug.Log(e.EventType);
-        Debug.Log(gameStateStack);
+    private void LogGameStateStack(GameStateChangeArgs e){
+        Debug.Log(string.Format("GameState {0}; Current gamestate is {1}", e.EventType, e.NewGameState));
     }
 
     public void PushState(GameState gameState){
-        switch(gameState){
-            case GameState.PAUSED:
-                Time.timeScale = 0;
-                break;
-            case GameState.RUNNING:
-                Time.timeScale = 1;
-                break;
-            //TODO: Review cutscenes and menu behaviour
-            case GameState.CUTSCENE:
-                Time.timeScale = 0;
-                break;
-            case GameState.MENU:
-                Time.timeScale = 0;
-                break;
-            default:
-                throw new Exception("Invalid gameState pushed to GameStateController, please refer to enum GameState for valid states");
-        }
+        //TODO: Review cutscenes and menu behaviour
+        Time.timeScale = gameState switch{
+            GameState.PAUSED => 0,
+            GameState.RUNNING => 1,
+            GameState.CUTSCENE => 0,
+            GameState.MENU => 0,
+            _ => throw new Exception("Invalid gameState pushed to GameStateController, please refer to enum GameState for valid states"),
+        };
+
         gameStateStack.Push(gameState);
         OnGameStateChange?.Invoke(new GameStateChangeArgs(
             StackChangeEventType.PUSH,
@@ -51,21 +42,15 @@ public class GameStateController {
     public void PopState(){
         gameStateStack.Pop();
         GameState gameState = gameStateStack.Peek();
-        switch(gameState){
-            case GameState.PAUSED:
-                Time.timeScale = 0;
-                break;
-            case GameState.RUNNING:
-                Time.timeScale = 1;
-                break;
-            //TODO: Review cutscenes behaviour
-            case GameState.CUTSCENE:
-                Time.timeScale = 0;
-                break;
-            case GameState.MENU:
-                Time.timeScale = 0;
-                break;
-        }
+        //TODO: Review cutscenes behaviour
+        Time.timeScale = gameState switch{
+            GameState.PAUSED => 0,
+            GameState.RUNNING => 1,
+            GameState.CUTSCENE => 0,
+            GameState.MENU => 0,
+            _ => throw new Exception("Invalid gameState popped to GameStateController, please refer to enum GameState for valid states"),
+        };
+
         OnGameStateChange?.Invoke(new GameStateChangeArgs(
             StackChangeEventType.POP,
             gameStateStack.Count,
@@ -77,7 +62,7 @@ public class GameStateController {
         switch (gameStateStack.Peek()){
             case GameState.RUNNING:
                 PushState(GameState.PAUSED);
-                OnPaused?.Invoke();
+                OnPausedEvent?.Invoke();
                 return;
 
             case GameState.PAUSED:
@@ -90,4 +75,4 @@ public class GameStateController {
                 return;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs b/Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs
new file mode 100644
index 0000000000000000000000000000000000000000..36ba66a22309a9d1d42b940a80c23bdba4b610eb
--- /dev/null
+++ b/Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs
@@ -0,0 +1,7 @@
+using UnityEngine;
+
+public class TestWeapon : WeaponObject{
+    public override void Attack(){
+        Debug.Log("Attacking using a Test Weapon");
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs.meta b/Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..eb0b2e71e8b09bd86f372ba632562642b4b0cbf3
--- /dev/null
+++ b/Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 68705b8ed948aae4d98ef6e87b6f6961
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Player/Player.cs b/Assets/Scripts/Core/Player/Player.cs
index 481a74e6195d6eec525b95bb1ea5467c489c4b85..980be6f2e58b646dff25452af40f8db66fc8f706 100644
--- a/Assets/Scripts/Core/Player/Player.cs
+++ b/Assets/Scripts/Core/Player/Player.cs
@@ -3,31 +3,38 @@ using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
-public class Player : Combatant {
+public class Player : AccompaniableCombatant {
     private PlayerAnimationController animationController;
     private PlayerMovementController movementController;
+    private PlayerAttackController attackController;
     public PlayerStateController stateController;
     public PlayerStats stats;
 
     new void Start(){
         base.Start();
-        Health *= GameConfig.DIFFICULTY_MODIFIERS[GameData.difficulty].PlayerHealthMultiplier;
-        BaseDamage *= GameConfig.DIFFICULTY_MODIFIERS[GameData.difficulty].PlayerDamageMultiplier;
+        Health *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].PlayerHealthMultiplier;
+        BaseDamage *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].PlayerDamageMultiplier;
 
+        Weapon = GetComponentInChildren<WeaponObject>();
         stateController = new PlayerStateController(this);
         movementController = new PlayerMovementController(this);
         animationController = new PlayerAnimationController(this);
+        attackController = new PlayerAttackController(this);
         stats = new PlayerStats(this);
+
+        GameController.instance.player = this;
     }
 
     new void Update(){
         base.Update();
+
+        attackController.HandleInputs();
     }
 
     new void FixedUpdate(){
         base.FixedUpdate();
 
-        stateController.DetectState();
+        stateController.UpdateState();
         movementController.HandleMovement();
     }
 }
diff --git a/Assets/Scripts/Core/Player/PlayerAnimationController.cs b/Assets/Scripts/Core/Player/PlayerAnimationController.cs
index 24bd42b5145074eeb9785429f172d24afc88e299..29a37e14a10bb9cc8b2f4843df8385d9a3b1897d 100644
--- a/Assets/Scripts/Core/Player/PlayerAnimationController.cs
+++ b/Assets/Scripts/Core/Player/PlayerAnimationController.cs
@@ -7,7 +7,7 @@ public class PlayerAnimationController{
     private const string SPRINT_TRIGGER = "sprint_param"; 
     
     // Attributes
-    private Player player;
+    private readonly Player player;
     private PlayerStateController playerStateController;
     private Transform modelTransform;
     private Animator animator;
@@ -18,7 +18,7 @@ public class PlayerAnimationController{
         modelTransform = player.transform.Find("Model");
         animator = modelTransform.GetComponent<Animator>();
 
-        player.stateController.OnStateChange += Animate;
+        player.stateController.OnStateChangeEvent += Animate;
     }
 
     // Functions
diff --git a/Assets/Scripts/Core/Player/PlayerAttackController.cs b/Assets/Scripts/Core/Player/PlayerAttackController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..999fec2259d3a902d716246e9a2bf7b67a5ca21f
--- /dev/null
+++ b/Assets/Scripts/Core/Player/PlayerAttackController.cs
@@ -0,0 +1,19 @@
+using UnityEngine;
+
+public class PlayerAttackController{
+    private readonly Player player;
+    
+    public PlayerAttackController(Player player){
+        this.player = player;
+    }
+
+    public void HandleInputs(){
+        if(Input.GetKeyDown(GameControls.instance.attackButton)){
+            Debug.Log("Player is attacking");
+            
+            if(player.Weapon == null) return;
+
+            player.Weapon.Attack();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Player/PlayerAttackController.cs.meta b/Assets/Scripts/Core/Player/PlayerAttackController.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..82d65179a740ceab44bbed08b72e629575a9798f
--- /dev/null
+++ b/Assets/Scripts/Core/Player/PlayerAttackController.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 24d96e02bfd50214984282c944c8e741
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Player/PlayerMovementController.cs b/Assets/Scripts/Core/Player/PlayerMovementController.cs
index 3e31d62680ad8443348d19cb989835e69948bed7..9cd5490ff09c289a1670ea08581ffc0623d74437 100644
--- a/Assets/Scripts/Core/Player/PlayerMovementController.cs
+++ b/Assets/Scripts/Core/Player/PlayerMovementController.cs
@@ -3,7 +3,7 @@ using UnityEngine;
 
 public class PlayerMovementController{
     // Attributes
-    private Player player;
+    private readonly Player player;
 
     // Constructor
     public PlayerMovementController(Player player){
@@ -19,12 +19,12 @@ public class PlayerMovementController{
     }
 
     public void HandleMovement(){
-        float keyPressAD = Input.GetAxisRaw("Horizontal");
-        float keyPressWS = Input.GetAxisRaw("Vertical");
+        float keyPressX = Input.GetAxisRaw("Horizontal");
+        float keyPressZ = Input.GetAxisRaw("Vertical");
         Vector3 velocity = new(player.Rigidbody.velocity.x, player.Rigidbody.velocity.y, player.Rigidbody.velocity.z);
         Vector3 dampVelocity = Vector3.zero;
 
-        Vector3 inputVector = new(keyPressAD, 0, keyPressWS);
+        Vector3 inputVector = new(keyPressX, 0, keyPressZ);
         Vector3 modifierVector = inputVector.normalized * player.stats.MaxSpeed;
         velocity.x = modifierVector.x;
         velocity.z = modifierVector.z;
diff --git a/Assets/Scripts/Core/Player/PlayerStateController.cs b/Assets/Scripts/Core/Player/PlayerStateController.cs
index 4aeac9157f5a77a7fae7f0e2f2a633d6cc4520e2..c61b876498159c50e62afcce0f06ae4939875a37 100644
--- a/Assets/Scripts/Core/Player/PlayerStateController.cs
+++ b/Assets/Scripts/Core/Player/PlayerStateController.cs
@@ -1,21 +1,15 @@
 using UnityEngine;
 
-public class PlayerStateController : StateController{
+public class PlayerStateController : DamageableEntityStateController {
     // Attributes
-    private Player player;
+    private readonly Player player;
 
     // Contstructor
-    public PlayerStateController(Player player){
+    public PlayerStateController(Player player) : base(player){
         this.player = player;
     }
 
     // Functions
-    private bool DetectJumping(){
-        return !player.Grounded && player.Rigidbody.velocity.y > 0;
-    }
-    private bool DetectFalling(){
-        return !player.Grounded && player.Rigidbody.velocity.y < 0;
-    }
     private bool DetectWalking(){
         return Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0;
     }
@@ -23,16 +17,10 @@ public class PlayerStateController : StateController{
         return (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0) && Input.GetKey(KeyCode.LeftShift);
     }
 
-    public override int DetectState(){
+    public override int UpdateState(){
         int initialState = state;
 
-        if(DetectJumping()){
-            state = PlayerState.JUMPING;
-        }
-        else if(DetectFalling()){
-            state = PlayerState.FALLING;
-        }
-        else if(DetectSprinting()){
+        if(DetectSprinting()){
             state = PlayerState.SPRINTING;
         }
         else if(DetectWalking()){
diff --git a/Assets/Scripts/Core/Player/PlayerStats.cs b/Assets/Scripts/Core/Player/PlayerStats.cs
index 31a088cb35a9641c19327c0a7c54b0b5f0ad39a2..1c5305ba28308610a8f914f9b008bdb875f345d6 100644
--- a/Assets/Scripts/Core/Player/PlayerStats.cs
+++ b/Assets/Scripts/Core/Player/PlayerStats.cs
@@ -3,10 +3,7 @@ using UnityEngine;
 public class PlayerStats {
     // Attributes
     private readonly Player player;
-    [SerializeField] public float walkSpeed = 10;
-    [SerializeField] public float sprintSpeed = 20;
-    [SerializeField] public float jumpForce = 600;
-    public float snapshotSpeed = 25;
+    public float sprintModifier = 1.5f;
     public float Health {
         get => player.Health;
         set => player.Health = value;
@@ -19,12 +16,9 @@ public class PlayerStats {
         get => player.BaseDamage;
         set => player.BaseDamage = value;
     }
-
     public float MaxSpeed => player.stateController.state switch{
-        PlayerState.WALKING => walkSpeed,
-        PlayerState.SPRINTING => sprintSpeed,
-        PlayerState.JUMPING => snapshotSpeed,
-        PlayerState.FALLING => snapshotSpeed,
+        PlayerState.WALKING => player.BaseSpeed,
+        PlayerState.SPRINTING => player.BaseSpeed * sprintModifier,
         _ => 0
     };
 
@@ -32,9 +26,4 @@ public class PlayerStats {
     public PlayerStats(Player player){
         this.player = player;
     }
-
-    // Functions
-    public void SaveStats(){
-        GameData.instance.Save(this);
-    }
 }
diff --git a/Assets/Scripts/Library/BaseClasses/AccompaniableCombatant.cs b/Assets/Scripts/Library/BaseClasses/AccompaniableCombatant.cs
new file mode 100644
index 0000000000000000000000000000000000000000..17aed23a8fa329849101a2f24dbffe2ebd74c4c5
--- /dev/null
+++ b/Assets/Scripts/Library/BaseClasses/AccompaniableCombatant.cs
@@ -0,0 +1,7 @@
+using System.Collections.Generic;
+
+public class AccompaniableCombatant : Combatant, IAccompaniable{
+    // Attributes
+    private readonly List<Companions> companionList = new();    
+    public List<Companions> Companions => companionList;
+}
diff --git a/Assets/Scripts/Library/BaseClasses/AccompaniableCombatant.cs.meta b/Assets/Scripts/Library/BaseClasses/AccompaniableCombatant.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..b084917adb5e37cffc7d65f700e35375226c17c8
--- /dev/null
+++ b/Assets/Scripts/Library/BaseClasses/AccompaniableCombatant.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 70ede02eebb60bf4f9f966141d3e789e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Library/BaseClasses/AttackHitbox.cs b/Assets/Scripts/Library/BaseClasses/AttackHitbox.cs
index 51c85788504a807a1db62f2019cc43db0f9b6da1..00b9bca25f0dfe80a8c627ed8cdc5dbac88c73aa 100644
--- a/Assets/Scripts/Library/BaseClasses/AttackHitbox.cs
+++ b/Assets/Scripts/Library/BaseClasses/AttackHitbox.cs
@@ -2,8 +2,9 @@ using System;
 using UnityEngine;
 
 public class AttackHitbox : AttackObject{
+    // Functions
     void OnTriggerStay(Collider otherCollider){
         Debug.Log(string.Format("Collision in hitbox of {0} by {1}", transform.name, otherCollider.transform.name));
         Hit(otherCollider);
     }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/BaseClasses/Combatant.cs b/Assets/Scripts/Library/BaseClasses/Combatant.cs
index d0d8786a5a63e1dfb8fad992fdab6ec3b9254474..2e6e17854f5af6415d3770b701923794c117e397 100644
--- a/Assets/Scripts/Library/BaseClasses/Combatant.cs
+++ b/Assets/Scripts/Library/BaseClasses/Combatant.cs
@@ -2,6 +2,7 @@ using System;
 using UnityEngine;
 
 public class Combatant : DamageableEntity, IArmed{
+    // Attributes
     [SerializeField] private float baseDamage;
     private WeaponObject weapon;
     public float BaseDamage { 
@@ -10,6 +11,11 @@ public class Combatant : DamageableEntity, IArmed{
     }
     public WeaponObject Weapon { 
         get => weapon; 
-        set => Weapon = value;
+        set => weapon = value;
     }
-}
\ No newline at end of file
+
+    // TODO: Test then decide whether to destroy/disable previous weapon
+    public void SwapWeapon(WeaponObject newWeapon){
+        Weapon = newWeapon;
+    }
+}
diff --git a/Assets/Scripts/Library/BaseClasses/Companions.cs b/Assets/Scripts/Library/BaseClasses/Companions.cs
new file mode 100644
index 0000000000000000000000000000000000000000..5cb61306d8b63be3013888c0083e7a628f942c41
--- /dev/null
+++ b/Assets/Scripts/Library/BaseClasses/Companions.cs
@@ -0,0 +1,7 @@
+using System;
+using UnityEngine;
+
+public abstract class Companions : DamageableEntity {
+    // Functions
+    public virtual void Act(){}
+}
diff --git a/Assets/Scripts/Library/BaseClasses/Companions.cs.meta b/Assets/Scripts/Library/BaseClasses/Companions.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..ea89e63d5f257dacabbc7f8f8fc2d6de316150d1
--- /dev/null
+++ b/Assets/Scripts/Library/BaseClasses/Companions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b9d58cb51e6bf6d47a044752686fe646
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Library/BaseClasses/Entity-Object/AttackEntity.cs b/Assets/Scripts/Library/BaseClasses/Entity-Object/AttackEntity.cs
index 59c33cd13bba805275025e47609fe6d1cb5d7cb1..a0d413b9786b856b44722ea5e0251cb3490aa3f9 100644
--- a/Assets/Scripts/Library/BaseClasses/Entity-Object/AttackEntity.cs
+++ b/Assets/Scripts/Library/BaseClasses/Entity-Object/AttackEntity.cs
@@ -14,7 +14,7 @@ public class AttackEntity : RigidEntity, IDamaging, IKnockback{
         set => damage = value; 
     }
     public Vector3 KnockbackOrigin{get; set;}
-    public event Action OnDamage;
+    public event Action OnDamageEvent;
 
     // Functions
     public void Knockback(IRigid rigidObject){
@@ -29,7 +29,7 @@ public class AttackEntity : RigidEntity, IDamaging, IKnockback{
 
         if(damageableObject.Damageable){
             damageableObject.InflictDamage(Damage);
-            OnDamage?.Invoke();
+            OnDamageEvent?.Invoke();
 
             otherCollider.TryGetComponent<IRigid>(out var rigidObject);
             if(rigidObject != null) Knockback(rigidObject);
diff --git a/Assets/Scripts/Library/BaseClasses/Entity-Object/AttackObject.cs b/Assets/Scripts/Library/BaseClasses/Entity-Object/AttackObject.cs
index 9d84903353165bcdb8ae772e0ede8c81be1d64fc..ae4645b83965b89eb333d46548e88d6d1681a226 100644
--- a/Assets/Scripts/Library/BaseClasses/Entity-Object/AttackObject.cs
+++ b/Assets/Scripts/Library/BaseClasses/Entity-Object/AttackObject.cs
@@ -14,7 +14,7 @@ public class AttackObject : MonoBehaviour, IDamaging, IKnockback{
         set => damage = value; 
     }
     public Vector3 KnockbackOrigin{get; set;}
-    public event Action OnDamage;
+    public event Action OnDamageEvent;
 
     // Functions
     public void Knockback(IRigid rigidObject){
@@ -29,10 +29,10 @@ public class AttackObject : MonoBehaviour, IDamaging, IKnockback{
 
         if(damageableObject.Damageable){
             damageableObject.InflictDamage(Damage);
-            OnDamage?.Invoke();
+            OnDamageEvent?.Invoke();
 
             otherCollider.TryGetComponent<IRigid>(out var rigidObject);
             if(rigidObject != null) Knockback(rigidObject);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/BaseClasses/Entity-Object/DamageableEntity.cs b/Assets/Scripts/Library/BaseClasses/Entity-Object/DamageableEntity.cs
index c46bd2e58e1f0504ce56fe1bf4bd8142e7c53b7c..56f1d388bc89f220f48ddb5f704cf2945e1a8e63 100644
--- a/Assets/Scripts/Library/BaseClasses/Entity-Object/DamageableEntity.cs
+++ b/Assets/Scripts/Library/BaseClasses/Entity-Object/DamageableEntity.cs
@@ -17,22 +17,22 @@ public class DamageableEntity : RigidEntity, IDamageable{
 
     public bool Damageable => !Dead;
     public bool Dead => health <= 0;
-    public event Action OnDeath;
-    public event Action OnDamaged;
-    public event Action OnHeal;
+    public event Action OnDeathEvent;
+    public event Action OnDamagedEvent;
+    public event Action OnHealEvent;
 
     // Functions
     public float InflictDamage(float damage){
         Health -= damage;
-        OnDamaged?.Invoke();
-        if(Dead) OnDeath?.Invoke();
+        OnDamagedEvent?.Invoke();
+        if(Dead) OnDeathEvent?.Invoke();
 
         return Health;
     }
 
     public float InflictHeal(float heal){
         Health += heal;
-        OnHeal?.Invoke();
+        OnHealEvent?.Invoke();
 
         return Health;
     }
@@ -48,4 +48,4 @@ public class DamageableEntity : RigidEntity, IDamageable{
     protected new void FixedUpdate(){
         base.FixedUpdate();
     }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/BaseClasses/Entity-Object/DamageableObject.cs b/Assets/Scripts/Library/BaseClasses/Entity-Object/DamageableObject.cs
index 06229a546bcf987edb73cf5469cc5b6879a166b6..9593c5046d5b299f65d10567ae5309bca9eaf211 100644
--- a/Assets/Scripts/Library/BaseClasses/Entity-Object/DamageableObject.cs
+++ b/Assets/Scripts/Library/BaseClasses/Entity-Object/DamageableObject.cs
@@ -17,23 +17,23 @@ public class DamageableObject : MonoBehaviour, IDamageable{
 
     public bool Damageable => !Dead;
     public bool Dead => health <= 0;
-    public event Action OnDeath;
-    public event Action OnDamaged;
-    public event Action OnHeal;
+    public event Action OnDeathEvent;
+    public event Action OnDamagedEvent;
+    public event Action OnHealEvent;
 
     // Functions
     public float InflictDamage(float damage){
         Health -= damage;
-        OnDamaged?.Invoke();
-        if(Dead) OnDeath?.Invoke();
+        OnDamagedEvent?.Invoke();
+        if(Dead) OnDeathEvent?.Invoke();
 
         return Health;
     }
 
     public float InflictHeal(float heal){
         Health += heal;
-        OnHeal?.Invoke();
+        OnHealEvent?.Invoke();
 
         return Health;
     }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/BaseClasses/Entity-Object/RigidEntity.cs b/Assets/Scripts/Library/BaseClasses/Entity-Object/RigidEntity.cs
index 54dbbd59c577ba0d755046682b82bea64a355f46..2b27abc800e455c6938e89791902360bd31e1f45 100644
--- a/Assets/Scripts/Library/BaseClasses/Entity-Object/RigidEntity.cs
+++ b/Assets/Scripts/Library/BaseClasses/Entity-Object/RigidEntity.cs
@@ -3,25 +3,24 @@ using UnityEngine;
 public class RigidEntity : MonoBehaviour, IRigid {
     // Attributes
     [SerializeField] private float knockbackResistance;
-
-    // Readonly by others
+    [SerializeField] private float baseSpeed;
     private new Rigidbody rigidbody;
     private new Collider collider;
-
-    //TODO: grounded automatic detection
-    private bool grounded = true;
-
-
+    
     public Rigidbody Rigidbody => rigidbody;
     public Collider Collider => collider;
     public Vector3 Position => transform.position;
-    public bool Grounded => grounded;
     public float KnockbackResistance {
         get => knockbackResistance <= 0? 1 : knockbackResistance;
         set => knockbackResistance = value;
     }
+    public float BaseSpeed { 
+        get => baseSpeed; 
+        set => baseSpeed = value < 0? 0 : value; 
+    }
 
     // Constructor
+
     protected void Start(){
         rigidbody = GetComponent<Rigidbody>();
         collider = GetComponent<Collider>();
diff --git a/Assets/Scripts/Library/BaseClasses/EntityStateController.meta b/Assets/Scripts/Library/BaseClasses/EntityStateController.meta
new file mode 100644
index 0000000000000000000000000000000000000000..21bc92439ca9c5fa4bf66ecee22c4c3ab9082eb1
--- /dev/null
+++ b/Assets/Scripts/Library/BaseClasses/EntityStateController.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e003128a05a8b1c46aaa1f39942aef7b
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Library/BaseClasses/EntityStateController/DamageableEntityStateController.cs b/Assets/Scripts/Library/BaseClasses/EntityStateController/DamageableEntityStateController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..cccba9fe17d09a68bcaf0ecbb2b78c05f6ac8e12
--- /dev/null
+++ b/Assets/Scripts/Library/BaseClasses/EntityStateController/DamageableEntityStateController.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections;
+using UnityEngine;
+
+public abstract class DamageableEntityStateController : EntityStateController {
+    // Attributes
+    private readonly DamageableEntity Entity;
+    private float damagedDelay;
+    protected bool damaged = false;
+    public bool Damaged => damaged;
+    public float DamagedDelay {
+        get => damagedDelay;
+        set => damagedDelay = value <= 0? GameConfig.DAMAGED_DELAY_DURATION : value;
+    }
+    public event Action OnDamageDelayOverEvent;
+
+    // Constructor
+    public DamageableEntityStateController(DamageableEntity entity, float delay = 0){
+        Entity = entity;
+        DamagedDelay =  delay;
+
+        OnDamageDelayOverEvent += OnDamageDelayOver;
+        entity.OnDamagedEvent += OnDamaged;
+    }
+
+    // Functions
+    private IEnumerator WaitDamagedDelay(){
+        if (!Entity.Dead){
+            yield return new WaitForSeconds(DamagedDelay);
+            damaged = false;
+            InvokeDamageDelayOver();
+        }
+    }
+
+    private void InvokeDamageDelayOver(){
+        OnDamageDelayOverEvent?.Invoke();
+    }
+
+    private void OnDamaged(){
+        damaged = true;
+        InvokeOnStateChanged();
+        Entity.StartCoroutine(WaitDamagedDelay());
+    }
+    private void OnDamageDelayOver(){
+        damaged = false;
+        InvokeOnStateChanged();
+    }
+}
diff --git a/Assets/Scripts/Library/BaseClasses/EntityStateController/DamageableEntityStateController.cs.meta b/Assets/Scripts/Library/BaseClasses/EntityStateController/DamageableEntityStateController.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..9020185e9ed594144cfcdbaf2997fc542e8e7321
--- /dev/null
+++ b/Assets/Scripts/Library/BaseClasses/EntityStateController/DamageableEntityStateController.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0e4de83b38eceeb428f0a0e1d1b346a4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Library/BaseClasses/EntityStateController/EntityStateController.cs b/Assets/Scripts/Library/BaseClasses/EntityStateController/EntityStateController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6af8f29a7defcc294bd13cfa36addd26357c4c33
--- /dev/null
+++ b/Assets/Scripts/Library/BaseClasses/EntityStateController/EntityStateController.cs
@@ -0,0 +1,14 @@
+using System;
+
+public abstract class EntityStateController{
+    // Attributes
+    public int state;
+    public event Action OnStateChangeEvent;
+
+    // Functions
+    protected void InvokeOnStateChanged(){
+        OnStateChangeEvent?.Invoke();
+    }
+
+    public abstract int UpdateState();
+}
diff --git a/Assets/Scripts/Library/BaseClasses/StateController.cs.meta b/Assets/Scripts/Library/BaseClasses/EntityStateController/EntityStateController.cs.meta
similarity index 100%
rename from Assets/Scripts/Library/BaseClasses/StateController.cs.meta
rename to Assets/Scripts/Library/BaseClasses/EntityStateController/EntityStateController.cs.meta
diff --git a/Assets/Scripts/Library/BaseClasses/StateController.cs b/Assets/Scripts/Library/BaseClasses/StateController.cs
deleted file mode 100644
index 224c230671e6109e178fb5fe941be9d77fc52cd1..0000000000000000000000000000000000000000
--- a/Assets/Scripts/Library/BaseClasses/StateController.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-public abstract class StateController{
-    // Attributes
-    public int state;
-    public event Action OnStateChange;
-
-    // Functions
-    protected void InvokeOnStateChanged(){
-        OnStateChange?.Invoke();
-    }
-
-    public abstract int DetectState();
-}
\ No newline at end of file
diff --git a/Assets/Scripts/Library/BaseClasses/WeaponObject.cs b/Assets/Scripts/Library/BaseClasses/WeaponObject.cs
index 8fd24421aae7431f70743a8fe7ce41946a6a73ba..44ea16ac0d01d70be2147afb30fbd1a471b04646 100644
--- a/Assets/Scripts/Library/BaseClasses/WeaponObject.cs
+++ b/Assets/Scripts/Library/BaseClasses/WeaponObject.cs
@@ -1,6 +1,14 @@
 using System;
 using UnityEngine;
 
-public abstract class WeaponObject : AttackObject{
-    public virtual void Attack(){}
-}
\ No newline at end of file
+public abstract class WeaponObject : MonoBehaviour {
+    // Attributes
+    [SerializeField] private float baseDamage;
+    public float BaseDamage { 
+        get => baseDamage;
+        set => baseDamage = value;
+    }
+
+    // Functions
+    public abstract void Attack();
+}
diff --git a/Assets/Scripts/Library/CameraBehaviour/CameraBehaviour.cs b/Assets/Scripts/Library/CameraBehaviour/CameraBehaviour.cs
index 44266adbb838cf24a40c259889d30f63f3b2cab7..be1ead9e89e836d1ab6b277b251a427e2bbe40f9 100644
--- a/Assets/Scripts/Library/CameraBehaviour/CameraBehaviour.cs
+++ b/Assets/Scripts/Library/CameraBehaviour/CameraBehaviour.cs
@@ -1,3 +1,3 @@
 using UnityEngine;
 
-public abstract class CameraBehaviour : MonoBehaviour {}
\ No newline at end of file
+public abstract class CameraBehaviour : MonoBehaviour {}
diff --git a/Assets/Scripts/Library/CameraBehaviour/CameraFollowObject.cs b/Assets/Scripts/Library/CameraBehaviour/CameraFollowObject.cs
index 85c4660b42a108f1a70b17e7d70a33e2251e264c..3ee122253123b97bdb429202dd8c1fc7207c1be6 100644
--- a/Assets/Scripts/Library/CameraBehaviour/CameraFollowObject.cs
+++ b/Assets/Scripts/Library/CameraBehaviour/CameraFollowObject.cs
@@ -13,4 +13,4 @@ public class CameraFollowObject : CameraBehaviour {
         Vector3 newPosition = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, followingTime);
         transform.position = newPosition;
     }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/CameraBehaviour/CameraStatic.cs b/Assets/Scripts/Library/CameraBehaviour/CameraStatic.cs
index 7679352d30b7e77e2825e081c9b4a99e4d4f20d0..c88e88fa927b4dcdd3b8bfb56aa3294d165321a9 100644
--- a/Assets/Scripts/Library/CameraBehaviour/CameraStatic.cs
+++ b/Assets/Scripts/Library/CameraBehaviour/CameraStatic.cs
@@ -1,3 +1,3 @@
 using UnityEngine;
 
-public class CameraStatic : CameraBehaviour {}
\ No newline at end of file
+public class CameraStatic : CameraBehaviour {}
diff --git a/Assets/Scripts/Library/DataTypes/DifficultyData.cs b/Assets/Scripts/Library/DataTypes/DifficultyData.cs
index 98f93776ddcca9c84ccc8d09f5430088b079b2ee..a08615d65ef1bfa7bdf8e511a29a8e1baf2a0103 100644
--- a/Assets/Scripts/Library/DataTypes/DifficultyData.cs
+++ b/Assets/Scripts/Library/DataTypes/DifficultyData.cs
@@ -3,4 +3,4 @@ public class DifficultyData{
     public float EnemyDamageMultiplier { get; set; }
     public float PlayerHealthMultiplier { get; set; }
     public float PlayerDamageMultiplier { get; set; }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/Enum/CameraBehaviourType.cs b/Assets/Scripts/Library/Enum/CameraBehaviourType.cs
index ca9c21f9f59fbc51445e72bfa6c038700d12ee1f..f8c1d945ab3e72cb6ab4e1a75e01223d2ab1585e 100644
--- a/Assets/Scripts/Library/Enum/CameraBehaviourType.cs
+++ b/Assets/Scripts/Library/Enum/CameraBehaviourType.cs
@@ -2,4 +2,4 @@ public enum CameraBehaviourType{
     NULL,
     STATIC,
     FOLLOW
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/Enum/DifficultyType.cs b/Assets/Scripts/Library/Enum/DifficultyType.cs
index b6759584f31357e4695194440f1f8be985beec17..fe61e48f5e68c1e29582008554f09f72841e5c73 100644
--- a/Assets/Scripts/Library/Enum/DifficultyType.cs
+++ b/Assets/Scripts/Library/Enum/DifficultyType.cs
@@ -2,4 +2,4 @@ public enum DifficultyType{
     EASY,
     NORMAL,
     HARD
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/Enum/EntityState.cs b/Assets/Scripts/Library/Enum/EntityState.cs
index fca3022c2140777060662545bc35f2cd3fa7b384..bb503d3312121e0fe37f7f7809cdaceee4c660c4 100644
--- a/Assets/Scripts/Library/Enum/EntityState.cs
+++ b/Assets/Scripts/Library/Enum/EntityState.cs
@@ -3,7 +3,4 @@ public class EntityState {
     public const int IDLE = 1;
     public const int WALKING = 2;
     public const int SPRINTING = 4;
-    public const int JUMPING = 8;
-    public const int FALLING = 16;
 }
-
diff --git a/Assets/Scripts/Library/Enum/GameEventType.cs b/Assets/Scripts/Library/Enum/GameEventType.cs
index 0252b7bbb00221078e577a370aa9d7cd95f4907d..3c20968a882131224d2c076737a2ee15838246b4 100644
--- a/Assets/Scripts/Library/Enum/GameEventType.cs
+++ b/Assets/Scripts/Library/Enum/GameEventType.cs
@@ -1,3 +1,3 @@
 public enum GameEventType{
     CHEAT
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/Enum/GameState.cs b/Assets/Scripts/Library/Enum/GameState.cs
index 0914c54b19607d0bcc7721050d570d344ee4e065..c4de8375045c1139a65d923f50a4d2c5bb1c8b70 100644
--- a/Assets/Scripts/Library/Enum/GameState.cs
+++ b/Assets/Scripts/Library/Enum/GameState.cs
@@ -5,4 +5,3 @@ public enum GameState {
     CUTSCENE,
     PAUSED
 }
-
diff --git a/Assets/Scripts/Library/Enum/StackChangeEventType.cs b/Assets/Scripts/Library/Enum/StackChangeEventType.cs
index 885d3c0b363c64bc3051c4f85cb755e7dccc3496..97aa2a78650342af6464f82137c1f8ef312c48a8 100644
--- a/Assets/Scripts/Library/Enum/StackChangeEventType.cs
+++ b/Assets/Scripts/Library/Enum/StackChangeEventType.cs
@@ -1,4 +1,4 @@
 public enum StackChangeEventType{
     PUSH,
     POP
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/Events/GameEvent.cs b/Assets/Scripts/Library/Events/GameEvent.cs
index 10086a8312a185ea231372911cb5b2582a1cdae0..18321f6cf04ded4ce82e77e2bcc7d86b40d01d9b 100644
--- a/Assets/Scripts/Library/Events/GameEvent.cs
+++ b/Assets/Scripts/Library/Events/GameEvent.cs
@@ -7,4 +7,4 @@ public class GameEventArgs : EventArgs{
     }
 }
 
-public delegate void GameEvent(GameEventArgs e);
\ No newline at end of file
+public delegate void GameEvent(GameEventArgs e);
diff --git a/Assets/Scripts/Library/Events/GameStateChangeEvent.cs b/Assets/Scripts/Library/Events/GameStateChangeEvent.cs
index ead0a904f4aea0bab54caa7cd432ee49e2d02182..a485da400892fe153f96e32e319c0452608b6d06 100644
--- a/Assets/Scripts/Library/Events/GameStateChangeEvent.cs
+++ b/Assets/Scripts/Library/Events/GameStateChangeEvent.cs
@@ -1,5 +1,6 @@
 
 public class GameStateChangeArgs : StackChangeEventArgs<GameState>{
-    public GameStateChangeArgs(StackChangeEventType eventType, int index, GameState value) : base(eventType, index, value){}
+    public GameState NewGameState => Value;
+    public GameStateChangeArgs(StackChangeEventType eventType, int index, GameState NewGameState) : base(eventType, index, NewGameState){}
 }
-public delegate void GameStateChangeEvent(GameStateChangeArgs e);
\ No newline at end of file
+public delegate void GameStateChangeEvent(GameStateChangeArgs e);
diff --git a/Assets/Scripts/Library/Events/StackChangeEvent.cs b/Assets/Scripts/Library/Events/StackChangeEvent.cs
index acab93193d549c251381d9354592616cefa1a45b..e0a968d6e3fa9ea6ff3b7a762d394fa5f6e32685 100644
--- a/Assets/Scripts/Library/Events/StackChangeEvent.cs
+++ b/Assets/Scripts/Library/Events/StackChangeEvent.cs
@@ -12,4 +12,4 @@ public class StackChangeEventArgs<T> : EventArgs{
     }
 }
 
-public delegate void StackChangeEvent<T>(StackChangeEventArgs<T> e);
\ No newline at end of file
+public delegate void StackChangeEvent<T>(StackChangeEventArgs<T> e);
diff --git a/Assets/Scripts/Library/Interfaces/IAccompanied.cs b/Assets/Scripts/Library/Interfaces/IAccompanied.cs
new file mode 100644
index 0000000000000000000000000000000000000000..826e646834e0fcf67cdf32949b41ab668b1a5e70
--- /dev/null
+++ b/Assets/Scripts/Library/Interfaces/IAccompanied.cs
@@ -0,0 +1,5 @@
+using System.Collections.Generic;
+
+public interface IAccompaniable{
+    public List<Companions> Companions { get; }
+}
diff --git a/Assets/Scripts/Library/Interfaces/IAccompanied.cs.meta b/Assets/Scripts/Library/Interfaces/IAccompanied.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..b4fc086ee3ac7d4733d8e4a49dff992e61396ebc
--- /dev/null
+++ b/Assets/Scripts/Library/Interfaces/IAccompanied.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5cdf14b558c905544aa05b347efb17d1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Library/Interfaces/IArmed.cs b/Assets/Scripts/Library/Interfaces/IArmed.cs
index 2c12e113091dd3ebd9c45920e3d8e63056d42fab..da5d4b8a7a53a0458e72b42d4afe4b157c8bcaee 100644
--- a/Assets/Scripts/Library/Interfaces/IArmed.cs
+++ b/Assets/Scripts/Library/Interfaces/IArmed.cs
@@ -1,4 +1,4 @@
 public interface IArmed{
     public float BaseDamage { get; set; }
     public WeaponObject Weapon { get; set; }
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/Interfaces/ICutscene.cs b/Assets/Scripts/Library/Interfaces/ICutscene.cs
index f1d4b8d81dc96f76087c6ff18283040ee0db6af6..d6ee87039dd44e006eed4c5f40b3f1a30440d74c 100644
--- a/Assets/Scripts/Library/Interfaces/ICutscene.cs
+++ b/Assets/Scripts/Library/Interfaces/ICutscene.cs
@@ -1,3 +1,3 @@
 public interface ICutscene{
     public void Skip();
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/Interfaces/IDamageable.cs b/Assets/Scripts/Library/Interfaces/IDamageable.cs
index e1f071473b9840cdbc0f9d3c303ac666aaf313f5..88d0696d4e29bdbb59b652bd14bedbf8299520db 100644
--- a/Assets/Scripts/Library/Interfaces/IDamageable.cs
+++ b/Assets/Scripts/Library/Interfaces/IDamageable.cs
@@ -6,9 +6,9 @@ public interface IDamageable{
     bool Damageable {get;}
     bool Dead {get;}
 
-    event Action OnDeath;
-    event Action OnDamaged;
-    event Action OnHeal;
+    event Action OnDeathEvent;
+    event Action OnDamagedEvent;
+    event Action OnHealEvent;
 
     float InflictDamage(float damage);
     float InflictHeal(float heal);
diff --git a/Assets/Scripts/Library/Interfaces/IDamaging.cs b/Assets/Scripts/Library/Interfaces/IDamaging.cs
index 0ac5ec0bd58abbc2db6bb447184dab2a64eeb99c..5b11e94d07b9b383d077d6f15f831bad21134d26 100644
--- a/Assets/Scripts/Library/Interfaces/IDamaging.cs
+++ b/Assets/Scripts/Library/Interfaces/IDamaging.cs
@@ -2,5 +2,5 @@ using System;
 
 public interface IDamaging{
     float Damage{get; set;}
-    event Action OnDamage;
+    event Action OnDamageEvent;
 }
diff --git a/Assets/Scripts/Library/Interfaces/IMenu.cs b/Assets/Scripts/Library/Interfaces/IMenu.cs
index 1ed68e7a26f2f3b42f2aaffcb8cba524925b3826..a03457e55d4b6289739b229adb089fcc0b751458 100644
--- a/Assets/Scripts/Library/Interfaces/IMenu.cs
+++ b/Assets/Scripts/Library/Interfaces/IMenu.cs
@@ -1,3 +1,3 @@
 public interface IMenu{
     public void Close();
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/Library/Interfaces/IRigid.cs b/Assets/Scripts/Library/Interfaces/IRigid.cs
index d06a4a072b7703c80928edd32ae6bece9aa641cc..7b092eb92728ddd98c92591458b915ec967bedf3 100644
--- a/Assets/Scripts/Library/Interfaces/IRigid.cs
+++ b/Assets/Scripts/Library/Interfaces/IRigid.cs
@@ -6,5 +6,6 @@ public interface IRigid{
     public Rigidbody Rigidbody {get;}
     public Collider Collider {get;}
     public Vector3 Position {get;}
+    public float BaseSpeed {get; set;}
     public float KnockbackResistance {get; set;}
 }
diff --git a/Assets/Scripts/Library/Util/MathUtil.cs b/Assets/Scripts/Library/Util/MathUtil.cs
index eaf1b1f573d8c10622ad6ef0353e53604e27186f..ac69919f17c83622b76d721ccfbcbc26f77573ab 100644
--- a/Assets/Scripts/Library/Util/MathUtil.cs
+++ b/Assets/Scripts/Library/Util/MathUtil.cs
@@ -5,4 +5,9 @@ public static class MathUtils{
         Vector3 direction = origin - target;
         return direction.normalized;
     }
-}
\ No newline at end of file
+
+    // TODO: Tweak, add an interesting equation, maybe?
+    public static float CalculateDamage(float characterDamageStat, float weaponDamageStat){
+        return characterDamageStat + weaponDamageStat;
+    }
+}
diff --git a/Assets/Scripts/Library/Util/ObjectFactory.cs b/Assets/Scripts/Library/Util/ObjectFactory.cs
index 6c8c5ff917b8d739d831d1aaed62dea7f49e1971..a12733365f91cdf07f780164d307e5dc852fc8fc 100644
--- a/Assets/Scripts/Library/Util/ObjectFactory.cs
+++ b/Assets/Scripts/Library/Util/ObjectFactory.cs
@@ -1,3 +1,3 @@
 public static class ObjectFactory{
     
-}
\ No newline at end of file
+}
diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset
index 0c2d7425921fe9554fbbc43f7009c554975430a6..0199396828b5070929fda6c7119e67c923f042aa 100644
--- a/ProjectSettings/TagManager.asset
+++ b/ProjectSettings/TagManager.asset
@@ -4,8 +4,7 @@
 TagManager:
   serializedVersion: 2
   tags:
-  - Weapon
-  - Model
+  - Ground
   - Enemy
   - Collectibles
   layers: