diff --git a/QSB/AssetBundles/instruments b/QSB/AssetBundles/instruments
index 47d25411..14517dd5 100644
Binary files a/QSB/AssetBundles/instruments and b/QSB/AssetBundles/instruments differ
diff --git a/QSB/AssetBundles/network b/QSB/AssetBundles/network
index 5bd507bf..9ca5c6c5 100644
Binary files a/QSB/AssetBundles/network and b/QSB/AssetBundles/network differ
diff --git a/QSB/Audio/PlayerAudioManager.cs b/QSB/Audio/PlayerAudioManager.cs
deleted file mode 100644
index 95b1e2ac..00000000
--- a/QSB/Audio/PlayerAudioManager.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using UnityEngine;
-
-namespace QSB.Audio
-{
-	internal class PlayerAudioManager
-	{
-		public static QSBPlayerAudioController InitRemote(Transform playerBody)
-		{
-			var REMOTE_Audio_Player = new GameObject("REMOTE_Audio_Player");
-			REMOTE_Audio_Player.transform.parent = playerBody;
-			REMOTE_Audio_Player.transform.localPosition = Vector3.zero;
-			REMOTE_Audio_Player.transform.localScale = Vector3.one;
-
-			return REMOTE_Audio_Player.AddComponent<QSBPlayerAudioController>();
-		}
-	}
-}
diff --git a/QSB/Audio/QSBPlayerAudioController.cs b/QSB/Audio/QSBPlayerAudioController.cs
index c721c2f2..85b0d46f 100644
--- a/QSB/Audio/QSBPlayerAudioController.cs
+++ b/QSB/Audio/QSBPlayerAudioController.cs
@@ -7,21 +7,6 @@ namespace QSB.Audio
 		public OWAudioSource _oneShotExternalSource;
 		public OWAudioSource _repairToolSource;
 
-		private void Start()
-		{
-			_oneShotExternalSource = CreateBaseAudio(transform, "OneShotAudio_PlayerExternal", false, 0, 1, AudioType.None, OWAudioMixer.TrackName.Player_External, false);
-			_repairToolSource = CreateBaseAudio(transform, "RepairToolAudio", true, 128, 0.5f, AudioType.None, OWAudioMixer.TrackName.Player_External, false);
-
-			var thrusterAudio = new GameObject("REMOTE_ThrusterAudio").transform;
-			thrusterAudio.parent = transform;
-			var jetpatchThrusterAudio = thrusterAudio.gameObject.AddComponent<QSBJetpackThrusterAudio>();
-			jetpatchThrusterAudio._rotationalSource = CreateBaseAudio(thrusterAudio, "RotationalSource", false, 0, 1, AudioType.None, OWAudioMixer.TrackName.Player, false);
-			jetpatchThrusterAudio._translationalSource = CreateBaseAudio(thrusterAudio, "TranslationalSource", true, 0, 0.1f, AudioType.PlayerSuitJetpackThrustTranslational_LP, OWAudioMixer.TrackName.Player_External, false);
-			jetpatchThrusterAudio._underwaterSource = CreateBaseAudio(thrusterAudio, "UnderwaterSource", true, 0, 0.1f, AudioType.PlayerSuitJetpackThrustUnderwater_LP, OWAudioMixer.TrackName.Player_External, false);
-			jetpatchThrusterAudio._oxygenSource = CreateBaseAudio(thrusterAudio, "OxygenPropellantSource", true, 0, 0.2f, AudioType.PlayerSuitJetpackOxygenPropellant_LP, OWAudioMixer.TrackName.Player_External, false);
-			jetpatchThrusterAudio._boostSource = CreateBaseAudio(thrusterAudio, "BoosterSource", true, 0, 0.35f, AudioType.PlayerSuitJetpackBoost, OWAudioMixer.TrackName.Player_External, false);
-		}
-
 		public void PlayEquipTool()
 			=> _oneShotExternalSource?.PlayOneShot(AudioType.ToolTranslatorEquip);
 
@@ -33,43 +18,5 @@ namespace QSB.Audio
 
 		public void PlayTurnOffFlashlight()
 			=> _oneShotExternalSource?.PlayOneShot(AudioType.ToolFlashlightOff);
-
-		private OWAudioSource CreateBaseAudio(
-			Transform parent,
-			string name,
-			bool loop,
-			int priority,
-			float volume,
-			AudioType audioLibraryClip,
-			OWAudioMixer.TrackName track,
-			bool randomize)
-		{
-			var go = new GameObject(name);
-			go.SetActive(false);
-			go.transform.parent = parent;
-			go.transform.localPosition = Vector3.zero;
-			go.transform.localScale = Vector3.one;
-
-			var audioSource = go.AddComponent<AudioSource>();
-			audioSource.mute = false;
-			audioSource.bypassEffects = false;
-			audioSource.bypassListenerEffects = false;
-			audioSource.bypassReverbZones = false;
-			audioSource.playOnAwake = false;
-			audioSource.loop = loop;
-			audioSource.priority = priority;
-			audioSource.volume = volume;
-			audioSource.spatialBlend = 1f;
-
-			var owAudioSource = go.AddComponent<OWAudioSource>();
-			owAudioSource._audioLibraryClip = audioLibraryClip;
-			owAudioSource._clipSelectionOnPlay = OWAudioSource.ClipSelectionOnPlay.RANDOM;
-			owAudioSource._track = track;
-			owAudioSource._randomizePlayheadOnAwake = randomize;
-
-			go.SetActive(true);
-
-			return owAudioSource;
-		}
 	}
 }
diff --git a/QSB/PlayerBodySetup/Remote/FixMaterialsInAllChildren.cs b/QSB/PlayerBodySetup/Remote/FixMaterialsInAllChildren.cs
index 78d57d4b..e270220e 100644
--- a/QSB/PlayerBodySetup/Remote/FixMaterialsInAllChildren.cs
+++ b/QSB/PlayerBodySetup/Remote/FixMaterialsInAllChildren.cs
@@ -21,7 +21,10 @@ namespace QSB.PlayerBodySetup.Remote
 			"Effects_HEA_ScannerProjector_mat",
 			"Props_HEA_Lightbulb_mat",
 			"Props_HEA_PlayerTools_mat",
-			"Structure_HEA_PlayerShip_Screens_mat"
+			"Structure_HEA_PlayerShip_Screens_mat",
+			"Effects_RecallWhiteHole_mat",
+			"Effects_HEA_Vapor_mat",
+			"Props_HEA_Lightbulb_OFF_mat"
 		};
 
 		private static void ReplaceMaterial(Renderer renderer, int index, Material mat)
diff --git a/QSB/PlayerBodySetup/Remote/RemotePlayerCreation.cs b/QSB/PlayerBodySetup/Remote/RemotePlayerCreation.cs
index 3e6da49c..31239853 100644
--- a/QSB/PlayerBodySetup/Remote/RemotePlayerCreation.cs
+++ b/QSB/PlayerBodySetup/Remote/RemotePlayerCreation.cs
@@ -58,7 +58,7 @@ namespace QSB.PlayerBodySetup.Remote
 					.GetComponentsInChildren<Renderer>(true)
 					.Select(x => x.gameObject.GetAddComponent<OWRenderer>())
 					.ToArray());
-			player.AudioController = PlayerAudioManager.InitRemote(REMOTE_Player_Body.transform);
+			player.AudioController = REMOTE_Player_Body.transform.Find("REMOTE_Audio_Player").GetComponent<QSBPlayerAudioController>();
 
 			/*
 			 * SET UP PLAYER CAMERA
diff --git a/QSB/Tools/PlayerToolsManager.cs b/QSB/Tools/PlayerToolsManager.cs
index 335a4e93..af01513c 100644
--- a/QSB/Tools/PlayerToolsManager.cs
+++ b/QSB/Tools/PlayerToolsManager.cs
@@ -5,41 +5,14 @@ using QSB.Tools.SignalscopeTool;
 using QSB.Tools.TranslatorTool;
 using QSB.Utility;
 using System;
-using System.Linq;
 using UnityEngine;
 
 namespace QSB.Tools
 {
 	public class PlayerToolsManager
 	{
-		public static Transform StowTransform;
-		public static Transform HoldTransform;
-
-		public static Material Props_HEA_PlayerTool_mat;
-		public static Material Props_HEA_Lightbulb_mat;
-		public static Material Props_HEA_Lightbulb_OFF_mat;
-		public static Material Structure_HEA_PlayerShip_Screens_mat;
-
 		public static void InitRemote(PlayerInfo player)
 		{
-			try
-			{
-				CreateStowTransforms(player.CameraBody.transform);
-
-				var surfaceData = Locator.GetSurfaceManager()._surfaceLookupAsset;
-				var metal = surfaceData.surfaceTypeGroups[15].materials;
-				var glass = surfaceData.surfaceTypeGroups[19].materials;
-
-				Props_HEA_PlayerTool_mat = metal[27];
-				Props_HEA_Lightbulb_mat = glass[47];
-				Props_HEA_Lightbulb_OFF_mat = glass[48];
-				Structure_HEA_PlayerShip_Screens_mat = glass[41];
-			}
-			catch (Exception ex)
-			{
-				DebugLog.ToConsole($"Error when trying to find materials : {ex}", OWML.Common.MessageType.Error);
-			}
-
 			try
 			{
 				FlashlightCreator.CreateFlashlight(player);
@@ -65,14 +38,5 @@ namespace QSB.Tools
 				spot.GetLight().shadows = LightShadows.Soft;
 			}
 		}
-
-		private static void CreateStowTransforms(Transform cameraBody)
-		{
-			StowTransform = cameraBody.Find("REMOTE_ToolStowTransform");
-			HoldTransform = cameraBody.Find("REMOTE_ToolHoldTransform");
-		}
-
-		internal static MeshRenderer GetRenderer(GameObject root, string gameObjectName) =>
-			root.GetComponentsInChildren<MeshRenderer>(true).First(x => x.name == gameObjectName);
 	}
 }
\ No newline at end of file
diff --git a/QSB/Tools/ProbeLauncherTool/ProbeLauncherCreator.cs b/QSB/Tools/ProbeLauncherTool/ProbeLauncherCreator.cs
index 065d811f..c4e8b4e0 100644
--- a/QSB/Tools/ProbeLauncherTool/ProbeLauncherCreator.cs
+++ b/QSB/Tools/ProbeLauncherTool/ProbeLauncherCreator.cs
@@ -1,86 +1,23 @@
 using QSB.Player;
-using UnityEngine;
-using UnityEngine.Rendering;
+using QSB.PlayerBodySetup.Remote;
 
 namespace QSB.Tools.ProbeLauncherTool
 {
 	internal static class ProbeLauncherCreator
 	{
-		private static readonly Vector3 ProbeLauncherOffset = new(0.5745087f, -0.26f, 0.4453125f);
-
 		internal static void CreateProbeLauncher(PlayerInfo player)
 		{
-			var ProbeLauncher = GameObject.Find("PlayerCamera/ProbeLauncher");
+			var REMOTE_ProbeLauncher = player.CameraBody.transform.Find("REMOTE_ProbeLauncher").gameObject;
 
-			// Create new ProbeLauncher
-			var REMOTE_ProbeLauncher = new GameObject("REMOTE_ProbeLauncher");
-			REMOTE_ProbeLauncher.SetActive(false);
+			var REMOTE_Props_HEA_ProbeLauncher = REMOTE_ProbeLauncher.transform.Find("Props_HEA_ProbeLauncher");
 
-			// Copy children of ProbeLauncher
-			var Props_HEA_ProbeLauncher = ProbeLauncher.transform.Find("Props_HEA_ProbeLauncher");
-			var REMOTE_Props_HEA_ProbeLauncher = Object.Instantiate(Props_HEA_ProbeLauncher, REMOTE_ProbeLauncher.transform, false);
-
-			var LaunchParticleEffect_Underwater = ProbeLauncher.transform.Find("LaunchParticleEffect_Underwater");
-			var REMOTE_LaunchParticleEffect_Underwater = Object.Instantiate(LaunchParticleEffect_Underwater, REMOTE_ProbeLauncher.transform, false);
-
-			var LaunchParticleEffect = ProbeLauncher.transform.Find("LaunchParticleEffect");
-			var REMOTE_LaunchParticleEffect = Object.Instantiate(LaunchParticleEffect, REMOTE_ProbeLauncher.transform, false);
-
-			// Set up effects
-			var effects = REMOTE_ProbeLauncher.AddComponent<ProbeLauncherEffects>();
-			effects._launchParticles = REMOTE_LaunchParticleEffect.GetComponent<ParticleSystem>();
-			effects._underwaterLaunchParticles = REMOTE_LaunchParticleEffect_Underwater.GetComponent<ParticleSystem>();
-			effects._owAudioSource = player.AudioController._repairToolSource;
-
-			var recallEffect = REMOTE_Props_HEA_ProbeLauncher.Find("RecallEffect");
-
-			var arrow = REMOTE_Props_HEA_ProbeLauncher.Find("PressureGauge_Arrow");
-			arrow.GetComponent<MeshRenderer>().material = PlayerToolsManager.Props_HEA_PlayerTool_mat;
-			arrow.GetComponent<MeshRenderer>().shadowCastingMode = ShadowCastingMode.On;
-
-			var chassis = REMOTE_Props_HEA_ProbeLauncher.Find("ProbeLauncherChassis");
-			chassis.GetComponent<MeshRenderer>().material = PlayerToolsManager.Props_HEA_PlayerTool_mat;
-			chassis.GetComponent<MeshRenderer>().shadowCastingMode = ShadowCastingMode.On;
-			Object.Destroy(REMOTE_Props_HEA_ProbeLauncher.Find("Props_HEA_ProbeLauncher_Prepass").gameObject);
-
-			var preLaunchProbe = REMOTE_Props_HEA_ProbeLauncher.Find("Props_HEA_Probe_Prelaunch");
-			Object.Destroy(preLaunchProbe.Find("Props_HEA_Probe_Prelaunch_Prepass").gameObject);
-
-			// fuck you unity
-			var materials = preLaunchProbe.GetComponent<MeshRenderer>().materials;
-			materials[0] = PlayerToolsManager.Props_HEA_PlayerTool_mat;
-			materials[1] = PlayerToolsManager.Props_HEA_Lightbulb_OFF_mat;
-			preLaunchProbe.GetComponent<MeshRenderer>().materials = materials;
-
-			preLaunchProbe.GetComponent<MeshRenderer>().shadowCastingMode = ShadowCastingMode.On;
-
-			var tool = REMOTE_ProbeLauncher.AddComponent<QSBProbeLauncherTool>();
-			var spring = new DampedSpringQuat
-			{
-				velocity = Vector4.zero,
-				settings = new DampedSpringSettings
-				{
-					springConstant = 50f,
-					dampingCoefficient = 8.485282f,
-					mass = 1
-				}
-			};
-
-			tool.MoveSpring = spring;
-			tool.StowTransform = PlayerToolsManager.StowTransform;
-			tool.HoldTransform = PlayerToolsManager.HoldTransform;
-			tool.ArrivalDegrees = 5f;
+			var tool = REMOTE_ProbeLauncher.GetComponent<QSBProbeLauncherTool>();
 			tool.Type = ToolType.ProbeLauncher;
 			tool.ToolGameObject = REMOTE_Props_HEA_ProbeLauncher.gameObject;
 			tool.Player = player;
-			tool.PreLaunchProbeProxy = preLaunchProbe.gameObject;
-			tool.ProbeRetrievalEffect = recallEffect.GetComponent<SingularityWarpEffect>();
-			tool.Effects = effects;
 
-			REMOTE_ProbeLauncher.transform.parent = player.CameraBody.transform;
-			REMOTE_ProbeLauncher.transform.localPosition = ProbeLauncherOffset;
+			FixMaterialsInAllChildren.ReplaceMaterials(REMOTE_ProbeLauncher.transform);
 
-			//UnityEvents.FireInNUpdates(() => REMOTE_ProbeLauncher.SetActive(true), 5);
 			REMOTE_ProbeLauncher.SetActive(true);
 		}
 	}
diff --git a/QSB/Tools/SignalscopeTool/SignalscopeCreator.cs b/QSB/Tools/SignalscopeTool/SignalscopeCreator.cs
index dbcb70f5..00b17a97 100644
--- a/QSB/Tools/SignalscopeTool/SignalscopeCreator.cs
+++ b/QSB/Tools/SignalscopeTool/SignalscopeCreator.cs
@@ -1,6 +1,5 @@
 using QSB.Player;
-using UnityEngine;
-using UnityEngine.Rendering;
+using QSB.PlayerBodySetup.Remote;
 
 namespace QSB.Tools.SignalscopeTool
 {
@@ -10,8 +9,6 @@ namespace QSB.Tools.SignalscopeTool
 		{
 			var signalscopeRoot = player.CameraBody.transform.Find("REMOTE_Signalscope").gameObject;
 
-			signalscopeRoot.SetActive(false);
-
 			var Props_HEA_Signalscope = signalscopeRoot.transform.Find("Props_HEA_Signalscope");
 
 			var tool = signalscopeRoot.GetComponent<QSBTool>();
@@ -19,8 +16,7 @@ namespace QSB.Tools.SignalscopeTool
 			tool.ToolGameObject = Props_HEA_Signalscope.gameObject;
 			tool.Player = player;
 
-			Props_HEA_Signalscope.GetComponent<MeshRenderer>().material = PlayerToolsManager.Props_HEA_PlayerTool_mat;
-			Props_HEA_Signalscope.GetComponent<MeshRenderer>().shadowCastingMode = ShadowCastingMode.On;
+			FixMaterialsInAllChildren.ReplaceMaterials(signalscopeRoot.transform);
 
 			signalscopeRoot.SetActive(true);
 		}
diff --git a/QSB/Tools/TranslatorTool/TranslatorCreator.cs b/QSB/Tools/TranslatorTool/TranslatorCreator.cs
index 3174b185..04431082 100644
--- a/QSB/Tools/TranslatorTool/TranslatorCreator.cs
+++ b/QSB/Tools/TranslatorTool/TranslatorCreator.cs
@@ -1,4 +1,5 @@
 using QSB.Player;
+using QSB.PlayerBodySetup.Remote;
 
 namespace QSB.Tools.TranslatorTool
 {
@@ -14,6 +15,10 @@ namespace QSB.Tools.TranslatorTool
 			tool.Type = ToolType.Translator;
 			tool.ToolGameObject = REMOTE_TranslatorGroup.gameObject;
 			tool.Player = player;
+
+			FixMaterialsInAllChildren.ReplaceMaterials(REMOTE_NomaiTranslatorProp.transform);
+
+			REMOTE_NomaiTranslatorProp.SetActive(true);
 		}
 	}
 }