diff --git a/AlterraWeaponry/AlterraWeaponry.csproj b/AlterraWeaponry/AlterraWeaponry.csproj
index 3f77afd..41cc3c3 100644
--- a/AlterraWeaponry/AlterraWeaponry.csproj
+++ b/AlterraWeaponry/AlterraWeaponry.csproj
@@ -35,17 +35,17 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'BZ|AnyCPU' ">
     <OutputPath>bin\BZ\</OutputPath>
     <PlatformTarget>AnyCPU</PlatformTarget>
+    <DefineConstants>BZ; BELOWZERO; BELOW_ZERO;</DefineConstants>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'SN1|AnyCPU' ">
     <OutputPath>bin\SN1\</OutputPath>
+    <DefineConstants>SN1; SN; SUBNAUTICA;</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="0Harmony">
       <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\BepInEx\core\0Harmony.dll</HintPath>
     </Reference>
-    <Reference Include="Assembly-CSharp">
-      <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\Assembly-CSharp.dll</HintPath>
-    </Reference>
     <Reference Include="Assembly-CSharp-firstpass">
       <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
     </Reference>
@@ -55,20 +55,29 @@
     <Reference Include="BepInEx">
       <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\BepInEx\core\BepInEx.dll</HintPath>
     </Reference>
+    <Reference Include="CuddleLibs">
+      <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\BepInEx\plugins\CuddleLibs\CuddleLibs.dll</HintPath>
+    </Reference>
     <Reference Include="FMODUnity">
       <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\FMODUnity.dll</HintPath>
     </Reference>
-    <Reference Include="SMLHelper">
-      <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\QMods\SMLHelper_BZ\SMLHelper.dll</HintPath>
+    <Reference Include="Nautilus">
+      <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\BepInEx\plugins\Nautilus\Nautilus.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.IO.Compression" />
+    <Reference Include="System.IO.Compression.FileSystem" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Net.Http" />
     <Reference Include="System.Xml" />
+    <Reference Include="Unity.Addressables, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\Unity.Addressables.dll</HintPath>
+    </Reference>
     <Reference Include="Unity.TextMeshPro">
       <HintPath>B:\SteamLibrary\steamapps\common\SubnauticaZero\SubnauticaZero_Data\Managed\Unity.TextMeshPro.dll</HintPath>
     </Reference>
@@ -103,39 +112,32 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="behaviours\CustomTriggerEventAssigner.cs" />
-    <Compile Include="behaviours\ZapFunctionalityBehaviour.cs" />
-    <Compile Include="items\PrawnSelfDefenseModule.cs" />
-    <Compile Include="patches\ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs" />
-    <Compile Include="patches\GameSettings_SaveAsync_Patch.cs" />
-    <Compile Include="patches\SeamothTorpedo_OnEnergyDepleted_Patch.cs" />
-    <Compile Include="patches\Vehicle_ChargeModule_Patch.cs" />
-    <Compile Include="patches\Vehicle_GetSlotCharge_Patch.cs" />
-    <Compile Include="patches\Vehicle_OnUpgradeModuleChange_Patch.cs" />
-    <Compile Include="patches\Vehicle_OnUpgradeModuleUse_Patch.cs" />
-    <Compile Include="utils\ExplosiveTorpedoInitializer.cs" />
-    <Compile Include="behaviours\TorpedoExplosionBehaviour.cs" />
+    <Compile Include="Behaviours\CustomTriggerEventAssigner.cs" />
+    <Compile Include="Behaviours\ZapFunctionalityBehaviour.cs" />
+    <Compile Include="Items\PrawnSelfDefenseModule.cs" />
+    <Compile Include="Patches\ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs" />
+    <Compile Include="Patches\SeamothTorpedo_OnEnergyDepleted_Patch.cs" />
+    <Compile Include="Utils\ExplosiveTorpedoInitializer.cs" />
+    <Compile Include="Behaviours\TorpedoExplosionBehaviour.cs" />
     <Compile Include="Global.cs" />
-    <Compile Include="items\BlackPowder.cs" />
-    <Compile Include="items\Coal.cs" />
-    <Compile Include="items\ExplosiveTorpedo.cs" />
+    <Compile Include="Items\BlackPowder.cs" />
+    <Compile Include="Items\Coal.cs" />
+    <Compile Include="Items\ExplosiveTorpedo.cs" />
     <Compile Include="Main.cs" />
-    <Compile Include="patches\ItemGoalTracker_Start_Patch.cs" />
-    <Compile Include="patches\uGUISceneLoading_End_Patch.cs" />
-    <Compile Include="patches\Vehicle_Awake_Patch.cs" />
+    <Compile Include="Patches\ItemGoalTracker_Start_Patch.cs" />
+    <Compile Include="Patches\uGUISceneLoading_End_Patch.cs" />
+    <Compile Include="Patches\Vehicle_Awake_Patch.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="utils\LanguagesHandler.cs" />
+    <Compile Include="Utils\GlobalInitializer.cs" />
+    <Compile Include="Utils\LanguagesHandler.cs" />
+    <Compile Include="Utils\Options.cs" />
+    <Compile Include="Utils\ResourcesCacheManager.cs" />
   </ItemGroup>
   <ItemGroup />
   <ItemGroup>
-    <Content Include="assets\Coal.png" />
-    <Content Include="assets\ExplosiveTorpedo.png" />
-    <Content Include="assets\first_lethal_weapon_message.mp3" />
-    <Content Include="assets\first_lethal_weapon_message.ogg" />
-    <Content Include="assets\PrawnPerimeterDefense.png" />
-    <Content Include="assets\prawn_shield.png" />
-    <Content Include="assets\xenoworx_pda_presentation.mp3" />
     <Content Include="Localizations.xml" />
+    <None Include="Sounds\AudioClip.FirstLethalMessage.wav" />
+    <None Include="Sounds\AudioClip.PWAPresentation.wav" />
   </ItemGroup>
   <ItemGroup>
     <None Include="mod.json" />
@@ -145,6 +147,7 @@
     <PostBuildEvent>mkdir "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry"
 copy /Y "$(TargetPath)" "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry\"
 copy /Y "$(ProjectDir)\alterraweaponry.assets" "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry\"
+copy /Y "$(ProjectDir)\alterraweaponry.assets.meta" "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry\"
 copy /Y "$(ProjectDir)\Localizations.xml" "$(SubnauticaRootPath)\BepInEx\plugins\AlterraWeaponry\"</PostBuildEvent>
   </PropertyGroup>
 </Project>
\ No newline at end of file
diff --git a/AlterraWeaponry/Global.cs b/AlterraWeaponry/Global.cs
index f31dbb0..e76c13a 100644
--- a/AlterraWeaponry/Global.cs
+++ b/AlterraWeaponry/Global.cs
@@ -15,22 +15,24 @@
 global using BepInEx.Bootstrap;
 global using BepInEx.Configuration;
 global using BepInEx.Logging;
-global using SMLHelper.V2.Assets;
-global using SMLHelper.V2.Commands;
-global using SMLHelper.V2.Crafting;
-global using SMLHelper.V2.FMod;
-global using SMLHelper.V2.FMod.Interfaces;
-global using SMLHelper.V2.Interfaces;
-global using SMLHelper.V2.Json;
-global using SMLHelper.V2.Json.Attributes;
-global using SMLHelper.V2.Json.Converters;
-global using SMLHelper.V2.Json.ExtensionMethods;
-global using SMLHelper.V2.Json.Interfaces;
-global using SMLHelper.V2.Handlers;
-global using SMLHelper.V2.MonoBehaviours;
-global using SMLHelper.V2.Options;
-global using SMLHelper.V2.Options.Attributes;
-global using SMLHelper.V2.Utility;
+global using Nautilus.Assets;
+global using Nautilus.Assets.Gadgets;
+global using Nautilus.Assets.PrefabTemplates;
+global using Nautilus.Commands;
+global using Nautilus.Crafting;
+global using Nautilus.Extensions;
+global using Nautilus.FMod;
+global using Nautilus.FMod.Interfaces;
+global using Nautilus.Handlers;
+global using Nautilus.Json;
+global using Nautilus.Json.Attributes;
+global using Nautilus.Json.Converters;
+global using Nautilus.Json.ExtensionMethods;
+global using Nautilus.Json.Interfaces;
+global using Nautilus.Options;
+global using Nautilus.Options.Attributes;
+global using Nautilus.Utility;
+global using Nautilus.Utility.MaterialModifiers;
 global using HarmonyLib;
 global using HarmonyLib.Public;
 global using HarmonyLib.Public.Patching;
@@ -44,9 +46,17 @@
 global using UWE;
 global using UWE.Timeline;
 global using UWEScript;
+global using FMOD;
 
 // LOCAL
-global using VELD.AlterraWeaponry.items;
-global using VELD.AlterraWeaponry.patches;
-global using VELD.AlterraWeaponry.utils;
-global using VELD.AlterraWeaponry.behaviours;
\ No newline at end of file
+global using VELD.AlterraWeaponry.Items;
+global using VELD.AlterraWeaponry.Patches;
+global using VELD.AlterraWeaponry.Utils;
+global using VELD.AlterraWeaponry.Behaviours;
+
+// MY LIBS
+global using CuddleLibs;
+global using CuddleLibs.Assets;
+global using CuddleLibs.Assets.Gadgets;
+global using CuddleLibs.Interfaces;
+global using CuddleLibs.Utility;
\ No newline at end of file
diff --git a/AlterraWeaponry/Localizations.xml b/AlterraWeaponry/Localizations.xml
index 31f34ac..bc9ee12 100644
Binary files a/AlterraWeaponry/Localizations.xml and b/AlterraWeaponry/Localizations.xml differ
diff --git a/AlterraWeaponry/Main.cs b/AlterraWeaponry/Main.cs
index adc4003..3dbce59 100644
--- a/AlterraWeaponry/Main.cs
+++ b/AlterraWeaponry/Main.cs
@@ -4,149 +4,68 @@
 public class Main : BaseUnityPlugin
 {
     // MOD INFO
-    private const string modName = "Alterra Weaponry";
-    private const string modGUID = "com.VELD.AlterraWeaponry";
-    private const string modVers = "1.0.3";
+    internal const string modName = "Alterra Weaponry";
+    internal const string modGUID = "com.VELD.AlterraWeaponry";
+    internal const string modVers = "1.0.5";
+    internal const string modLongVers = "1.0.5.1";
 
     // BepInEx/Harmony/Unity
     private static readonly Harmony harmony = new(modGUID);
     public static ManualLogSource logger;
 
     // STORY GOALS
-#if BZ
-    internal static StoryGoal AWPresentationGoal = new("Log_PDA_Goal_AWPresentation", Story.GoalType.PDA, 0f) { playInCreative = true, playInCinematics = false, delay = 8f };
-#endif
+    internal static StoryGoal AWPresentationGoal;
+    internal static ItemGoal AWFirstLethal;
 
-    public static readonly AssetBundle assets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "alterraweaponry.assets"));
+    public static ResourcesCacheManager AssetsCache { get; private set; }
 
+    internal static Options Options { get; } = OptionsPanelHandler.RegisterModOptions<Options>();
 
     private void Awake()
     {
         logger = Logger;
+        try
+        {
+            AssetsCache = ResourcesCacheManager.LoadResources(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "alterraweaponry.assets"));
+        }
+        catch (Exception ex)
+        {
+            logger.LogFatal($"Fatal error occured: Unable to load resources to cache.\n{ex}");
+        }
         logger.LogInfo($"{modName} {modVers} started patching.");
         harmony.PatchAll();
         logger.LogInfo($"{modName} {modVers} harmony patched.");
-
-        Coal coal = new();
-        BlackPowder blackPowder = new();
-        ExplosiveTorpedo explosiveTorpedo = new();
-        PrawnSelfDefenseModule prawnSelfDefenseModule = new();
-
-        coal.Patch();
-        blackPowder.Patch();
-        explosiveTorpedo.Patch();
-        prawnSelfDefenseModule.Patch();
-
-        logger.LogInfo($"{modName} {modVers} items registered.");
-
-        LanguagesHandler.LanguagePatch();
+        LanguagesHandler.GlobalPatch();
         logger.LogInfo($"{modName} {modVers} languages lines patched.");
-
-        RegisterPDAEncyEntries();
+        GlobalInitializer.PatchPDAEncyEntries();
         logger.LogInfo($"{modName} {modVers} PDA encyclopedia entries registered.");
-        RegisterPDALogs();
+        GlobalInitializer.PatchGoals();
+        logger.LogInfo($"{modName} {modVers} PDA goals initialized.");
+        GlobalInitializer.PatchPDALogs();
         logger.LogInfo($"{modName} {modVers} PDA logs registered.");
 
-    }
-
-    private void Update()
-    {
-        if(UnityInput.Current.GetKeyDown(KeyCode.P))
+        ModDatabankHandler.RegisterMod(new ModDatabankHandler.ModData()
         {
-            logger.LogInfo("Should play audio.");
-            GameObject cameraObject = Camera.main.gameObject;
-            AudioSource audioSource = cameraObject.GetComponent<AudioSource>();
-            audioSource.clip = Main.assets.LoadAsset<AudioClip>("AudioClip.PWAPresentation");
-            audioSource.Play();
-            logger.LogInfo("Should have played an audio.");
-        }
-    }
-
-    private static void RegisterPDALogs()
-    {
-        // Load audio clips
-        logger.LogInfo($"{modName} {modVers} Loading audio clips...");
-#if BZ
-        AudioClip AWPresentationAudioClip = assets.LoadAsset<AudioClip>("pwa_presentation_message");
-        AudioClip AWFirstLethalAudioClip = assets.LoadAsset<AudioClip>("first_lethal_message");
-#endif
-        logger.LogInfo($"{modName} {modVers} Audio clips loaded!");
-
-        logger.LogInfo($"{modName} {modVers} Registering PDA Logs...");
-
-        // Presentation PDA log "Hello xenoworker 91802..."
-#if BZ
-        CustomSoundHandler.RegisterCustomSound(AWPresentationGoal.key, AWPresentationAudioClip, AudioUtils.BusPaths.PDAVoice);
-        FMODAsset presentation = ScriptableObject.CreateInstance<FMODAsset>();
-        presentation.path = AWPresentationGoal.key;
-        presentation.id = AWPresentationGoal.key;
-        PDALogHandler.AddCustomEntry(
-            AWPresentationGoal.key,
-            "Subtitles_AWPresentation",
-            sound: presentation
-        );
-#endif
+            guid = modGUID,
+            version = modVers,
+            image = AssetsCache.GetAsset<Texture2D>("ModLogo"),
+            name = "Alterra Weaponry",
+            desc = "Since the return of the Aurora survivor, Alterra secretely added a few weapons blueprints.\nThis information is kept confidential, by using the PWA (Personal Weaponry Assistance) you agree the Alterra's NDA (Non-Divulgation Accord)."
+        });
 
-// First lethal weapon PDA log "A lethal weapon have been detected into your inventory..."
-#if BZ
-        CustomSoundHandler.RegisterCustomSound("Log_PDA_Goal_FirstLethal", AWFirstLethalAudioClip, AudioUtils.BusPaths.PDAVoice);
-        FMODAsset firstLethal = ScriptableObject.CreateInstance<FMODAsset>();
-        firstLethal.path = "Log_PDA_Goal_FirstLethal";
-        firstLethal.id = "Log_PDA_Goal_FirstLethal";
-        PDALogHandler.AddCustomEntry(
-            "Log_PDA_Goal_FirstLethal",
-            "Subtitles_AWFirstLethal",
-            sound: firstLethal
-        );
-#endif
-    }
+        Coal coal = new();
+        coal.Patch();
 
-    private static void RegisterPDAEncyEntries()
-    {
-        // Register AWModInfo entry
-        PDAEncyclopediaHandler.AddCustomEntry(new()
-        {
-            key = "AWModInfo",
-            kind = PDAEncyclopedia.EntryData.Kind.Encyclopedia,
-            nodes = new[] { "Meta" },
-            path = "Meta",
-            unlocked = true,
-        });
+        BlackPowder blackPowder = new();
+        blackPowder.Patch();
 
-        // Explosive torpedoes entry
-#if BZ
-        PDAEncyclopediaHandler.AddCustomEntry(new()
-        {
-            key = "ExplosiveTorpedo",
-            kind = PDAEncyclopedia.EntryData.Kind.Encyclopedia,
-            nodes = new[] { "Tech", "Weaponry" },
-            path = "Tech/Weaponry",
-            unlocked = false,
-        });
-#endif
+        ExplosiveTorpedo explosiveTorpedo = new();
+        explosiveTorpedo.Patch();
 
-        // Prawn laser arm entry
-#if BZ
-        PDAEncyclopediaHandler.AddCustomEntry(new()
-        {
-            key = "PrawnLaserArm",
-            kind = PDAEncyclopedia.EntryData.Kind.Encyclopedia,
-            nodes = new[] { "Tech", "Weaponry" },
-            path = "Tech/Weaponry",
-            unlocked = false,
-        });
-#endif
+        PrawnSelfDefenseModule prawnSelfDefenseModule = new();
+        prawnSelfDefenseModule.Patch();
 
-        // Prawn Self Defense Module
-#if BZ
-        PDAEncyclopediaHandler.AddCustomEntry(new()
-        {
-            key = "PrawnDefensePerimeter",
-            kind = PDAEncyclopedia.EntryData.Kind.Encyclopedia,
-            nodes = new[] { "Tech", "Modules" },
-            path = "Tech/Modules",
-            unlocked = false,
-        });
-#endif
+        logger.LogInfo($"{modName} {modVers} items registered.");
     }
+
 }
diff --git a/AlterraWeaponry/Properties/AssemblyInfo.cs b/AlterraWeaponry/Properties/AssemblyInfo.cs
index df41b7f..ad51016 100644
--- a/AlterraWeaponry/Properties/AssemblyInfo.cs
+++ b/AlterraWeaponry/Properties/AssemblyInfo.cs
@@ -1,7 +1,6 @@
 using System.Resources;
-using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
+using VELD.AlterraWeaponry;
 
 // General Information about an assembly is controlled through the following
 // set of attributes. Change these attribute values to modify the information
@@ -33,6 +32,6 @@
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.3.0")]
-[assembly: AssemblyFileVersion("1.0.3.0")]
+[assembly: AssemblyVersion(Main.modVers)]
+[assembly: AssemblyFileVersion(Main.modLongVers)]
 [assembly: NeutralResourcesLanguage("en")]
diff --git a/AlterraWeaponry/Sounds/AudioClip.FirstLethalMessage.wav b/AlterraWeaponry/Sounds/AudioClip.FirstLethalMessage.wav
new file mode 100644
index 0000000..d5bd667
Binary files /dev/null and b/AlterraWeaponry/Sounds/AudioClip.FirstLethalMessage.wav differ
diff --git a/AlterraWeaponry/Sounds/AudioClip.PWAPresentation.wav b/AlterraWeaponry/Sounds/AudioClip.PWAPresentation.wav
new file mode 100644
index 0000000..419fe2b
Binary files /dev/null and b/AlterraWeaponry/Sounds/AudioClip.PWAPresentation.wav differ
diff --git a/AlterraWeaponry/Sounds/AudioClip.UnderwaterExplosionFX.ogg b/AlterraWeaponry/Sounds/AudioClip.UnderwaterExplosionFX.ogg
new file mode 100644
index 0000000..eed8eed
Binary files /dev/null and b/AlterraWeaponry/Sounds/AudioClip.UnderwaterExplosionFX.ogg differ
diff --git a/AlterraWeaponry/Utils/ResourcesCacheManager.cs b/AlterraWeaponry/Utils/ResourcesCacheManager.cs
new file mode 100644
index 0000000..8847658
--- /dev/null
+++ b/AlterraWeaponry/Utils/ResourcesCacheManager.cs
@@ -0,0 +1,213 @@
+namespace VELD.AlterraWeaponry.Utils;
+
+public class ResourcesCacheManager
+{
+    private static readonly List<string> ResourcesNames = new()
+    {
+        "AudioClip.FirstLethalMessage",
+        "AudioClip.PWAPresentation",
+        "GameObject.BlackPowder",
+        "GameObject.CustomEventTrigger",
+        "Material.BlackPowder",
+        "Mesh.BlackPowder",
+        "Sprite.BlackPowder",
+        "Sprite.Coal",
+        "Sprite.ExplosiveTorpedo",
+        "Sprite.PrawnSelfDefenseModule",
+        "Sprite.PrawnShieldModule",
+        "Sprite.UpgradePopup",
+        "Texture2D.BlackPowder",
+        "Texture2D.BlackPowder_normal",
+        "Texture2D.BlackPowder_spec",
+        "Texture2D.Coal",
+        "Texture2D.Coal_illum",
+        "Texture2D.Coal_normals",
+        "Texture2D.Coal_spec",
+        "Texture2D.ModLogo"
+    };
+
+    private static readonly Dictionary<string, string[]> ResourcesPaths = new()
+    {
+        { "AudioClip", new[] { "AudioClips" } },
+        { "GameObject", new[] { "GameObjects" } },
+        { "Material", new[] { "Materials" } },
+        { "Mesh", new[] { "Meshes" } },
+        { "Sprite", new[] { "Sprites" } },
+        { "Texture2D", new[] { "Textures2D" } }
+    };
+
+    public static UnityEngine.Object[] RawResources;
+
+    public Dictionary<string, AudioClip> CachedAudioClips { get; private set; } = new();
+    public Dictionary<string, GameObject> CachedPrefabs { get; private set; } = new();
+    public Dictionary<string, Material> CachedMaterials { get; private set; } = new();
+    public Dictionary<string, Mesh> CachedMeshes { get; private set; } = new();
+    public Dictionary<string, Sprite> CachedSprites { get; private set; } = new();
+    public Dictionary<string, Texture2D> CachedTextures { get; private set; } = new();
+    public ResourcesCacheManager() { }
+
+    public static ResourcesCacheManager LoadResources(string path)
+    {
+        Main.logger.LogInfo("Loading assetbundle...");
+        var bundle = AssetBundle.LoadFromFile(path) ?? throw new IOException($"Provided path '{path}' does not contain any assetbundle.");
+        RawResources = bundle.LoadAllAssets();
+        var rm = new ResourcesCacheManager();
+
+        Main.logger.LogInfo("Loaded bundle, encaching...");
+
+        foreach (string resName in ResourcesNames)
+        {
+            Main.logger.LogInfo($"Trying to encache asset {resName}...");
+            var assetName = resName.Split('.').Last();
+            var assetType = resName.Split('.').First();
+            try
+            {
+                UnityEngine.Object asset;
+                switch(true)
+                {
+                    case true when assetType == "AudioClip":
+                        asset = bundle.LoadAsset<AudioClip>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle.");
+                        rm.CachedAudioClips.Add(assetName, asset as AudioClip);
+                        Main.logger.LogInfo($"Added {resName} to rm.CachedAudioClips.");
+                    break;
+                    case true when assetType == "GameObject" || assetType == "Prefab":
+                        asset = bundle.LoadAsset<GameObject>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle.");
+                        rm.CachedPrefabs.Add(assetName, asset as GameObject);
+                        Main.logger.LogInfo($"Added {resName} to rm.CachedPrefabs.");
+                        break;
+                    case true when assetType == "Material":
+                        asset = bundle.LoadAsset<Material>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle.");
+                        rm.CachedMaterials.Add(assetName, asset as Material);
+                        Main.logger.LogInfo($"Added {resName} to rm.CachedMaterials.");
+                        break;
+                    case true when assetType == "Mesh":
+                        asset = bundle.LoadAsset<Mesh>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle.");
+                        rm.CachedMeshes.Add(assetName, asset as Mesh);
+                        Main.logger.LogInfo($"Added {resName} to rm.CachedMeshes.");
+                        break;
+                    case true when assetType == "Sprite":
+                        asset = bundle.LoadAsset<Sprite>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle.");
+                        rm.CachedSprites.Add(assetName, asset as Sprite);
+                        Main.logger.LogInfo($"Added {resName} to rm.CachedSprites.");
+                        break;
+                    case true when assetType == "Texture2D":
+                        asset = bundle.LoadAsset<Texture2D>(resName) ?? throw new KeyNotFoundException($"No resource with name {resName} exists as a {assetType} in the asset bundle.");
+                        rm.CachedTextures.Add(assetName, asset as Texture2D);
+                        Main.logger.LogInfo($"Added {resName} to rm.CachedTextures.");
+                        break;
+                    default:
+                        throw new Exception("The type of the asset is incorrect.");
+                }
+                Main.logger.LogInfo($"Encached {resName} to key {assetName} and in {assetType}'s cache.");
+            }
+            catch(Exception ex)
+            {
+                Main.logger.LogFatal($"A fatal error has ocurred when loading the resources.\n{ex}");
+            }
+        }
+        var str = new StringBuilder();
+        str.AppendLine("RESOURCES CACHE MANAGER: CACHED CONTENTS:");
+        str.AppendLine(" ");
+        str.AppendLine("rm.CachedAudioClips = [");
+        foreach(var asset in rm.CachedAudioClips)
+            str.AppendLine($"\t{asset}");
+        str.AppendLine("]");
+        str.AppendLine(" ");
+        str.AppendLine("rm.CachedPrefabs = [");
+        foreach(var asset in rm.CachedPrefabs)
+            str.AppendLine($"\t{asset}");
+        str.AppendLine("]");
+        str.AppendLine(" ");
+        str.AppendLine("rm.CachedMaterials = [");
+        foreach (var asset in rm.CachedMaterials)
+            str.AppendLine($"\t{asset}");
+        str.AppendLine("]");
+        str.AppendLine(" ");
+        str.AppendLine("rm.CachedMeshes = [");
+        foreach (var asset in rm.CachedMeshes)
+            str.AppendLine($"\t{asset}");
+        str.AppendLine("]");
+        str.AppendLine(" ");
+        str.AppendLine("rm.CachedSprites = [");
+        foreach (var asset in rm.CachedSprites)
+            str.AppendLine($"\t{asset}");
+        str.AppendLine("]");
+        str.AppendLine(" ");
+        str.AppendLine("rm.CachedTextures = [");
+        foreach (var asset in rm.CachedTextures)
+            str.AppendLine($"\t{asset}");
+        str.AppendLine("]");
+        str.AppendLine(" ");
+        Main.logger.LogDebug(str.ToString());
+        Main.logger.LogInfo("Encached all assets.");
+        return rm;
+    }
+
+    /// <summary>
+    /// Gets a resource in the AssetsCache cache.
+    /// <para>You better use <see cref="TryGetAsset{T}(string, out T)"/>.</para>
+    /// </summary>
+    /// <typeparam name="T">Type of the item to find.</typeparam>
+    /// <param name="name">Name of the asset to find.</param>
+    /// <returns>A reference to the instance of the asset, or an error if nothing have been found.</returns>
+    /// <exception cref="ArgumentException">If the provided type is not a valid UnityEngine.Object or is not supported.</exception>
+    public T GetAsset<T>(string name) where T : UnityEngine.Object
+    {
+        Main.logger.LogDebug($"Getting the asset {typeof(T).Name}.{name}...");
+        UnityEngine.Object result = true switch
+        {
+            true when typeof(T) == typeof(AudioClip) => CachedAudioClips[name],
+            true when typeof(T) == typeof(GameObject) => CachedPrefabs[name],
+            true when typeof(T) == typeof(Material) => CachedMaterials[name],
+            true when typeof(T) == typeof(Mesh) => CachedMeshes[name],
+            true when typeof(T) == typeof(Sprite) => CachedSprites[name],
+            true when typeof(T) == typeof(Texture2D) => CachedTextures[name],
+            _ => throw new ArgumentException("The type of T is not recognized as an UnityEngine.Object class or subclass, or it is not supported."),
+        };
+        Main.logger.LogDebug($"Asset found: {((T)result).GetType().Name} '{name}'");
+
+        return result as T;
+    }
+
+    /// <summary>
+    /// Try to get an asset from the resourcescache.
+    /// </summary>
+    /// <typeparam name="T">Type of the resource to find.</typeparam>
+    /// <param name="name">Name of the resource to find.</param>
+    /// <param name="result">Asset found. Null if not found.</param>
+    /// <returns>True if the item have been found, otherwise false.</returns>
+    /// <exception cref="ArgumentException">If the provided type is not a valid UnityEngine.Object or not supported.</exception>
+    public bool TryGetAsset<T>(string name, out T result) where T : UnityEngine.Object
+    {
+        bool res;
+        switch(true)
+        {
+            case true when typeof(T) == typeof(AudioClip):
+                res = CachedAudioClips.TryGetValue(name, out var audio);
+                result = audio as T;
+                return res;
+            case true when typeof(T) == typeof(GameObject):
+                res = CachedPrefabs.TryGetValue(name, out var gameObject);
+                result = gameObject as T;
+                return res;
+            case true when typeof(T) == typeof(Material):
+                res = CachedMaterials.TryGetValue(name, out var material);
+                result = material as T;
+                return res;
+            case true when typeof(T) == typeof(Mesh):
+                res = CachedMeshes.TryGetValue(name, out var mesh);
+                result = mesh as T;
+                return res;
+            case true when typeof(T) == typeof(Sprite):
+                res = CachedSprites.TryGetValue(name, out var sprite);
+                result = sprite as T;
+                return res;
+            case true when typeof(T) == typeof(Texture2D):
+                res = CachedTextures.TryGetValue(name, out var texture);
+                result = texture as T;
+                return res;
+            default:
+                throw new ArgumentException("Type of T is not a valid UnityEngine.Object, or is not supported.");
+        }
+    }
+}
diff --git a/AlterraWeaponry/alterraweaponry.assets b/AlterraWeaponry/alterraweaponry.assets
index 31c067a..cef3bd2 100644
Binary files a/AlterraWeaponry/alterraweaponry.assets and b/AlterraWeaponry/alterraweaponry.assets differ
diff --git a/AlterraWeaponry/assets/Coal.png b/AlterraWeaponry/assets/Coal.png
deleted file mode 100644
index 8436d67..0000000
Binary files a/AlterraWeaponry/assets/Coal.png and /dev/null differ
diff --git a/AlterraWeaponry/assets/ExplosiveTorpedo.png b/AlterraWeaponry/assets/ExplosiveTorpedo.png
deleted file mode 100644
index e2ab1f1..0000000
Binary files a/AlterraWeaponry/assets/ExplosiveTorpedo.png and /dev/null differ
diff --git a/AlterraWeaponry/assets/PrawnPerimeterDefense.png b/AlterraWeaponry/assets/PrawnPerimeterDefense.png
deleted file mode 100644
index 2b4f6d7..0000000
Binary files a/AlterraWeaponry/assets/PrawnPerimeterDefense.png and /dev/null differ
diff --git a/AlterraWeaponry/assets/Texture2D/crashfish_powder_01.png b/AlterraWeaponry/assets/Texture2D/crashfish_powder_01.png
deleted file mode 100644
index 602a1c1..0000000
Binary files a/AlterraWeaponry/assets/Texture2D/crashfish_powder_01.png and /dev/null differ
diff --git a/AlterraWeaponry/assets/Texture2D/crashfish_powder_normal.png b/AlterraWeaponry/assets/Texture2D/crashfish_powder_normal.png
deleted file mode 100644
index 3c19475..0000000
Binary files a/AlterraWeaponry/assets/Texture2D/crashfish_powder_normal.png and /dev/null differ
diff --git a/AlterraWeaponry/assets/Texture2D/crashfish_powder_spec.png b/AlterraWeaponry/assets/Texture2D/crashfish_powder_spec.png
deleted file mode 100644
index 315fa65..0000000
Binary files a/AlterraWeaponry/assets/Texture2D/crashfish_powder_spec.png and /dev/null differ
diff --git a/AlterraWeaponry/assets/crashpowder.png b/AlterraWeaponry/assets/crashpowder.png
deleted file mode 100644
index eabfb92..0000000
Binary files a/AlterraWeaponry/assets/crashpowder.png and /dev/null differ
diff --git a/AlterraWeaponry/assets/first_lethal_message.ogg b/AlterraWeaponry/assets/first_lethal_message.ogg
deleted file mode 100644
index 1542af3..0000000
Binary files a/AlterraWeaponry/assets/first_lethal_message.ogg and /dev/null differ
diff --git a/AlterraWeaponry/assets/prawn_shield.png b/AlterraWeaponry/assets/prawn_shield.png
deleted file mode 100644
index 8aac9fc..0000000
Binary files a/AlterraWeaponry/assets/prawn_shield.png and /dev/null differ
diff --git a/AlterraWeaponry/assets/pwa_presentation.ogg b/AlterraWeaponry/assets/pwa_presentation.ogg
deleted file mode 100644
index b11c962..0000000
Binary files a/AlterraWeaponry/assets/pwa_presentation.ogg and /dev/null differ
diff --git a/AlterraWeaponry/behaviours/CustomTriggerEventAssigner.cs b/AlterraWeaponry/behaviours/CustomTriggerEventAssigner.cs
index 355ee5d..addfa1d 100644
--- a/AlterraWeaponry/behaviours/CustomTriggerEventAssigner.cs
+++ b/AlterraWeaponry/behaviours/CustomTriggerEventAssigner.cs
@@ -1,4 +1,4 @@
-namespace VELD.AlterraWeaponry.behaviours;
+namespace VELD.AlterraWeaponry.Behaviours;
 
 public class CustomTriggerStoryGoalAssigner : MonoBehaviour
 {
diff --git a/AlterraWeaponry/behaviours/TorpedoExplosionBehaviour.cs b/AlterraWeaponry/behaviours/TorpedoExplosionBehaviour.cs
index dc96411..b3883d6 100644
--- a/AlterraWeaponry/behaviours/TorpedoExplosionBehaviour.cs
+++ b/AlterraWeaponry/behaviours/TorpedoExplosionBehaviour.cs
@@ -1,17 +1,62 @@
-namespace VELD.AlterraWeaponry.behaviours;
+namespace VELD.AlterraWeaponry.Behaviours;
 
 public class TorpedoExplosionBehaviour : MonoBehaviour
 {
+    public void Awake()
+    {
+    }
+
     public void Start()
     {
-        DamageSystem.RadiusDamage(250f, base.gameObject.transform.position, 5f, DamageType.Explosive, base.gameObject);
-#if BZ
-        Utils.PlayOneShotPS(GameObject.Instantiate(new VFXMeteor().gameObject).GetComponent<VFXMeteor>().impactPrefab, base.gameObject.transform.position, base.gameObject.transform.rotation, null);
-#else
-        Utils.PlayOneShotPS(GameObject.Instantiate(new LavaLizard().gameObject).GetComponent<LavaLiazardRangedAttack>().attackStartFXcontrol.emitters[0].fx, base.gameObject.transform.position, base.gameObject.transform.rotation, null);
+        Main.logger.LogInfo("Releasing explosion !");
+        DamageSystem.RadiusDamage((250f * Main.Options.dmgMultiplier), gameObject.transform.position, 10f, DamageType.Explosive, gameObject);
+#if BELOWZERO
+        try
+        {
+            var vfxMeteor = detonationPrefab.GetComponent<VFXMeteor>();
+            if (vfxMeteor.impactPrefab == null)
+                throw new Exception("vfxMeteor.impactPerfab is null.");
+            global::Utils.PlayOneShotPS(vfxMeteor.impactPrefab, gameObject.transform.position, gameObject.transform.rotation);
+            if (vfxMeteor.meteorCrashOSSound == null)
+                throw new Exception("vfxMeteor.meteorCrashOSSound is null.");
+            VFXWeatherManager.PlayOneShotSound(vfxMeteor.meteorCrashOSSound, gameObject.transform.position, 8f, Array.Empty<VFXWeatherManager.FmodParameter>());
+        }
+        catch(Exception e)
+        {
+            Main.logger.LogError($"An error has occured while exploding the torpedo.\n{e}");
+        }
+#elif SUBNAUTICA
+        global::Utils.PlayOneShotPS(GameObject.Instantiate<LavaLizard>(new LavaLizard()).GetComponent<LavaLiazardRangedAttack>().attackStartFXcontrol.emitters[0].fx, base.gameObject.transform.position, base.gameObject.transform.rotation, null);
 #endif
-        UnityEngine.Object.Destroy(base.gameObject);
+        Destroy(gameObject);
+        Main.logger.LogInfo("Exploded !!!");
     }
 
-    public static GameObject detonationEffectPrefab;
+    public static GameObject detonationPrefab;
+
+    public static IEnumerator SetupDetonationPrefabAsync()
+    {
+        Main.logger.LogInfo($"{typeof(TorpedoExplosionBehaviour).FullName}: Setting up detonation prefab for explosive torpedo...");
+        if (detonationPrefab != null)
+        {
+            Main.logger.LogInfo($"{typeof(TorpedoExplosionBehaviour).FullName}: vfxMeteor is already defined.");
+            yield break;
+        }
+
+        GameObject prefab;
+
+#if BELOWZERO
+        prefab = VFXWeatherManager.main.meteorController.closeUpPrefab;
+
+        if(prefab.GetComponent<VFXMeteor>() == null)
+        {
+            Main.logger.LogError($"{typeof(TorpedoExplosionBehaviour).FullName}: No VFXMeteor found in the closeupPrefab.");
+            yield break;
+        }
+#endif
+
+        yield return prefab;
+        detonationPrefab = prefab;
+        Main.logger.LogInfo($"{typeof(TorpedoExplosionBehaviour).FullName}: Detonation prefab set up.");
+    }
 }
diff --git a/AlterraWeaponry/behaviours/ZapFunctionalityBehaviour.cs b/AlterraWeaponry/behaviours/ZapFunctionalityBehaviour.cs
index 5d44a0a..a6f960b 100644
--- a/AlterraWeaponry/behaviours/ZapFunctionalityBehaviour.cs
+++ b/AlterraWeaponry/behaviours/ZapFunctionalityBehaviour.cs
@@ -1,4 +1,4 @@
-namespace VELD.AlterraWeaponry.behaviours;
+namespace VELD.AlterraWeaponry.Behaviours;
 
 internal class ZapFunctionalityBehaviour : MonoBehaviour // Thanks to ECM and PrimeSonic 👌
 {
@@ -9,10 +9,16 @@ internal class ZapFunctionalityBehaviour : MonoBehaviour // Thanks to ECM and Pr
     public float Overcharge { get; private set; }
     public float OverchargeScalar { get; private set; } 
 
-    public static IEnumerator UpdateDefensePrefab()
+    private void Awake()
     {
-        if (seamothElectricalDefensePrefab) yield break;
+        if(seamothElectricalDefensePrefab == null)
+            CoroutineHost.StartCoroutine(UpdateDefensePrefab());
+    }
 
+    public static IEnumerator UpdateDefensePrefab()
+    {
+        if (seamothElectricalDefensePrefab is not null) yield break;
+        Main.logger.LogDebug("Updating defense prefab for ZapFunctionalityBehaviour.ElectricalDefensePrefab.");
         var task = CraftData.GetPrefabForTechTypeAsync(TechType.SeaTruck);
         yield return task;
         var prefab = task.GetResult();
@@ -20,18 +26,20 @@ public static IEnumerator UpdateDefensePrefab()
         if (prefab == null) yield break;
 
         seamothElectricalDefensePrefab = prefab.GetComponent<SeaTruckUpgrades>().electricalDefensePrefab;
+        Main.logger.LogDebug("Done !");
     }
-    public bool Zap(Vehicle vehicle, int usedSlotID)
+    public bool Zap(Vehicle vehicle, int usedSlotID, float charge, float chargeScalar)
     {
+        Main.logger.LogInfo("Preparing the zap...");
         if (vehicle == null)
             return false;
 
-        float charge = vehicle.quickSlotCharge[usedSlotID];
-        float slotCharge = vehicle.GetSlotCharge(usedSlotID);
+        Main.logger.LogInfo("Should zap.");
         this.Overcharge = charge;
-        this.OverchargeScalar = slotCharge;
-        CoroutineHost.StartCoroutine(UpdateDefensePrefab());
+        this.OverchargeScalar = chargeScalar;
+        Main.logger.LogInfo("Settings set, it should be zapping.");
 
+        Main.logger.LogInfo("Executing Zap in radius..");
         ZapRadius(vehicle);
         return true;
     }
@@ -39,9 +47,11 @@ public bool Zap(Vehicle vehicle, int usedSlotID)
     private void ZapRadius(Vehicle vehicle)
     {
 
-        GameObject gameObject = Utils.SpawnZeroedAt(ElectricalDefensePrefab, vehicle.transform, false);
+        GameObject gameObject = global::Utils.SpawnZeroedAt(ElectricalDefensePrefab, vehicle.transform, false);
         ElectricalDefense defenseComponent = gameObject.GetComponent<ElectricalDefense>();
         defenseComponent.charge = this.Overcharge;
         defenseComponent.chargeScalar = this.OverchargeScalar;
+        defenseComponent.damage *= Main.Options.dmgMultiplier;
+        Main.logger.LogInfo("Should have zapped !");
     }
 }
diff --git a/AlterraWeaponry/items/BlackPowder.cs b/AlterraWeaponry/items/BlackPowder.cs
index c3adab4..ac62a82 100644
--- a/AlterraWeaponry/items/BlackPowder.cs
+++ b/AlterraWeaponry/items/BlackPowder.cs
@@ -1,66 +1,86 @@
-namespace VELD.AlterraWeaponry.items;
+namespace VELD.AlterraWeaponry.Items;
 
-internal class BlackPowder : Craftable
+internal class BlackPowder
 {
-    public static GameObject AssetPrefab = Main.assets.LoadAsset<GameObject>("GameObject.BlackPowder");
-    public static GameObject prefab;
-    public static TechType techType { get; private set; } = 0;
+    public static string ClassID = "BlackPowder";
+    public static TechType TechType { get; private set; } = 0;
 
-    public BlackPowder() : base("BlackPowder", "BlackPowder", "Tooltip_BlackPowder")
+
+    public static GameObject AssetPrefab = Main.AssetsCache.GetAsset<GameObject>("BlackPowder");
+    public PrefabInfo Info { get; private set; }
+
+    public BlackPowder()
     {
-        OnFinishedPatching += () =>
-        {
-            techType = TechType;
-        };
+        Main.logger.LogDebug("Loading BlackPowder prefab info");
+        if (!Main.AssetsCache.TryGetAsset("BlackPowder", out Sprite icon))
+            Main.logger.LogError("Unable to load BlackPowder sprite from cache.");
+
+        this.Info = PrefabInfo
+            .WithTechType(classId: ClassID, displayName: null, description: null, unlockAtStart: true, techTypeOwner: Assembly.GetExecutingAssembly())
+            .WithIcon(icon)
+            .WithSizeInInventory(new(1, 1));
+        TechType = this.Info.TechType;
+        Main.logger.LogDebug("Loaded BlackPowder prefab info and assigned TechType");
     }
-    public override TechCategory CategoryForPDA => TechCategory.AdvancedMaterials;
-    public override TechGroup GroupForPDA => TechGroup.Resources;
-    public override TechType RequiredForUnlock => Coal.techType;
-    public override float CraftingTime => 2.5f;
-    public override CraftTree.Type FabricatorType => CraftTree.Type.Fabricator;
-    public override Vector2int SizeInInventory => new(1, 1);
-    public override string[] StepsToFabricatorTab => new string[] { "Resources", "AdvancedMaterials"};
-    protected override RecipeData GetBlueprintRecipe()
+
+    public void Patch()
     {
-        return new()
+        Main.logger.LogDebug("Loading BlackPowder recipe");
+        RecipeData recipe = new()
         {
             craftAmount = 1,
             Ingredients = new()
             {
-                new(Coal.techType, 1),
+                new(Coal.TechType, 1),
                 new(TechType.Sulphur, 1),
                 new(TechType.JeweledDiskPiece, 3)
             }
         };
+
+        Main.logger.LogDebug("Loaded BlackPowder recipe, loading custom prefab...");
+
+        CustomPrefab customPrefab = new(this.Info);
+
+        customPrefab.SetGameObject(SetupGameObject());
+        customPrefab.SetUnlock(Coal.TechType)
+            .WithCompoundTechsForUnlock(new()
+            {
+                TechType.CreepvinePiece,
+                TechType.Sulphur
+            })
+            .WithPdaGroupCategoryBefore(TechGroup.Resources, TechCategory.AdvancedMaterials, TechType.HydrochloricAcid);
+        customPrefab.SetEquipment(EquipmentType.None);
+        customPrefab.SetRecipe(recipe)
+            .WithCraftingTime(2.5f)
+            .WithFabricatorType(CraftTree.Type.Fabricator)
+            .WithStepsToFabricatorTab("Resources", "BasicMaterials");
+
+        customPrefab.Register();
+
+        Main.logger.LogDebug("Loaded and registered BlackPowder prefab.");
     }
-    protected override Sprite GetItemSprite()
-    {
-        return Main.assets.LoadAsset<Sprite>("Sprite.BlackPowder");
-    }
-    public override GameObject GetGameObject()
+
+    /// <summary>
+    /// Setup the game object
+    /// </summary>
+    /// <returns>The modified asset prefab</returns>
+    public GameObject SetupGameObject()
     {
-        bool flag = !prefab;
-        if (flag)
+        Main.logger.LogDebug("Setting up BlackPowder GameObject.");
+        Main.logger.LogDebug("Setting shaders.");
+        var renderer = AssetPrefab.EnsureComponent<MeshRenderer>();
+        foreach(var mat in renderer.materials)
         {
-            prefab = Main.assets.LoadAsset<GameObject>("GameObject.BlackPowder");
-            Pickupable pickupable = prefab.AddComponent<Pickupable>();
-            pickupable.overrideTechType = base.TechType;
-            PrefabIdentifier prefabIdentifier = prefab.AddComponent<PrefabIdentifier>();
-            prefabIdentifier.ClassId = base.ClassID;
-            prefabIdentifier.name = base.ClassID;
-            prefab.AddComponent<WorldForces>();
-            prefab.AddComponent<LargeWorldEntity>();
-            TechTag techTag = prefab.AddComponent<TechTag>();
-            techTag.type = base.TechType;
+            if (Main.AssetsCache.TryGetAsset("BlackPowder", out Texture2D albedo))
+                mat.SetTexture(ShaderPropertyID._MainTex, albedo);
+
+            if(Main.AssetsCache.TryGetAsset("BlackPowder_spec", out Texture2D speculars))
+                mat.SetTexture(ShaderPropertyID._SpecTex, speculars);
+
+            if(Main.AssetsCache.TryGetAsset("BlackPowder_normals", out Texture2D normals))
+                mat.SetTexture(ShaderPropertyID._NormalsTex, normals);
         }
-        prefab.SetActive(true);
-        GameObject go = UnityEngine.Object.Instantiate<GameObject>(prefab);
-        return go;
-    }
-    public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject)
-    {
-        gameObject.Set(this.GetGameObject());
-        yield return null;
-        yield break;
+        MaterialUtils.ApplySNShaders(AssetPrefab);
+        return AssetPrefab;
     }
 }
diff --git a/AlterraWeaponry/items/Coal.cs b/AlterraWeaponry/items/Coal.cs
index cefc37f..b1bd0f2 100644
--- a/AlterraWeaponry/items/Coal.cs
+++ b/AlterraWeaponry/items/Coal.cs
@@ -1,28 +1,32 @@
-namespace VELD.AlterraWeaponry.items;
+namespace VELD.AlterraWeaponry.Items;
 
-internal class Coal : Craftable
+internal class Coal
 {
-    public static GameObject prefab;
-    public static TechType techType { get; private set; } = 0;
+    public static string ClassID = "Coal";
+    public static TechType TechType { get; private set; } = 0;
 
-    public Coal() : base ("Coal", "Coal", "Tooltip_Coal")
+
+    public PrefabInfo Info { get; private set; }
+
+    public Coal()
     {
-        OnFinishedPatching += () =>
-        {
-            techType = TechType;
-        };
+        Main.logger.LogDebug("Loading Coal go info");
+        if (!Main.AssetsCache.TryGetAsset("Coal", out Sprite icon))
+            Main.logger.LogError("Unable to load Coal Sprite from cache.");
+
+        this.Info = PrefabInfo
+            .WithTechType(classId: ClassID, displayName: null, description: null, unlockAtStart: true, techTypeOwner: Assembly.GetExecutingAssembly())
+            .WithIcon(icon)
+            .WithSizeInInventory(new(1, 1));
+
+        TechType = this.Info.TechType;
+        Main.logger.LogDebug("Loaded Coal go and assigned techType");
     }
 
-    public override CraftTree.Type FabricatorType => CraftTree.Type.Fabricator;
-    public override TechCategory CategoryForPDA => TechCategory.BasicMaterials;
-    public override TechGroup GroupForPDA => TechGroup.Resources;
-    public override Vector2int SizeInInventory => new(1, 1);
-    public override float CraftingTime => 3f;
-    public override bool UnlockedAtStart => true;
-    public override string[] StepsToFabricatorTab => new string[] { "Resources", "BasicMaterials" };
-    protected override RecipeData GetBlueprintRecipe()
+    public void Patch()
     {
-        return new()
+        Main.logger.LogDebug("Setting Coal recipe");
+        RecipeData recipe = new()
         {
             craftAmount = 4,
             Ingredients = new()
@@ -30,24 +34,51 @@ protected override RecipeData GetBlueprintRecipe()
                 new(TechType.CreepvinePiece, 1)
             }
         };
-    }
-    protected override Sprite GetItemSprite()
-    {
-        return Main.assets.LoadAsset<Sprite>("Sprite.Coal");
-    }
-    public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject)
-    {
-        if (prefab == null)
+
+        Main.logger.LogDebug("Recipe set, now patching go.");
+
+        CustomPrefab customPrefab = new(this.Info);
+        PrefabTemplate clone = new CloneTemplate(this.Info, TechType.Sulphur)
         {
-            CoroutineTask<GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.Titanium);
-            yield return task;
+            ModifyPrefab = (go) =>
+            {
+                var renderer = go.GetComponentInChildren<MeshRenderer>();
+                foreach(var mat in renderer.materials)
+                {
+                    if (Main.AssetsCache.TryGetAsset("Coal", out Texture2D albedo))
+                        mat.SetTexture(ShaderPropertyID._MainTex, albedo);
 
-            prefab = GameObject.Instantiate(task.GetResult());
-        }
+                    if (Main.AssetsCache.TryGetAsset("Coal_spec", out Texture2D specular))
+                        mat.SetTexture(ShaderPropertyID._SpecTex, specular);
 
-        GameObject go = GameObject.Instantiate(prefab);
-        gameObject.Set(go);
-    }
+                    if (Main.AssetsCache.TryGetAsset("Coal_illum", out Texture2D illumination))
+                        mat.SetTexture(ShaderPropertyID._Illum, illumination);
+                }
 
+                var vfxFabricating = go.EnsureComponent<VFXFabricating>();
+                MaterialUtils.ApplySNShaders(go);
+            } 
+        };
 
+        customPrefab.SetGameObject(clone);
+        customPrefab.SetUnlock(TechType.CreepvinePiece)
+            .WithPdaGroupCategoryBefore(TechGroup.Resources, TechCategory.BasicMaterials);
+        customPrefab.SetEquipment(EquipmentType.None);
+        customPrefab.SetRecipe(recipe)
+            .WithCraftingTime(4f)
+            .WithFabricatorType(CraftTree.Type.Fabricator)
+            .WithStepsToFabricatorTab("Resources", "BasicMaterials");
+        
+        customPrefab.SetOutcropDrop(
+                new(TechType.LimestoneChunk, 0.408f),
+                new(TechType.BreakableGold, 0.159f),
+                new(TechType.BreakableSilver, 0.118f)
+            );
+
+        customPrefab.Register();
+
+        BaseBioReactor.charge.Add(TechType, 560f);
+
+        Main.logger.LogDebug("Prefab loaded and registered for Coal.");
+    }
 }
diff --git a/AlterraWeaponry/items/ExplosiveTorpedo.cs b/AlterraWeaponry/items/ExplosiveTorpedo.cs
index b1ee7b1..05dc4e0 100644
--- a/AlterraWeaponry/items/ExplosiveTorpedo.cs
+++ b/AlterraWeaponry/items/ExplosiveTorpedo.cs
@@ -1,53 +1,54 @@
-namespace VELD.AlterraWeaponry.items;
+namespace VELD.AlterraWeaponry.Items;
 
-internal class ExplosiveTorpedo : Craftable
+internal class ExplosiveTorpedo
 {
+    public static string ClassID = "ExplosiveTorpedo";
+    public static TechType TechType { get; private set; } = 0;
+
+
     public static GameObject prefab;
-    public static TechType techType { get; private set; } = 0;
+    public PrefabInfo Info { get; private set; }
 
-    public ExplosiveTorpedo() : base("ExplosiveTorpedo", "ExplosiveTorpedo", "Tooltip_ExplosiveTorpedo")
+    public ExplosiveTorpedo()
     {
-        OnFinishedPatching += () =>
-        {
-            techType = TechType;
-        };
+        if (!Main.AssetsCache.TryGetAsset("ExplosiveTorpedo", out Sprite icon))
+            Main.logger.LogError("Unable to load ExplosiveTorpedo Sprite from cache.");
+
+        Info = PrefabInfo
+            .WithTechType(classId: ClassID, displayName: null, description: null, techTypeOwner: Assembly.GetExecutingAssembly())
+            .WithSizeInInventory(new(1, 1))
+            .WithIcon(icon);
+
+        TechType = Info.TechType;
     }
 
-    public override TechCategory CategoryForPDA => TechCategory.VehicleUpgrades;
-    public override TechType RequiredForUnlock => TechType.ExosuitTorpedoArmModule;
-    public override float CraftingTime => 3f;
-    public override CraftTree.Type FabricatorType => CraftTree.Type.Fabricator;
-    public override TechGroup GroupForPDA => TechGroup.VehicleUpgrades;
-    public override Vector2int SizeInInventory => new(1, 1);
-    public override string[] StepsToFabricatorTab => new string[] { "Upgrades", "ExosuitUpgrades" };
-    public override string DiscoverMessage => "Discover_LethalWeapon";
-    protected override RecipeData GetBlueprintRecipe()
+    public void Patch()
     {
-        return new()
+        RecipeData recipe = new()
         {
             craftAmount = 2,
             Ingredients = new()
             {
-                new(BlackPowder.techType, 2),
-                new(TechType.Titanium, 1),
+                new(BlackPowder.TechType, 2),
+                new(TechType.Titanium, 1)
             }
         };
-    }
-    protected override Sprite GetItemSprite()
-    {
-        return Main.assets.LoadAsset<Sprite>("Sprite.ExplosiveTorpedo");
-    }
-    public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject)
-    {
-        if (prefab == null)
-        {
-            CoroutineTask<GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.WhirlpoolTorpedo);
-            yield return task;
 
-            prefab = GameObject.Instantiate(task.GetResult());
-        }
+        CustomPrefab customPrefab = new(Info);
+        CloneTemplate clone = new(Info, TechType.GasTorpedo);
+
+        customPrefab.SetGameObject(clone);
+        if (!Main.AssetsCache.TryGetAsset("UpgradePopup", out Sprite popupSprite))
+            Main.logger.LogError("Unable to load UpgradePopup sprite from cache.");
+        customPrefab.SetUnlock(BlackPowder.TechType)
+            .WithEncyclopediaEntry("Tech/Weaponry", popupSprite)
+            .WithPdaGroupCategoryAfter(TechGroup.VehicleUpgrades, TechCategory.VehicleUpgrades, TechType.GasTorpedo);
+        customPrefab.SetEquipment(EquipmentType.None);
+        customPrefab.SetRecipe(recipe)
+            .WithCraftingTime(3f)
+            .WithFabricatorType(CraftTree.Type.Fabricator)
+            .WithStepsToFabricatorTab("Upgrades", "ExosuitUpgrades");
 
-        GameObject go = GameObject.Instantiate(prefab);
-        gameObject.Set(go);
+        customPrefab.Register();
     }
 }
diff --git a/AlterraWeaponry/items/PrawnSelfDefenseModule.cs b/AlterraWeaponry/items/PrawnSelfDefenseModule.cs
index 94afc35..151f76a 100644
--- a/AlterraWeaponry/items/PrawnSelfDefenseModule.cs
+++ b/AlterraWeaponry/items/PrawnSelfDefenseModule.cs
@@ -1,34 +1,35 @@
-namespace VELD.AlterraWeaponry.items;
+namespace VELD.AlterraWeaponry.Items;
 
-public class PrawnSelfDefenseModule : Equipable
+public class PrawnSelfDefenseModule
 {
+    public const float maxCharge = 10f;
+    public const float energyCost = 5f;
+    public const float cooldown = 5f;
+
+    public static string ClassID = "PrawnSelfDefenseModule";
+    public static TechType TechType { get; private set; } = 0;
+
+
     public static GameObject prefab;
-    public static float maxCharge = 10f;
-    public static float energyCost = 5f;
-    public static float cooldown = 5f;
-    public static TechType techType { get; private set; } = 0;
+    public PrefabInfo Info { get; private set; }
 
-    public PrawnSelfDefenseModule() : base("PrawnSelfDefenseModule", "PrawnSelfDefenseModule", "Tooltip_PrawnSelfDefenseModule")
+    public PrawnSelfDefenseModule()
     {
-        OnFinishedPatching += () =>
-        {
-            techType = TechType;
-        };
+        if (!Main.AssetsCache.TryGetAsset("PrawnSelfDefenseModule", out Sprite icon))
+            Main.logger.LogError("Unable to load PrawnSelfDefenseModule sprite from cache.");
+
+        Info = PrefabInfo
+            .WithTechType(classId: ClassID, displayName: null, description: null, techTypeOwner: Assembly.GetExecutingAssembly())
+            .WithSizeInInventory(new(1, 1))
+            .WithIcon(icon);
+
+        TechType = this.Info.TechType;
+
     }
 
-    public override TechCategory CategoryForPDA => TechCategory.VehicleUpgrades;
-    public override float CraftingTime => 3f;
-    public override EquipmentType EquipmentType => EquipmentType.ExosuitModule;
-    public override CraftTree.Type FabricatorType => CraftTree.Type.Fabricator;
-    public override int FragmentsToScan => 1;
-    public override TechGroup GroupForPDA => TechGroup.VehicleUpgrades;
-    public override QuickSlotType QuickSlotType => QuickSlotType.Chargeable;
-    public override TechType RequiredForUnlock => TechType.SeaTruckUpgradePerimeterDefense;
-    public override Vector2int SizeInInventory => new(1, 1);
-    public override string[] StepsToFabricatorTab => new string[] { "Upgrades", "ExosuitUpgrades" };
-    protected override RecipeData GetBlueprintRecipe()
+    public void Patch()
     {
-        return new()
+        RecipeData recipe = new()
         {
             craftAmount = 1,
             Ingredients = new()
@@ -39,22 +40,57 @@ protected override RecipeData GetBlueprintRecipe()
                 new(TechType.Polyaniline, 1)
             }
         };
-    }
-    protected override Sprite GetItemSprite()
-    {
-        return Main.assets.LoadAsset<Sprite>("Sprite.PrawnSelfDefenseModule");
-    }
-    public override IEnumerator GetGameObjectAsync(IOut<GameObject> gameObject)
-    {
-        if (prefab == null)
-        {
-            CoroutineTask<GameObject> task = CraftData.GetPrefabForTechTypeAsync(TechType.SeaTruckUpgradePerimeterDefense);
-            yield return task;
 
-            prefab = GameObject.Instantiate(task.GetResult());
-        }
+        CustomPrefab customPrefab = new(this.Info);
+        CloneTemplate clone = new(this.Info, TechType.SeaTruckUpgradePerimeterDefense);
+
+        customPrefab.SetGameObject(clone);
+
+        if (!Main.AssetsCache.TryGetAsset("UpgradePopup", out Sprite popupSprite))
+            Main.logger.LogError("Unable to load UpgradePopup sprite from cache.");
+
+        customPrefab.SetUnlock(TechType.Polyaniline)
+            .WithEncyclopediaEntry("Tech/Weaponry", popupSprite)
+            .WithPdaGroupCategoryAfter(TechGroup.VehicleUpgrades, TechCategory.VehicleUpgrades, TechType.ExosuitThermalReactorModule);
+        customPrefab.SetVehicleUpgradeModule(EquipmentType.ExosuitModule, QuickSlotType.Chargeable)
+            .WithEnergyCost(energyCost)
+            .WithMaxCharge(maxCharge)
+            .WithCooldown(5f)
+            .WithOnModuleAdded((Vehicle instance, int slotID) =>
+            {
+                if (!instance.gameObject.TryGetComponent(out ZapFunctionalityBehaviour defMono))
+                    instance.gameObject.EnsureComponent<ZapFunctionalityBehaviour>();
+                else
+                    Main.logger.LogWarning("For some reason, the defense mono was already existing on the prawn although the upgrade was not equipped.");
+            })
+            .WithOnModuleRemoved((Vehicle instance, int slotID) =>
+            {
+                if (instance.gameObject.TryGetComponent(out ZapFunctionalityBehaviour defMono))
+                    UnityEngine.Object.Destroy(defMono);
+                else
+                    Main.logger.LogWarning("For some reason, the defense mono was no existing on Prawn although the upgrade was equipped.");
+            })
+            .WithOnModuleUsed((Vehicle instance, int slotID, float charge, float chargeScalar) =>
+            {
+                if (!instance.gameObject.TryGetComponent(out ZapFunctionalityBehaviour defenseMono))
+                    defenseMono = instance.gameObject.EnsureComponent<ZapFunctionalityBehaviour>();
+                Main.logger.LogInfo("Zapping !");
+                try
+                {
+                    defenseMono.Zap(instance, slotID, charge, chargeScalar);
+                }
+                catch (Exception e)
+                {
+                    Main.logger.LogError($"Cannot use the defense mono.\nError:");
+                    Main.logger.LogError(e);
+                }
+                Main.logger.LogInfo("Zapped !");
+            });
+        customPrefab.SetRecipe(recipe)
+            .WithCraftingTime(2.5f)
+            .WithFabricatorType(CraftTree.Type.Fabricator)
+            .WithStepsToFabricatorTab("Upgrades", "ExosuitUpgrades");
 
-        GameObject go = GameObject.Instantiate(prefab);
-        gameObject.Set(go);
+        customPrefab.Register();
     }
 }
diff --git a/AlterraWeaponry/patches/ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs b/AlterraWeaponry/patches/ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs
index c712a05..13d14bb 100644
--- a/AlterraWeaponry/patches/ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs
+++ b/AlterraWeaponry/patches/ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch.cs
@@ -1,15 +1,24 @@
-namespace VELD.AlterraWeaponry.patches;
+namespace VELD.AlterraWeaponry.Patches;
 
 [HarmonyPatch(typeof(ExosuitTorpedoArm))]
 public class ExosuitTorpedoArm_OpenTorpedoStorageExternal_Patch // Thanks to Grimm The Second !
 {
     [HarmonyPrefix]
-    [HarmonyPatch(nameof(ExosuitTorpedoArm.OnOpenTorpedoStorage))]
-    public static void OpenTorpedoStorageExternal(ExosuitTorpedoArm __instance)
+    [HarmonyPatch(typeof(ExosuitTorpedoArm), nameof(ExosuitTorpedoArm.OpenTorpedoStorageExternal))]
+    private static void OpenTorpedoStorageExternal(ExosuitTorpedoArm __instance)
     {
-        __instance.container.allowedTech.AddRange(new TechType[]
+        try
         {
-            ExplosiveTorpedo.techType
-        });
+            Main.logger.LogDebug("Trying to open PRAWN torpedo arm. Adding TechType: " + ExplosiveTorpedo.TechType);
+            __instance.container.allowedTech.AddRange(new[]
+            {
+                ExplosiveTorpedo.TechType
+            });
+            Main.logger.LogDebug("Added torpedo techtypes to PRAWN torpedo arm container filter.");
+        }
+        catch(Exception e)
+        {
+            Main.logger.LogDebug(e);
+        }
     }
 }
diff --git a/AlterraWeaponry/patches/GameSettings_SaveAsync_Patch.cs b/AlterraWeaponry/patches/GameSettings_SaveAsync_Patch.cs
deleted file mode 100644
index 664b076..0000000
--- a/AlterraWeaponry/patches/GameSettings_SaveAsync_Patch.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace VELD.AlterraWeaponry.patches;
-
-[HarmonyPatch(typeof(GameSettings))]
-public class GameSettings_SaveAsync_Patch
-{
-    [HarmonyPostfix]
-    [HarmonyPatch(nameof(GameSettings.SaveAsync))]
-    public static void SaveAsync(GameSettings.OnSaveDelegate onSave)
-    {
-        LanguagesHandler.LanguagePatch();
-    }
-}
diff --git a/AlterraWeaponry/patches/ItemGoalTracker_Start_Patch.cs b/AlterraWeaponry/patches/ItemGoalTracker_Start_Patch.cs
index b0f116b..ed0364b 100644
--- a/AlterraWeaponry/patches/ItemGoalTracker_Start_Patch.cs
+++ b/AlterraWeaponry/patches/ItemGoalTracker_Start_Patch.cs
@@ -1,4 +1,4 @@
-namespace VELD.AlterraWeaponry.patches;
+namespace VELD.AlterraWeaponry.Patches;
 
 [HarmonyPatch(typeof(ItemGoalTracker))]
 internal class ItemGoalTracker_Start_Patch
@@ -9,18 +9,18 @@ public static void Start(ItemGoalTracker __instance)
     {
         List<TechType> techTypes = new()
         {
-            ExplosiveTorpedo.techType,
-            //PrawnLaserArm.techType,
+            ExplosiveTorpedo.TechType,
+            //PrawnLaserArm.TechType,
         };
 
-        var goals = __instance.goalData.goals;
+        ItemGoal[] goals = __instance.goalData.goals;
         foreach (TechType techType in techTypes)
         {
-            var goal = new ItemGoal()
+            ItemGoal goal = new ItemGoal()
             {
                 techType = techType,
                 goalType = Story.GoalType.PDA,
-                key = "Log_PDA_Goal_FirstLethal",
+                key = "AWFirstLethal",
                 playInCreative = true,
                 playInCinematics = false,
             };
@@ -30,14 +30,16 @@ public static void Start(ItemGoalTracker __instance)
 
         foreach (TechType techType in techTypes)
         {
-            var goal = new ItemGoal()
+            ItemGoal goal = new ItemGoal()
             {
                 techType = techType,
                 goalType = Story.GoalType.Encyclopedia,
-                key = $"Ency_PDA_Goal_{nameof(techType)}",
+                key = $"Ency_{nameof(techType)}",
                 playInCreative = true,
                 playInCinematics = false,
             };
+
+            goals = goals.AddItem(goal).ToArray();
         }
 
         __instance.goalData.goals = goals;
diff --git a/AlterraWeaponry/patches/SeamothTorpedo_OnEnergyDepleted_Patch.cs b/AlterraWeaponry/patches/SeamothTorpedo_OnEnergyDepleted_Patch.cs
index e45e426..850c6a4 100644
--- a/AlterraWeaponry/patches/SeamothTorpedo_OnEnergyDepleted_Patch.cs
+++ b/AlterraWeaponry/patches/SeamothTorpedo_OnEnergyDepleted_Patch.cs
@@ -1,4 +1,4 @@
-namespace VELD.AlterraWeaponry.patches;
+namespace VELD.AlterraWeaponry.Patches;
 
 [HarmonyPatch(typeof(SeamothTorpedo))]
 public class SeamothTorpedo_OnEnergyDepleted_Patch // Thanks to Grimm The Second !
@@ -7,6 +7,6 @@ public class SeamothTorpedo_OnEnergyDepleted_Patch // Thanks to Grimm The Second
     [HarmonyPatch(nameof(SeamothTorpedo.OnEnergyDepleted))]
     public static bool OnEnergyDepleted(SeamothTorpedo __instance)
     {
-        return __instance.enabled;
+        return __instance._active;
     }
 }
diff --git a/AlterraWeaponry/patches/Vehicle_Awake_Patch.cs b/AlterraWeaponry/patches/Vehicle_Awake_Patch.cs
index d8c491f..7bef415 100644
--- a/AlterraWeaponry/patches/Vehicle_Awake_Patch.cs
+++ b/AlterraWeaponry/patches/Vehicle_Awake_Patch.cs
@@ -1,4 +1,4 @@
-namespace VELD.AlterraWeaponry.patches;
+namespace VELD.AlterraWeaponry.Patches;
 
 [HarmonyPatch(typeof(Vehicle))]
 public class Vehicle_Awake_Patch // Thanks to Grimm The Second !
@@ -7,16 +7,15 @@ public class Vehicle_Awake_Patch // Thanks to Grimm The Second !
     [HarmonyPatch(nameof(Vehicle.Awake))]
     public static void Awake(Vehicle __instance)
     {
-        bool flag = ExplosiveTorpedoInitializer.torpedoType == null;
-        if(flag)
+        if(ExplosiveTorpedoInitializer.torpedoType == null)
         {
-            TorpedoType torpedoType = Enumerable.FirstOrDefault<TorpedoType>(__instance.torpedoTypes, (TorpedoType type) => type.techType == TechType.GasTorpedo);
-            GameObject prefab = (torpedoType != null) ? torpedoType.prefab : null;
+            TorpedoType torpedoType = Enumerable.FirstOrDefault(__instance.torpedoTypes, (TorpedoType type) => type.techType == TechType.GasTorpedo);
+            GameObject prefab = torpedoType?.prefab;
             ExplosiveTorpedoInitializer.InitPrefab(prefab);
         }
-        __instance.torpedoTypes = __instance.torpedoTypes.ToArray().AddRangeToArray(new[]
+        __instance.torpedoTypes = CollectionExtensions.AddRangeToArray(__instance.torpedoTypes, new[]
         {
             ExplosiveTorpedoInitializer.torpedoType
-        });
+        }).ToArray();
     }
 }
diff --git a/AlterraWeaponry/patches/Vehicle_ChargeModule_Patch.cs b/AlterraWeaponry/patches/Vehicle_ChargeModule_Patch.cs
deleted file mode 100644
index a96e1f2..0000000
--- a/AlterraWeaponry/patches/Vehicle_ChargeModule_Patch.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-namespace VELD.AlterraWeaponry.patches;
-
-[HarmonyPatch(typeof(Vehicle))]
-public class Vehicle_ChargeModule_Patch
-{
-    [HarmonyPrefix]
-    [HarmonyPatch(nameof(Vehicle.ChargeModule))]
-    public static bool ChargeModule(Vehicle __instance, TechType techType, int slotID)
-    {
-        float num = __instance.quickSlotCharge[slotID];
-        float maxCharge = TechData.GetMaxCharge(techType);
-
-        // TEMP CODE WAITING FOR SMLHELPER UPDATE
-        if(techType == PrawnSelfDefenseModule.techType)
-            maxCharge = PrawnSelfDefenseModule.maxCharge;
-
-        float num2;
-        TechData.GetEnergyCost(techType, out num2);
-
-        // TEMP CODE WAITING FOR SMLHELPER UPDATE
-        if (techType == PrawnSelfDefenseModule.techType)
-            num2 = PrawnSelfDefenseModule.energyCost;
-
-        float num3 = num2 * Time.deltaTime;
-        float num4 = maxCharge - num;
-        bool flag = num3 >= num4;
-        float b = flag ? Mathf.Max(0f, num4) : num3;
-        int num6;
-        float num5 = Mathf.Min(__instance.energyInterface.TotalCanProvide(out num6), b);
-        __instance.ConsumeEnergy(num5);
-        __instance.quickSlotCharge[slotID] = __instance.quickSlotCharge[slotID] + num5;
-        if (__instance.quickSlotCharge[slotID] > 0f && (flag || num5 == 0f))
-        {
-            __instance.OnUpgradeModuleUse(techType, slotID);
-            __instance.quickSlotCharge[slotID] = 0f;
-        }
-        return false;
-    }
-}
diff --git a/AlterraWeaponry/patches/Vehicle_GetSlotCharge_Patch.cs b/AlterraWeaponry/patches/Vehicle_GetSlotCharge_Patch.cs
deleted file mode 100644
index 8289dff..0000000
--- a/AlterraWeaponry/patches/Vehicle_GetSlotCharge_Patch.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-namespace VELD.AlterraWeaponry.patches;
-
-
-[HarmonyPatch(typeof(Vehicle))]
-internal class Vehicle_GetSlotCharge_Patch
-{
-    [HarmonyPrefix]
-    [HarmonyPatch(nameof(Vehicle.GetSlotCharge))]
-    public static bool GetSlotCharge(Vehicle __instance, int slotID, ref float __result)
-    {
-        if (slotID < 0 || slotID >= __instance.slotIDs.Length)
-        {
-            __result = 1f;
-            return false;
-        }
-        TechType techType;
-        QuickSlotType quickSlotType = __instance.GetQuickSlotType(slotID, out techType);
-        if (quickSlotType == QuickSlotType.Chargeable || quickSlotType == QuickSlotType.SelectableChargeable)
-        {
-            float maxCharge = TechData.GetMaxCharge(techType);
-
-            // TEMPORARY PATCH, WAITING FOR AN SMLHELPER UPDATE
-            bool flag = techType == PrawnSelfDefenseModule.techType;
-            if (flag)
-                maxCharge = PrawnSelfDefenseModule.maxCharge;
-
-            if (maxCharge > 0f)
-            {
-                __result = __instance.quickSlotCharge[slotID] / maxCharge;
-                Main.logger.LogInfo($"Slot charge: {__result}");
-                return false;
-            }
-        }
-        __result = 1f;
-        return false;
-    }
-}
diff --git a/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleChange_Patch.cs b/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleChange_Patch.cs
deleted file mode 100644
index 0f1d831..0000000
--- a/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleChange_Patch.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-namespace VELD.AlterraWeaponry.patches;
-
-[HarmonyPatch(typeof(Vehicle))]
-internal class Vehicle_OnUpgradeModuleChange_Patch
-{
-    [HarmonyPostfix]
-    [HarmonyPatch(nameof(Vehicle.OnUpgradeModuleChange))]
-    public static void OnUpgradeModuleChange(TechType techType, bool added, Vehicle __instance)
-    {
-        if(techType == PrawnSelfDefenseModule.techType)
-        {
-            if(added)
-            {
-                Main.logger.LogInfo("Adding component ZapFunctionality to Vehicle.");
-                __instance.gameObject.AddComponent<ZapFunctionalityBehaviour>();
-                Main.logger.LogInfo("Added successfully ZapFunctionality to Vehicle.");
-            }
-            else
-            {
-                __instance.TryGetComponent<ZapFunctionalityBehaviour>(out ZapFunctionalityBehaviour defenseMono);
-                if (defenseMono != null)
-                    UnityEngine.Object.Destroy(defenseMono);
-            }
-        }
-    }
-}
diff --git a/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleUse_Patch.cs b/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleUse_Patch.cs
deleted file mode 100644
index a555f97..0000000
--- a/AlterraWeaponry/patches/Vehicle_OnUpgradeModuleUse_Patch.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-namespace VELD.AlterraWeaponry.patches;
-
-[HarmonyPatch(typeof(Vehicle))]
-public class Vehicle_OnUpgradeModuleUse_Patch
-{
-    [HarmonyPostfix]
-    [HarmonyPatch(nameof(Vehicle.OnUpgradeModuleUse))]
-    public static void OnUpgradeModuleUse(TechType techType, int slotID, Vehicle __instance)
-    {
-        if(__instance is not Exosuit)
-            return;
-
-
-        bool flag = true;
-        float num = 0f;
-        if (techType == PrawnSelfDefenseModule.techType)
-        {
-            if (!__instance.TryGetComponent(out ZapFunctionalityBehaviour defenseMono))
-                return;
-            defenseMono.Zap(__instance, slotID);
-            num = PrawnSelfDefenseModule.cooldown;
-        }
-        if (flag)
-        {
-            __instance.quickSlotTimeUsed[slotID] = Time.time;
-            __instance.quickSlotCooldown[slotID] = num;
-        }
-    }
-}
diff --git a/AlterraWeaponry/patches/uGUISceneLoading_End_Patch.cs b/AlterraWeaponry/patches/uGUISceneLoading_End_Patch.cs
index 1a55cd6..d10ddcd 100644
--- a/AlterraWeaponry/patches/uGUISceneLoading_End_Patch.cs
+++ b/AlterraWeaponry/patches/uGUISceneLoading_End_Patch.cs
@@ -1,13 +1,14 @@
-namespace VELD.AlterraWeaponry.patches;
+namespace VELD.AlterraWeaponry.Patches;
 
 [HarmonyPatch(typeof(uGUI_SceneLoading))]
 public class uGUISceneLoading_End_Patch
 {
-    [HarmonyPrefix]
+    [HarmonyPostfix]
     [HarmonyPatch(nameof(uGUI_SceneLoading.End))]
-    public static void End(bool fade)
+    public static void End(uGUI_SceneLoading __instance, bool fade)
     {
         Main.logger.LogInfo("Triggered LoadingScene end.");
+        //if(StoryGoalManager.main.OnGoalComplete(Main.AWPresentationGoal.key))
         Main.AWPresentationGoal.Trigger();
         Main.logger.LogInfo("Should play or have played AWPresentationGoal.");
     }
diff --git a/AlterraWeaponry/utils/ExplosiveTorpedoInitializer.cs b/AlterraWeaponry/utils/ExplosiveTorpedoInitializer.cs
index 4691f6a..bac3dbf 100644
--- a/AlterraWeaponry/utils/ExplosiveTorpedoInitializer.cs
+++ b/AlterraWeaponry/utils/ExplosiveTorpedoInitializer.cs
@@ -1,4 +1,4 @@
-namespace VELD.AlterraWeaponry.behaviours;
+namespace VELD.AlterraWeaponry.Utils;
 
 internal class ExplosiveTorpedoInitializer // Thanks to Grimm The Second !
 {
@@ -6,29 +6,35 @@ internal class ExplosiveTorpedoInitializer // Thanks to Grimm The Second !
 
     public static void InitPrefab(GameObject prefab)
     {
-        bool flag = torpedoType != null;
-        if(!flag)
+        if(torpedoType == null)
         {
-            bool flag2 = !prefab;
-            if(flag2)
+            if(!prefab)
             {
                 Main.logger.LogError("ExplosiveTorpedoBehaviour.InitPrefab() -> invalid prefab for torpedo.");
             }
             else
             {
-                GameObject go = new GameObject("TorpedoExplosion", new Type[]
+                try
                 {
-                    typeof(TorpedoExplosionBehaviour)
-                });
-                ModPrefabCache.AddPrefab(go, false);
-                GameObject go2 = ModPrefabCache.AddPrefabCopy(prefab, false);
-                go2.GetComponent<SeamothTorpedo>().explosionPrefab = go;
-                go2.GetComponent<SeamothTorpedo>().homingTorpedo = true;
-                torpedoType = new()
+                    CoroutineHost.StartCoroutine(TorpedoExplosionBehaviour.SetupDetonationPrefabAsync());
+                    Main.logger.LogInfo("Initializing TorpedoExplosionBehaviour TorpedoExplosion prefab...");
+                    GameObject go = new("TorpedoExplosion", new Type[]
+                    {
+                        typeof(TorpedoExplosionBehaviour)
+                    });
+                    ModPrefabCache.AddPrefab(go);
+                    prefab.GetComponent<SeamothTorpedo>().explosionPrefab = go;
+                    prefab.GetComponent<SeamothTorpedo>().homingTorpedo = true;
+                    torpedoType = new()
+                    {
+                        techType = ExplosiveTorpedo.TechType,
+                        prefab = prefab
+                    };
+                }
+                catch(Exception ex)
                 {
-                    techType = ExplosiveTorpedo.techType,
-                    prefab = go2
-                };
+                    Main.logger.LogError($"An error has occured while initializing torpedo prefab.\n{ex}");
+                }
             }
         }
     }
diff --git a/AlterraWeaponry/utils/GlobalInitializer.cs b/AlterraWeaponry/utils/GlobalInitializer.cs
new file mode 100644
index 0000000..783c3c1
--- /dev/null
+++ b/AlterraWeaponry/utils/GlobalInitializer.cs
@@ -0,0 +1,138 @@
+namespace VELD.AlterraWeaponry.Utils;
+
+internal class GlobalInitializer
+{
+    internal static string AudiosPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Sounds");
+    internal static void PatchGoals()
+    {
+
+        Main.AWPresentationGoal = new("PWAPresentation", Story.GoalType.PDA, 8f)
+        { 
+            playInCreative = true,
+            playInCinematics = false,
+            checkPlayerSafety = true,
+            delay = 15f
+        };
+
+        Nautilus.Handlers.StoryGoalHandler.RegisterCustomEvent(Main.AWPresentationGoal.key, () =>
+        {
+            Main.logger.LogInfo("Played PWAPresentation goal.");
+        });
+
+        Main.AWFirstLethal = Nautilus.Handlers.StoryGoalHandler.RegisterItemGoal("AWFirstLethal", Story.GoalType.PDA, ExplosiveTorpedo.TechType, 3f);
+
+        Nautilus.Handlers.StoryGoalHandler.RegisterCustomEvent("AWFirstLethal", () =>
+        {
+            Main.logger.LogInfo("Revealing the WeaponsAuthorization PDA ency entry.");
+            try
+            {
+                PDAEncyclopedia.Reveal("Ency_WeaponsAuthorization", true);
+            }
+            catch(Exception ex)
+            {
+                Main.logger.LogError(ex.ToString());
+            }
+
+            try
+            {
+                PDAEncyclopedia.Reveal("WeaponsAuthoriazation", true);
+            }
+            catch (Exception ex)
+            {
+                Main.logger.LogError(ex.ToString());
+            }
+        });
+    }
+
+    internal static void PatchPDALogs()
+    {
+        Main.logger.LogInfo($"{Main.modName} {Main.modVers} Registering PDA Logs...");
+
+        // Presentation PDA log "Hello xenoworker 91802..."
+        if(Main.AssetsCache.TryGetAsset("PWAPresentation", out AudioClip PWAPresentation))
+        {
+            Main.logger.LogInfo("PWAPresentation audio message is being registered.");
+            if(Main.Options.allowDialogs)
+            {
+                Sound sound = AudioUtils.CreateSound(PWAPresentation, AudioUtils.StandardSoundModes_Stream);
+                CustomSoundHandler.RegisterCustomSound("PWAPresAudio", sound, AudioUtils.BusPaths.PDAVoice);
+                FMODAsset fmodAsset = AudioUtils.GetFmodAsset("PWAPresAudio");
+                PDAHandler.AddLogEntry(
+                    Main.AWPresentationGoal.key,
+                    "Subtitles_AWPresentation",
+                    sound: fmodAsset,
+                    SpriteManager.Get(SpriteManager.Group.Log, "Pda")
+                );
+            }
+            else
+            {
+                PDAHandler.AddLogEntry(
+                    Main.AWPresentationGoal.key,
+                    "Subtitles_AWPresentation",
+                    sound: null,
+                    SpriteManager.Get(SpriteManager.Group.Log, "Pda")
+                );
+            }
+        }
+
+        // First lethal weapon PDA log "A lethal weapon have been detected into your inventory..."
+        if(Main.AssetsCache.TryGetAsset("FirstLethalMessage", out AudioClip AWFirstLethal))
+        {
+            Main.logger.LogInfo("AWFirstLethal audio message is being registered.");
+            if(Main.Options.allowDialogs)
+            {
+                Sound sound = AudioUtils.CreateSound(AWFirstLethal, AudioUtils.StandardSoundModes_Stream);
+                CustomSoundHandler.RegisterCustomSound("FirstLethalMessage", sound, AudioUtils.BusPaths.PDAVoice);
+                FMODAsset fmodAsset = AudioUtils.GetFmodAsset("FirstLethalMessage");
+                PDAHandler.AddLogEntry(
+                    key: "AWFirstLethal",
+                    languageKey: "Subtitles_AWFirstLethal",
+                    sound: fmodAsset,
+                    SpriteManager.Get(SpriteManager.Group.Log, "Pda")
+                );
+            }
+            else
+            {
+                PDAHandler.AddLogEntry(
+                    key: "AWFirstLethal",
+                    languageKey: "Subtitles_AWFirstLethal",
+                    sound: null,
+                    SpriteManager.Get(SpriteManager.Group.Log, "Pda")
+                );
+            }
+            Main.logger.LogInfo("AWFirstLethal registered successfully.");
+
+        }
+
+        Main.logger.LogInfo($"{Main.modName} {Main.modVers} Registered PDA logs!");
+    }
+
+    internal static void PatchPDAEncyEntries()
+    {
+        // Register AWModInfo entry
+        PDAHandler.AddEncyclopediaEntry(
+            "AWModInfo",
+            "Meta",
+            null,
+            null,
+            unlockSound: PDAHandler.UnlockBasic
+        );
+
+        // Prawn laser arm entry
+        PDAHandler.AddEncyclopediaEntry(
+            "PrawnLaserArm",
+            "Tech/Weaponry",
+            null,
+            null,
+            unlockSound: PDAHandler.UnlockBasic
+        );
+
+        PDAHandler.AddEncyclopediaEntry(
+            "WeaponsAuthorization",
+            "Tech/Weaponry",
+            null,
+            null,
+            unlockSound: PDAHandler.UnlockImportant
+        );
+    }
+}
diff --git a/AlterraWeaponry/utils/LanguagesHandler.cs b/AlterraWeaponry/utils/LanguagesHandler.cs
index dc4ce23..5ccaa9d 100644
--- a/AlterraWeaponry/utils/LanguagesHandler.cs
+++ b/AlterraWeaponry/utils/LanguagesHandler.cs
@@ -1,4 +1,4 @@
-namespace VELD.AlterraWeaponry.utils
+namespace VELD.AlterraWeaponry.Utils
 {
     namespace LocalizationHandler
     {
@@ -39,7 +39,7 @@ public static void LanguagePatch()
             Main.logger.LogInfo("Starting patching the languages !");
             XmlSerializer serializer = new(typeof(LocalizationHandler.LocalizationPackages));
 
-            FileStream fs = new(Path.Combine(ModPath, filename), FileMode.Open);
+            FileStream fs = new(Path.Combine(ModPath, filename), FileMode.Open, FileAccess.Read);
             LocalizationHandler.LocalizationPackages lps;
 
             Main.logger.LogInfo(Language.main.GetCurrentLanguage());
@@ -56,7 +56,7 @@ public static void LanguagePatch()
                 if (Language.main.Get(text.key) != null)
                 {
                     LanguageHandler.SetLanguageLine(text.key, text.value);
-                    Main.logger.LogInfo($"Patched key {text.key} with text '{(text.value.Length > 50 ? text.value.Substring(50) : text.value)}'");
+                    Main.logger.LogInfo($"Patched key {text.key} with text '{(text.value.Length > 50 ? text.value.Substring(0, 50) + "..." : text.value)}'");
                 }
                 else
                 {
@@ -65,5 +65,29 @@ public static void LanguagePatch()
             }
             Main.logger.LogInfo("Language patching done.");
         }
+
+        public static void GlobalPatch()
+        {
+            Main.logger.LogInfo("Starting global patching...");
+            XmlSerializer serializer = new(typeof(LocalizationHandler.LocalizationPackages));
+
+            FileStream fs = new(Path.Combine(ModPath, filename), FileMode.Open, FileAccess.Read);
+            LocalizationHandler.LocalizationPackages lps;
+            
+            lps = (LocalizationHandler.LocalizationPackages)serializer.Deserialize(fs);
+
+            foreach (LocalizationHandler.LocalizationPackage locpack in lps.Localizations)
+            {
+                Main.logger.LogInfo(locpack.Lang);
+
+                foreach(LocalizationHandler.Text text in locpack.Texts)
+                {
+                    if (string.IsNullOrEmpty(text.value))
+                        continue;
+                    LanguageHandler.SetLanguageLine(text.key, text.value, locpack.Lang);
+                    Main.logger.LogInfo($"Patched key {text.key} with text '{(text.value.Length > 50 ? text.value.Substring(0, 50) + "..." : text.value)}'");
+                }
+            }
+        }
     }
 }
diff --git a/AlterraWeaponry/utils/Options.cs b/AlterraWeaponry/utils/Options.cs
new file mode 100644
index 0000000..bae28ee
--- /dev/null
+++ b/AlterraWeaponry/utils/Options.cs
@@ -0,0 +1,13 @@
+namespace VELD.AlterraWeaponry.Utils;
+
+[Menu("Alterra Weaponry")]
+public class Options : Nautilus.Json.ConfigFile
+{
+
+    [Toggle(LabelLanguageId = "Options.AW_DialogsBool", TooltipLanguageId = "Options.AW_DialogsBool.Tooltip", Order = 0)]
+    public bool allowDialogs = true;
+
+    [Slider(Min = 0.05f, Max = 24.00f, Step = 0.05f, Format = "x{0:F2}",
+        LabelLanguageId = "Options.AW_dmgMultiplier", TooltipLanguageId = "Options.AW_dmgMultiplier.Tooltip", Order = 1)]
+    public float dmgMultiplier = 1.0f;
+}
diff --git a/README.md b/README.md
index 0fdf421..89983c9 100644
--- a/README.md
+++ b/README.md
@@ -34,8 +34,9 @@ Main weapons:
 - **Unity 2019.4.36f1**: Bundling the assets
 
 ### Dependencies
-- **SMLHelper 2.14.1**
-- **BepInEx** (Latest)
+- [**Nautilus v1.0.0-pre.16+**](https://github.com/SubnauticaModding/Nautilus/releases)
+- [**CuddleLibs v1.0.1+**](https://github.com/VELD-Dev/CuddleLibs)
+- [**Tobey's BepInEx Pack**](https://github.com/toebeann/BepInEx.Subnautica/releases)
 
 This C# project is using **.NET 4.7.2** and **C# 11.0**.