Stop allocating a new Vessel and CelestialBody every window frame because WTF.
Stop allocating a new Vessel and CelestialBody every window frame because WTF.

file:b/API/Enums.cs (new)
--- /dev/null
+++ b/API/Enums.cs
@@ -1,1 +1,25 @@
+// VOID © 2015 toadicus
+//
+// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
+// copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
+using System;
 
+namespace VOID
+{
+	public enum VOID_TimeScale : UInt32
+	{
+		KERBIN_TIME = 1, // Earth if 0
+		SOLAR_DAY = 4, // Sidereal if 0
+		ROUNDED_SCALE = 1024 // Real values if 0
+	}
+
+	public enum IconState : UInt32
+	{
+		PowerOff = 1,
+		PowerOn = 2,
+		Inactive = 4,
+		Active = 8
+	}
+}
+
+

--- a/API/VOIDCore.cs
+++ b/API/VOIDCore.cs
@@ -64,8 +64,11 @@
 		public abstract Stage LastStage { get; protected set; }
 		public abstract Stage[] Stages { get; protected set; }
 
+		public abstract VOID_TimeScale TimeScale { get; protected set; }
+
 		public abstract event VOIDEventHandler onApplicationQuit;
 		public abstract event VOIDEventHandler onSkinChanged;
+		public abstract event VOIDEventHandler onUpdate;
 
 		public virtual void OnGUI() {}
 

--- a/API/VOIDMaster.cs
+++ b/API/VOIDMaster.cs
@@ -127,8 +127,11 @@
 
 		protected virtual bool InValidScene()
 		{
-			foreach (var attr in this.GetType().GetCustomAttributes(true))
+			object[] attributes = this.GetType().GetCustomAttributes(true);
+			object attr;
+			for (int idx = 0; idx < attributes.Length; idx++)
 			{
+				attr = attributes[idx];
 				if (attr is KSPAddon)
 				{
 					KSPAddon addonAttr = (KSPAddon)attr;

--- a/API/VOID_HUDModule.cs
+++ b/API/VOID_HUDModule.cs
@@ -104,8 +104,11 @@
 				SimManager.RequestSimulation();
 			}
 
-			foreach (HUDWindow window in this.Windows)
-			{
+			HUDWindow window;
+			for (int idx = 0; idx < this.Windows.Count; idx++)
+			{
+				window = this.Windows[idx];
+
 				window.WindowPos = GUILayout.Window(
 					this.core.WindowID,
 					window.WindowPos,
@@ -127,8 +130,11 @@
 
 			if (GUILayout.Button(string.Intern("Reset HUD Positions"), GUILayout.ExpandWidth(false)))
 			{
-				foreach (HUDWindow window in this.Windows)
+				HUDWindow window;
+				for (int idx = 0; idx < this.Windows.Count; idx++)
 				{
+					window = this.Windows[idx];
+
 					window.WindowPos = new Rect(window.defaultWindowPos);
 				}
 			}
@@ -143,8 +149,11 @@
 			var config = KSP.IO.PluginConfiguration.CreateForType<VOID_HUDModule>();
 			config.load();
 
-			foreach (HUDWindow window in this.Windows)
-			{
+			HUDWindow window;
+			for (int idx = 0; idx < this.Windows.Count; idx++)
+			{
+				window = this.Windows[idx];
+
 				string saveName = string.Format("{0}_{1}", this.GetType().Name, window.WindowName);
 				Rect loadedPos = config.GetValue(saveName, window.defaultWindowPos);
 
@@ -156,8 +165,11 @@
 		{
 			base.Save(config);
 
-			foreach (HUDWindow window in this.Windows)
-			{
+			HUDWindow window;
+			for (int idx = 0; idx < this.Windows.Count; idx++)
+			{
+				window = this.Windows[idx];
+
 				string saveName = string.Format("{0}_{1}", this.GetType().Name, window.WindowName);
 				config.SetValue(saveName, window.WindowPos);
 			}

--- a/API/VOID_Module.cs
+++ b/API/VOID_Module.cs
@@ -28,7 +28,6 @@
 
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Reflection;
 using ToadicusTools;
 using UnityEngine;
@@ -118,8 +117,13 @@
 				if (this.validModes == null)
 				{
 					Tools.PostDebugMessage(this, "validModes is null when checking inValidGame; fetching attribute.");
-					foreach (var attr in this.GetType().GetCustomAttributes(false))
+
+					object[] attributes = this.GetType().GetCustomAttributes(false);
+					object attr;
+					for (int idx = 0; idx < attributes.Length; idx++)
 					{
+						attr = attributes[idx];
+
 						if (attr is VOID_GameModesAttribute)
 						{
 							VOID_GameModesAttribute addonAttr = (VOID_GameModesAttribute)attr;
@@ -158,8 +162,12 @@
 				if (this.validScenes == null)
 				{
 					Tools.PostDebugMessage(this, "validScenes is null when checking inValidScene; fetching attribute.");
-					foreach (var attr in this.GetType().GetCustomAttributes(false))
+					object[] attributes = this.GetType().GetCustomAttributes(false);
+					object attr;
+					for (int idx = 0; idx < attributes.Length; idx++)
 					{
+						attr = attributes[idx];
+
 						if (attr is VOID_ScenesAttribute)
 						{
 							VOID_ScenesAttribute addonAttr = (VOID_ScenesAttribute)attr;
@@ -253,30 +261,40 @@
 				}
 			}
 
-			foreach (var field in this.GetType().GetMembers(
-				BindingFlags.NonPublic |
-				BindingFlags.Public |
-				BindingFlags.Instance |
-				BindingFlags.FlattenHierarchy
-			))
-			{
-				if (!(field is FieldInfo || field is PropertyInfo))
+			MemberInfo[] members = this.GetType().GetMembers(
+				                         BindingFlags.NonPublic |
+				                         BindingFlags.Public |
+				                         BindingFlags.Instance |
+				                         BindingFlags.FlattenHierarchy
+			                         );
+			MemberInfo member;
+
+			for (int fIdx = 0; fIdx < members.Length; fIdx++)
+			{
+				member = members[fIdx];
+
+				if (!(member is FieldInfo || member is PropertyInfo))
 				{
 					continue;
 				}
 
-				if (field is PropertyInfo && (field as PropertyInfo).GetIndexParameters().Length > 0)
+				if (member is PropertyInfo && (member as PropertyInfo).GetIndexParameters().Length > 0)
 				{
 					continue;
 				}
 
-				object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
-
-				if (attrs.Length == 0) {
+				object[] attrs = member.GetCustomAttributes(typeof(AVOID_SaveValue), false);
+
+				AVOID_SaveValue attr;
+
+				if (attrs.Length > 0)
+				{
+					attr = (AVOID_SaveValue)attrs[0];
+				}
+				else
+				{
 					continue;
 				}
-
-				AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
 
 				string fieldName = string.Empty;
 
@@ -312,13 +330,13 @@
 
 				object fieldValue;
 
-				if (field is FieldInfo)
-				{
-					fieldValue = (field as FieldInfo).GetValue(this);
-				}
-				else
-				{
-					fieldValue = (field as PropertyInfo).GetValue(this, null);
+				if (member is FieldInfo)
+				{
+					fieldValue = (member as FieldInfo).GetValue(this);
+				}
+				else
+				{
+					fieldValue = (member as PropertyInfo).GetValue(this, null);
 				}
 
 				bool convertBack = false;
@@ -338,13 +356,13 @@
 					fieldValue = convertValue;
 				}
 
-				if (field is FieldInfo)
-				{
-					(field as FieldInfo).SetValue(this, fieldValue);
-				}
-				else
-				{
-					(field as PropertyInfo).SetValue(this, fieldValue, null);
+				if (member is FieldInfo)
+				{
+					(member as FieldInfo).SetValue(this, fieldValue);
+				}
+				else
+				{
+					(member as PropertyInfo).SetValue(this, fieldValue, null);
 				}
 
 				Tools.PostDebugMessage(string.Format("{0}: Loaded field {1}.", this.GetType().Name, fieldName));
@@ -353,20 +371,30 @@
 
 		public virtual void Save(KSP.IO.PluginConfiguration config)
 		{
-			foreach (var field in this.GetType().GetMembers(
-				BindingFlags.Instance |
+			MemberInfo[] members = this.GetType().GetMembers(
 				BindingFlags.NonPublic |
 				BindingFlags.Public |
+				BindingFlags.Instance |
 				BindingFlags.FlattenHierarchy
-				))
-			{
-				object[] attrs = field.GetCustomAttributes(typeof(AVOID_SaveValue), false);
-
-				if (attrs.Length == 0) {
+			);
+			MemberInfo member;
+
+			for (int fIdx = 0; fIdx < members.Length; fIdx++)
+			{
+				member = members[fIdx];
+
+				object[] attrs = member.GetCustomAttributes(typeof(AVOID_SaveValue), false);
+
+				AVOID_SaveValue attr;
+
+				if (attrs.Length > 0)
+				{
+					attr = (AVOID_SaveValue)attrs[0];
+				}
+				else
+				{
 					continue;
 				}
-
-				AVOID_SaveValue attr = attrs.FirstOrDefault () as AVOID_SaveValue;
 
 				string fieldName;
 
@@ -386,13 +414,13 @@
 
 				object fieldValue;
 
-				if (field is FieldInfo)
-				{
-					fieldValue = (field as FieldInfo).GetValue(this);
-				}
-				else
-				{
-					fieldValue = (field as PropertyInfo).GetValue(this, null);
+				if (member is FieldInfo)
+				{
+					fieldValue = (member as FieldInfo).GetValue(this);
+				}
+				else
+				{
+					fieldValue = (member as PropertyInfo).GetValue(this, null);
 				}
 
 				if (fieldValue is IVOID_SaveValue)

--- /dev/null
+++ b/API/VOID_SingletonCore.cs
@@ -1,1 +1,69 @@
+// VOID
+//
+// VOID_SingletonModule.cs
+//
+// Copyright © 2015, toadicus
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+//    this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation and/or other
+//    materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+//    to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+using System;
 
+namespace VOID
+{
+	public abstract class VOID_SingletonCore<T> : VOIDCore, IVOID_Module, IDisposable
+		where T : VOID_Module, new()
+	{
+		#region Singleton Members
+		/*
+		 * Static Members
+		 * */
+		protected static bool _initialized = false;
+
+		public static bool Initialized
+		{
+			get
+			{
+				return _initialized;
+			}
+		}
+
+		protected static T _instance;
+
+		public static T Instance
+		{
+			get
+			{
+				if (_instance == null)
+				{
+					_instance = new T();
+					_initialized = true;
+				}
+				return _instance;
+			}
+		}
+
+		public abstract void Dispose();
+		#endregion
+	}
+}
+
+

--- a/API/VOID_SingletonModule.cs
+++ /dev/null
@@ -1,67 +1,1 @@
-// VOID
-//
-// VOID_SingletonModule.cs
-//
-// Copyright © 2015, toadicus
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-//    this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation and/or other
-//    materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its contributors may be used
-//    to endorse or promote products derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-using System;
 
-namespace VOID
-{
-	public abstract class VOID_SingletonModule<T> : VOIDCore, IVOID_Module
-		where T : VOID_Module, new()
-	{
-		#region Singleton Members
-		/*
-		 * Static Members
-		 * */
-		protected static bool _initialized = false;
-
-		public static bool Initialized
-		{
-			get
-			{
-				return _initialized;
-			}
-		}
-
-		protected static T _instance;
-
-		public static T Instance
-		{
-			get
-			{
-				if (_instance == null)
-				{
-					_instance = new T();
-					_initialized = true;
-				}
-				return _instance;
-			}
-		}
-		#endregion
-	}
-}
-
-

--- /dev/null
+++ b/API/VOID_SingletonWindow.cs
@@ -1,1 +1,73 @@
+// VOID
+//
+// VOID_SingletonModule.cs
+//
+// Copyright © 2015, toadicus
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+//    this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation and/or other
+//    materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be used
+//    to endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+using System;
 
+namespace VOID
+{
+	public abstract class VOID_SingletonWindow<T> : VOID_WindowModule, IVOID_Module, IDisposable
+		where T : VOID_WindowModule, new()
+	{
+		#region Singleton Members
+		/*
+		 * Static Members
+		 * */
+		protected static bool _initialized = false;
+
+		public static bool Initialized
+		{
+			get
+			{
+				return _initialized;
+			}
+		}
+
+		protected static T _instance;
+
+		public static T Instance
+		{
+			get
+			{
+				if (_instance == null)
+				{
+					_instance = new T();
+					_initialized = true;
+				}
+				return _instance;
+			}
+		}
+
+		public virtual void Dispose()
+		{
+			_instance = null;
+			_initialized = false;
+		}
+		#endregion
+	}
+}
+
+

--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -39,7 +39,7 @@
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion("0.16.4.*")]
+[assembly: AssemblyVersion("0.18.2.*")]
 // The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]

--- a/Tools/VOID_DataValue.cs
+++ b/Tools/VOID_DataValue.cs
@@ -229,7 +229,7 @@
 		}
 		
 		public virtual string ValueUnitString(int digits) {
-			return Tools.MuMech_ToSI(this, digits) + this.Units;
+			return string.Format("{0}{1}", SIFormatProvider.ToSI(this, digits), Units);
 		}
 
 		public virtual string ValueUnitString(int digits, int MinMagnitude, int MaxMagnitude)
@@ -264,26 +264,17 @@
 
 		public virtual int DoGUIHorizontalPrec(int digits)
 		{
-			double magnitude;
-			double magLimit;
-
-			magnitude = Math.Log10(Math.Abs((double)this));
-
-			magLimit = Math.Max(Math.Abs(magnitude), 3d) + 3d;
-			magLimit = Math.Round(Math.Ceiling(magLimit / 3f)) * 3d;
+			if (digits < 0 || digits > 8)
+			{
+				digits = 5;
+			}
 
 			GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 			GUILayout.Label(this.Label + "ⁱ:", GUILayout.ExpandWidth(true));
 			GUILayout.FlexibleSpace();
 
-			if (magnitude >= 0)
-			{
-				GUILayout.Label(this.ValueUnitString(3, int.MinValue, (int)magnitude - digits), GUILayout.ExpandWidth(false));
-			}
-			else
-			{
-				GUILayout.Label(this.ValueUnitString(3, (int)magnitude + digits, int.MaxValue), GUILayout.ExpandWidth(false));
-			}
+			GUILayout.Label(this.ValueUnitString(digits), GUILayout.ExpandWidth(false));
+
 			GUILayout.EndHorizontal();
 
 			if (Event.current.type == EventType.mouseUp)
@@ -291,33 +282,28 @@
 				Rect lastRect = GUILayoutUtility.GetLastRect();
 				if (lastRect.Contains(Event.current.mousePosition))
 				{
-					Tools.PostDebugMessage(string.Format("{0}: Changing digits from {1} within magLimit {2}.",
+					Tools.PostDebugMessage(string.Format("{0}: Changing digits from {1}",
 						this.GetType().Name,
-						digits,
-						magLimit));
+						digits
+					));
 
 					if (Event.current.button == 0)
 					{
-						digits = (digits + 3) % (int)magLimit;
+						digits = (digits + 3) % 9;
 					}
 					else if (Event.current.button == 1)
 					{
-						digits = (digits - 3) % (int)magLimit;
+						digits = (digits - 3) % 9;
 					}
 
 					if (digits < 0)
 					{
-						digits += (int)magLimit;
+						digits += 9;
 					}
 
-					Tools.PostDebugMessage(string.Format("{0}: Changed digits to {1}." +
-						"\n\tNew minMagnitude: {2}, maxMagnitude: {3}" +
-						"\n\tMagnitude: {4}",
+					Tools.PostDebugMessage(string.Format("{0}: Changed digits to {1}.",
 						this.GetType().Name,
-						digits,
-						magnitude >= 0 ? int.MinValue : (int)magnitude - 4 + digits,
-						magnitude >= 0 ? (int)magnitude - digits : int.MaxValue,
-						magnitude
+						digits
 					));
 				}
 			}

--- a/Tools/VOID_Tools.cs
+++ b/Tools/VOID_Tools.cs
@@ -414,28 +414,55 @@
 			{
 				get
 				{
-					if (GameSettings.KERBIN_TIME)
+					VOID_TimeScale flags = VOID_Data.Core.TimeScale &
+						(VOID_TimeScale.KERBIN_TIME | VOID_TimeScale.SOLAR_DAY | VOID_TimeScale.ROUNDED_SCALE);
+
+					switch (flags)
 					{
-						return 21600d;
+						// Earth day, sidereal
+						case 0:
+							return 86164.1d;
+						// Earth day, solar (also rounded)
+						case VOID_TimeScale.ROUNDED_SCALE | VOID_TimeScale.SOLAR_DAY:
+						case VOID_TimeScale.ROUNDED_SCALE:
+						case VOID_TimeScale.SOLAR_DAY:
+							return 86400d;
+						// Kerbin day, solar
+						case VOID_TimeScale.KERBIN_TIME | VOID_TimeScale.SOLAR_DAY:
+							return 21650.813d;
+						// Kerbin day, sidereal (also rounded)
+						default:
+							return 21600d;
 					}
-					else
+				}
+			}
+
+			public static double SecondsPerYear
+			{
+				get
+				{
+					VOID_TimeScale flags = VOID_Data.Core.TimeScale &
+						(VOID_TimeScale.KERBIN_TIME | VOID_TimeScale.SOLAR_DAY | VOID_TimeScale.ROUNDED_SCALE);
+
+					switch (flags)
 					{
-						return 86164.1d;
-					}
-				}
-			}
-
-			public static double SecondsPerYear
-			{
-				get
-				{
-					if (GameSettings.KERBIN_TIME)
-					{
-						return 9203545d;
-					}
-					else
-					{
-						return 31558149d;
+						// Earth year, rounded
+						case VOID_TimeScale.SOLAR_DAY | VOID_TimeScale.ROUNDED_SCALE:
+						case VOID_TimeScale.ROUNDED_SCALE:
+							return 60 * 60 * 24 * 365;
+						// Kerbin year, rounded
+						case VOID_TimeScale.KERBIN_TIME | VOID_TimeScale.SOLAR_DAY | VOID_TimeScale.ROUNDED_SCALE:
+						case VOID_TimeScale.KERBIN_TIME | VOID_TimeScale.ROUNDED_SCALE:
+							return 60 * 60 * 6 * 426;
+						// Earth year, solar time
+						case VOID_TimeScale.SOLAR_DAY:
+							return 31556925.2507328;
+						// Earth year, sidereal time
+						case 0:
+							return 31558149.7635456d;
+						// Kerbin year, solar & sidereal time
+						default:
+							return 9203544.61750141d;
 					}
 				}
 			}

--- a/VOID.csproj
+++ b/VOID.csproj
@@ -106,7 +106,6 @@
     <Compile Include="Tools\VOID_DataValue.cs" />
     <Compile Include="Tools\VOID_SaveValue.cs" />
     <Compile Include="API\VOID_HUDModule.cs" />
-    <Compile Include="API\VOID_SingletonModule.cs" />
     <Compile Include="API\Attributes\VOID_ScenesAttribute.cs" />
     <Compile Include="API\Attributes\AVOID_SaveValue.cs" />
     <Compile Include="API\VOIDMaster.cs" />
@@ -114,6 +113,9 @@
     <Compile Include="VOID_ConfigWindow.cs" />
     <Compile Include="Tools\VOID_Localization.cs" />
     <Compile Include="Tools\VOID_StageExtensions.cs" />
+    <Compile Include="API\VOID_SingletonCore.cs" />
+    <Compile Include="API\VOID_SingletonWindow.cs" />
+    <Compile Include="API\Enums.cs" />
   </ItemGroup>
   <ProjectExtensions>
     <MonoDevelop>

--- a/VOIDCore_Editor.cs
+++ b/VOIDCore_Editor.cs
@@ -30,7 +30,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using ToadicusTools;
 using UnityEngine;
 

--- a/VOIDCore_Generic.cs
+++ b/VOIDCore_Generic.cs
@@ -26,18 +26,19 @@
 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+using KerbalEngineer.Editor;
+using KerbalEngineer.Helpers;
 using KerbalEngineer.VesselSimulator;
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using ToadicusTools;
 using UnityEngine;
 
 namespace VOID
 {
-	public abstract class VOIDCore_Generic<T> : VOID_SingletonModule<T>, IVOID_Module, IDisposable
+	public abstract class VOIDCore_Generic<T> : VOID_SingletonCore<T>, IVOID_Module, IDisposable
 		where T : VOID_Module, new()
 	{
 		/*
@@ -58,7 +59,8 @@
 		protected string VOIDIconOffActivePath;
 		protected string VOIDIconOffInactivePath;
 
-		private bool _useToolbarManager;
+		[AVOID_SaveValue("useToolbarManager")]
+		protected VOID_SaveValue<bool> useToolbarManager;
 
 		protected GUIStyle iconStyle;
 
@@ -90,8 +92,12 @@
 		[AVOID_SaveValue("vesselSimActive")]
 		protected VOID_SaveValue<bool> vesselSimActive;
 
-		// Vessel Type Housekeeping
+		[AVOID_SaveValue("timeScaleFlags")]
+		protected VOID_SaveValue<UInt32> timeScaleFlags;
+
+		// Load-up housekeeping
 		protected bool vesselTypesLoaded = false;
+		protected bool simManagerLoaded = false;
 
 		protected string defaultSkin = "KSP window 2";
 
@@ -100,7 +106,7 @@
 		protected int skinIdx;
 
 		protected Dictionary<string, GUISkin> validSkins;
-		protected string[] skinNames;
+		protected List<string> skinNames;
 		protected string[] forbiddenSkins =
 			{
 				"PlaqueDialogSkin",
@@ -119,14 +125,29 @@
 
 		public override bool configDirty { get; set; }
 
-		internal IButton ToolbarButton;
-
-		internal ApplicationLauncherButton AppLauncherButton;
+		protected IButton ToolbarButton;
+		protected ApplicationLauncherButton AppLauncherButton;
+		protected IconState iconState;
 
 		/*
 		 * Properties
 		 * */
-
+		public override bool Active
+		{
+			get
+			{
+				return base.Active;
+			}
+			set
+			{
+				if (value != base.Active)
+				{
+					this.SetIconTexture(this.powerState | this.activeState);
+				}
+
+				base.Active = value;
+			}
+		}
 		public override IList<CelestialBody> AllBodies
 		{
 			get
@@ -242,6 +263,18 @@
 			protected set;
 		}
 
+		public override VOID_TimeScale TimeScale
+		{
+			get
+			{
+				return (VOID_TimeScale)this.timeScaleFlags.value;
+			}
+			protected set
+			{
+				this.timeScaleFlags.value = (UInt32)value;
+			}
+		}
+
 		protected IconState activeState
 		{
 			get
@@ -279,47 +312,16 @@
 			get
 			{
 				return HighLogic.LoadedScene.ToAppScenes();
-			}
-		}
-
-		protected bool useToolbarManager
-		{
-			get
-			{
-				return _useToolbarManager & ToolbarManager.ToolbarAvailable;
-			}
-			set
-			{
-				if (_useToolbarManager == value)
-				{
-					return;
-				}
-
-				if (value == false && this.ToolbarButton != null)
-				{
-					this.ToolbarButton.Destroy();
-					this.ToolbarButton = null;
-				}
-				if (value == true)
-				{
-					if (this.AppLauncherButton != null)
-					{
-						ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
-						this.AppLauncherButton = null;
-					}
-
-					this.InitializeToolbarButton();
-				}
-
-				_useToolbarManager = value;
 			}
 		}
 
 		/*
 		 * Events
 		 * */
+		// public 
 		public override event VOIDEventHandler onApplicationQuit;
 		public override event VOIDEventHandler onSkinChanged;
+		public override event VOIDEventHandler onUpdate;
 
 		/*
 		 * Methods
@@ -351,26 +353,14 @@
 					this.useToolbarManager);
 			}
 
-			if (!this.useToolbarManager)
-			{
-				if (this.AppLauncherButton == null)
-				{
-					Tools.PostDebugMessage(this,
-						"UseToolbarManager = false (ToolbarAvailable = {0}) and " +
-						"AppLauncherButton is null, making AppLauncher button.",
-						ToolbarManager.ToolbarAvailable
-					);
-					this.InitializeAppLauncherButton();
-				}
-			}
-			else if (this.ToolbarButton == null)
-			{
-				Tools.PostDebugMessage(this,
-					"UseToolbarManager = true (ToolbarAvailable = {0}) and " +
-					"ToolbarButton is null, making Toolbar button.",
-					ToolbarManager.ToolbarAvailable
-				);
-				this.InitializeToolbarButton();
+			if (
+				this.iconState != (this.powerState | this.activeState) ||
+				(this.VOIDIconTexture == null && this.AppLauncherButton != null)
+			)
+			{
+				this.iconState = this.powerState | this.activeState;
+
+				this.SetIconTexture(this.iconState);
 			}
 
 			if (this.Active)
@@ -404,8 +394,11 @@
 				this.StartGUI();
 			}
 
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				if (
 					!module.GUIRunning &&
 					module.Active &&
@@ -441,8 +434,58 @@
 				}
 			}
 
-			this.CheckAndSave();
+			if (this.useToolbarManager)
+			{
+				if (this.AppLauncherButton != null)
+				{
+					ApplicationLauncher.Instance.RemoveModApplication(this.AppLauncherButton);
+					this.AppLauncherButton = null;
+				}
+
+				if (this.ToolbarButton == null)
+				{
+					this.InitializeToolbarButton();
+				}
+			}
+			else
+			{
+				if (this.ToolbarButton != null)
+				{
+					this.ToolbarButton.Destroy();
+					this.ToolbarButton = null;
+				}
+
+				if (this.AppLauncherButton == null)
+				{
+					this.InitializeAppLauncherButton();
+				}
+
+			}
+
+			this.saveTimer += Time.deltaTime;
+
+			if (this.saveTimer > 2f)
+			{
+				if (this.configDirty)
+				{
+
+					Tools.PostDebugMessage(string.Format(
+							"{0}: Time to save, checking if configDirty: {1}",
+							this.GetType().Name,
+							this.configDirty
+						));
+
+					this.SaveConfig();
+					this.saveTimer = 0;
+				}
+			}
+
 			this.UpdateTimer += Time.deltaTime;
+
+			if (this.onUpdate != null)
+			{
+				this.onUpdate(this);
+			}
 		}
 
 		public virtual void FixedUpdate()
@@ -470,12 +513,14 @@
 				if (this.powerAvailable != newPowerState)
 				{
 					this.powerAvailable = newPowerState;
-					this.SetIconTexture(this.powerState | this.activeState);
-				}
-			}
-
-			foreach (IVOID_Module module in this.modules)
-			{
+				}
+			}
+
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				if (module is IVOID_BehaviorModule)
 				{
 					((IVOID_BehaviorModule)module).FixedUpdate();
@@ -485,8 +530,11 @@
 
 		public void OnDestroy()
 		{
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				if (module is IVOID_BehaviorModule)
 				{
 					((IVOID_BehaviorModule)module).OnDestroy();
@@ -518,8 +566,11 @@
 		{
 			this.StopGUI();
 
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				module.StopGUI();
 				module.StartGUI();
 			}
@@ -541,14 +592,16 @@
 					if (GUILayout.Button("Power " + str))
 					{
 						togglePower.value = !togglePower;
-						this.SetIconTexture(this.powerState | this.activeState);
 					}
 				}
 
 				if (togglePower || !HighLogic.LoadedSceneIsFlight)
 				{
-					foreach (IVOID_Module module in this.modules)
+					IVOID_Module module;
+					for (int idx = 0; idx < this.modules.Count; idx++)
 					{
+						module = this.modules[idx];
+
 						if (module is VOID_ConfigWindow)
 						{
 							continue;
@@ -577,10 +630,61 @@
 		{
 			GUIContent _content;
 
-			this.useToolbarManager = GUITools.Toggle(this.useToolbarManager, "Use Blizzy's Toolbar If Available");
+			this.useToolbarManager.value = GUITools.Toggle(this.useToolbarManager, "Use Blizzy's Toolbar If Available");
 
 			this.vesselSimActive.value = GUITools.Toggle(this.vesselSimActive.value,
 				"Enable Engineering Calculations");
+
+			bool useEarthTime = (this.TimeScale & VOID_TimeScale.KERBIN_TIME) == 0u;
+			bool useSiderealTime = (this.TimeScale & VOID_TimeScale.SOLAR_DAY) == 0u;
+			bool useRoundedScale = (this.TimeScale & VOID_TimeScale.ROUNDED_SCALE) != 0u;
+
+			useEarthTime = GUITools.Toggle(useEarthTime, "Use Earth Time (changes KSP option)");
+
+			GameSettings.KERBIN_TIME = !useEarthTime;
+
+			useSiderealTime = GUITools.Toggle(
+				useSiderealTime,
+				string.Format(
+					"Time Scale: {0}",
+					useSiderealTime ? "Sidereal" : "Solar"
+				)
+			);
+
+			useRoundedScale = GUITools.Toggle(
+				useRoundedScale,
+				string.Format(
+					"Time Scale: {0}",
+					useRoundedScale ? "Rounded" : "True"
+				)
+			);
+
+			if (useEarthTime)
+			{
+				this.TimeScale &= ~VOID_TimeScale.KERBIN_TIME;
+			}
+			else
+			{
+				this.TimeScale |= VOID_TimeScale.KERBIN_TIME;
+			}
+
+			if (useSiderealTime)
+			{
+				this.TimeScale &= ~VOID_TimeScale.SOLAR_DAY;
+			}
+			else
+			{
+				this.TimeScale |= VOID_TimeScale.SOLAR_DAY;
+			}
+
+			if (useRoundedScale)
+			{
+				this.TimeScale |= VOID_TimeScale.ROUNDED_SCALE;
+			}
+			else
+			{
+				this.TimeScale &= ~VOID_TimeScale.ROUNDED_SCALE;
+			}
 
 			GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 
@@ -618,10 +722,10 @@
 				));
 			}
 
-			this.skinIdx %= this.skinNames.Length;
+			this.skinIdx %= this.skinNames.Count;
 			if (this.skinIdx < 0)
 			{
-				this.skinIdx += this.skinNames.Length;
+				this.skinIdx += this.skinNames.Count;
 			}
 
 			if (this.skinName != skinNames[this.skinIdx])
@@ -648,9 +752,12 @@
 			}
 			GUILayout.EndHorizontal();
 
-			foreach (IVOID_Module mod in this.modules)
-			{
-				mod.DrawConfigurables();
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
+				module.DrawConfigurables();
 			}
 
 			this.FactoryReset = GUITools.Toggle(this.FactoryReset, "Factory Reset");
@@ -658,28 +765,26 @@
 
 		protected void UpdateSimManager()
 		{
-			if (SimManager.ResultsReady())
-			{
-				if (HighLogic.LoadedSceneIsEditor)
-				{
-					SimManager.Gravity = VOID_Data.KerbinGee;
-				}
-				else
-				{
-					double radius = this.Vessel.Radius();
-					SimManager.Gravity = this.Vessel.mainBody.gravParameter / (radius * radius);
-				}
-
-				SimManager.minSimTime = new TimeSpan(0, 0, 0, 0, (int)(this.UpdatePeriod * 1000d));
-
-				SimManager.TryStartSimulation();
-			}
+			if (HighLogic.LoadedSceneIsFlight)
+			{
+				double radius = this.Vessel.Radius();
+				SimManager.Gravity = this.Vessel.mainBody.gravParameter / (radius * radius);
+				SimManager.Atmosphere = this.Vessel.staticPressurekPa * PhysicsGlobals.KpaToAtmospheres;
+				SimManager.Mach = this.Vessel.mach;
+				BuildAdvanced.Altitude = this.Vessel.altitude;
+				CelestialBodies.SelectedBody = this.Vessel.mainBody;
+			}
+
 			#if DEBUG
-			else
-			{
-				Tools.PostDebugMessage(this, "VesselSimulator results not ready.");
-			}
+			SimManager.logOutput = true;
 			#endif
+
+			SimManager.TryStartSimulation();
+
+			Tools.PostDebugMessage(this, "Started Engineer simulation with Atmosphere={0} atm and Gravity={1} m/s²",
+				SimManager.Atmosphere,
+				SimManager.Gravity
+			);
 		}
 
 		protected void GetSimManagerResults()
@@ -688,9 +793,9 @@
 
 			this.Stages = SimManager.Stages;
 
-			if (this.Stages != null)
-			{
-				this.LastStage = this.Stages.Last();
+			if (this.Stages != null && this.Stages.Length > 0)
+			{
+				this.LastStage = this.Stages[this.Stages.Length - 1];
 			}
 		}
 
@@ -699,10 +804,17 @@
 			Tools.DebugLogger sb = Tools.DebugLogger.New(this);
 			sb.AppendLine("Loading modules...");
 
-			foreach (AssemblyLoader.LoadedAssembly assy in AssemblyLoader.loadedAssemblies)
-			{
-				foreach (Type loadedType in assy.assembly.GetExportedTypes())
-				{
+			AssemblyLoader.LoadedAssembly assy;
+			for (int aIdx = 0; aIdx < AssemblyLoader.loadedAssemblies.Count; aIdx++)
+			{
+				assy = AssemblyLoader.loadedAssemblies[aIdx];
+
+				Type[] loadedTypes = assy.assembly.GetExportedTypes();
+				Type loadedType;
+				for (int tIdx = 0; tIdx < loadedTypes.Length; tIdx++)
+				{
+					loadedType = loadedTypes[tIdx];
+
 					if (
 						loadedType.IsInterface ||
 						loadedType.IsAbstract ||
@@ -740,20 +852,22 @@
 
 		protected void LoadModule(Type T)
 		{
-			var existingModules = this.modules.Where(mod => mod.GetType().Name == T.Name);
-			if (existingModules.Any())
-			{
-				Tools.PostDebugMessage(string.Format(
-					"{0}: refusing to load {1}: already loaded",
-					this.GetType().Name,
-					T.Name
-				));
-				return;
+			/*var existingModules = this.modules.Where(mod => mod.GetType().Name == T.Name);
+			if (existingModules.Any())*/
+			for (int mIdx = 0; mIdx < this.modules.Count; mIdx++)
+			{
+				if (this.modules[mIdx].Name == T.Name)
+				{
+					Tools.PostErrorMessage("{0}: refusing to load {1}: already loaded", this.GetType().Name, T.Name);
+					return;
+				}
 			}
 
 			var InstanceProperty = T.GetProperty(
 				"Instance",
-				System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public
+				System.Reflection.BindingFlags.Static |
+				System.Reflection.BindingFlags.Public |
+				System.Reflection.BindingFlags.FlattenHierarchy
 			);
 
 			object modInstance = null;
@@ -784,24 +898,32 @@
 						T.Name
 					));
 			}
+			else
+			{
+				if (module is IDisposable)
+				{
+					(module as IDisposable).Dispose();
+				}
+			}
 		}
 
 		protected void LoadSkins()
 		{
-			Tools.PostDebugMessage("AssetBase has skins: \n" +
-				string.Join("\n\t",
-					Resources.FindObjectsOfTypeAll(typeof(GUISkin))
-					.Select(s => s.ToString())
-					.ToArray()
-				)
-			);
-
-			this.validSkins = Resources.FindObjectsOfTypeAll(typeof(GUISkin))
-				.Where(s => !this.forbiddenSkins.Contains(s.name))
-				.Select(s => s as GUISkin)
-				.GroupBy(s => s.name)
-				.Select(g => g.First())
-				.ToDictionary(s => s.name);
+			this.validSkins = new Dictionary<string, GUISkin>();
+			this.skinNames = new List<string>();
+
+			UnityEngine.Object[] skins = Resources.FindObjectsOfTypeAll(typeof(GUISkin));
+			GUISkin skin;
+			for (int sIdx = 0; sIdx < skins.Length; sIdx++)
+			{
+				skin = (GUISkin)skins[sIdx];
+
+				if (!this.forbiddenSkins.Contains(skin.name))
+				{
+					this.validSkins[skin.name] = skin;
+					this.skinNames.Add(skin.name);
+				}
+			}
 
 			Tools.PostDebugMessage(string.Format(
 				"{0}: loaded {1} GUISkins.",
@@ -809,12 +931,11 @@
 				this.validSkins.Count
 			));
 
-			this.skinNames = this.validSkins.Keys.ToArray();
-			Array.Sort(this.skinNames);
+			this.skinNames.Sort();
 
 			int defaultIdx = int.MinValue;
 
-			for (int i = 0; i < this.skinNames.Length; i++)
+			for (int i = 0; i < this.skinNames.Count; i++)
 			{
 				if (this.skinNames[i] == this.skinName)
 				{
@@ -856,17 +977,19 @@
 			this.GUIStylesLoaded = true;
 		}
 
-		protected void LoadVesselTypes()
-		{
-			this.AllVesselTypes = Enum.GetValues(typeof(VesselType)).OfType<VesselType>().ToArray();
-			this.vesselTypesLoaded = true;
-		}
-
 		protected void LoadBeforeUpdate()
 		{
 			if (!this.vesselTypesLoaded)
 			{
-				this.LoadVesselTypes();
+				Array typeObjs = Enum.GetValues(typeof(VesselType));
+				this.AllVesselTypes = new VesselType[typeObjs.Length];
+
+				for (int idx = 0; idx < typeObjs.Length; idx++)
+				{
+					this.AllVesselTypes[idx] = (VesselType)typeObjs.GetValue(idx);
+				}
+
+				this.vesselTypesLoaded = true;
 			}
 
 			if (this.SortedBodyList == null && FlightGlobals.Bodies != null && FlightGlobals.Bodies.Count > 0)
@@ -874,10 +997,20 @@
 				this.SortedBodyList = new List<CelestialBody>(FlightGlobals.Bodies);
 				this.SortedBodyList.Sort(new CBListComparer());
 				this.SortedBodyList.Reverse();
-
-				Debug.Log(string.Format("sortedBodyList: {0}", string.Join("\n\t", this.SortedBodyList.Select(b => b.bodyName).ToArray())));
-			}
-
+			}
+
+			// SimManager initialization that we don't necessarily want to repeat every Update.
+			if (!this.simManagerLoaded && this.HomeBody != null)
+			{
+				SimManager.Gravity = VOID_Data.KerbinGee;
+				SimManager.Atmosphere = 0d;
+				SimManager.Mach = 1d;
+				CelestialBodies.SelectedBody = this.HomeBody;
+				BuildAdvanced.Altitude = 0d;
+				SimManager.OnReady += this.GetSimManagerResults;
+
+				this.simManagerLoaded = true;
+			}
 		}
 
 		protected void InitializeToolbarButton()
@@ -928,7 +1061,6 @@
 		protected void ToggleMainWindow()
 		{
 			this.Active = !this.Active;
-			this.SetIconTexture(this.powerState | this.activeState);
 		}
 
 		protected void SetIconTexture(IconState state)
@@ -954,49 +1086,37 @@
 
 		protected void SetIconTexture(string texturePath)
 		{
+			if (texturePath == null)
+			{
+				return;
+			}
+
 			if (this.ToolbarButton != null)
 			{
 				this.ToolbarButton.TexturePath = texturePath;
 			}
 
-			this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath.Replace("icon", "appIcon"), false);
-
 			if (this.AppLauncherButton != null)
 			{
+				this.VOIDIconTexture = GameDatabase.Instance.GetTexture(texturePath.Replace("icon", "appIcon"), false);
+
 				this.AppLauncherButton.SetTexture(VOIDIconTexture);
 			}
 		}
 
-		protected virtual void CheckAndSave()
-		{
-			this.saveTimer += Time.deltaTime;
-
-			if (this.saveTimer > 2f)
-			{
-				if (!this.configDirty)
-				{
-					return;
-				}
-
-				Tools.PostDebugMessage(string.Format(
-					"{0}: Time to save, checking if configDirty: {1}",
-					this.GetType().Name,
-					this.configDirty
-				));
-
-				this.SaveConfig();
-				this.saveTimer = 0;
-			}
-		}
-
 		public override void LoadConfig()
 		{
 			base.LoadConfig();
 
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				module.LoadConfig();
 			}
+
+			this.TimeScale |= GameSettings.KERBIN_TIME ? VOID_TimeScale.KERBIN_TIME : 0u;
 		}
 
 		public override void SaveConfig()
@@ -1012,8 +1132,11 @@
 
 			this.Save(config);
 
-			foreach (IVOID_Module module in this.modules)
-			{
+			IVOID_Module module;
+			for (int idx = 0; idx < this.modules.Count; idx++)
+			{
+				module = this.modules[idx];
+
 				module.Save(config);
 			}
 
@@ -1046,21 +1169,17 @@
 			this.UpdateTimer = 0f;
 
 			this.vesselSimActive = (VOID_SaveValue<bool>)true;
-			SimManager.Atmosphere = 0d;
-			SimManager.OnReady += this.GetSimManagerResults;
-
-			this.useToolbarManager = ToolbarManager.ToolbarAvailable;
+
+			this.useToolbarManager = (VOID_SaveValue<bool>)ToolbarManager.ToolbarAvailable;
 
 			this.LoadConfig();
 
 			this.configVersion = (VOID_SaveValue<int>)VOIDCore.CONFIG_VERSION;
-			
-			this.SetIconTexture(this.powerState | this.activeState);
 
 			this.FactoryReset = false;
 		}
 
-		public virtual void Dispose()
+		public override void Dispose()
 		{
 			this.StopGUI();
 
@@ -1080,14 +1199,6 @@
 			_instance = null;
 			_initialized = false;
 		}
-
-		protected enum IconState
-		{
-			PowerOff = 1,
-			PowerOn = 2,
-			Inactive = 4,
-			Active = 8
-		}
 	}
 }
 

--- a/VOID_CBInfoBrowser.cs
+++ b/VOID_CBInfoBrowser.cs
@@ -203,7 +203,7 @@
 				GUILayout.Label("Natural satellites:");
 				GUILayout.Label("Artificial satellites:");
 				GUILayout.Label("Surface gravity:");
-				GUILayout.Label("Atmosphere altitude:");
+				GUILayout.Label("Atmosphere Depth:");
 				GUILayout.Label("Atmospheric O\u2082:");
 				GUILayout.Label("Has ocean:");
 
@@ -380,8 +380,12 @@
 
 			//show # artificial satellites
 			int num_art_sats = 0;
-			foreach (Vessel v in FlightGlobals.Vessels)
-			{
+
+			Vessel v;
+			for (int idx = 0; idx < FlightGlobals.Vessels.Count; idx++)
+			{
+				v = FlightGlobals.Vessels[idx];
+
 				if (v.mainBody == body && v.situation.ToString() == "ORBITING") num_art_sats++;
 			}
 
@@ -393,7 +397,7 @@
 
 			if (body.atmosphere)
 			{
-				GUILayout.Label("≈ " + Tools.MuMech_ToSI(body.maxAtmosphereAltitude) + "m",
+				GUILayout.Label("≈ " + Tools.MuMech_ToSI(body.atmosphereDepth) + "m",
 					VOID_Styles.labelRight,
 					GUILayout.ExpandWidth(true));
 

--- a/VOID_CareerStatus.cs
+++ b/VOID_CareerStatus.cs
@@ -36,14 +36,8 @@
 {
 	[VOID_Scenes(GameScenes.FLIGHT, GameScenes.EDITOR, GameScenes.SPACECENTER)]
 	[VOID_GameModes(Game.Modes.CAREER, Game.Modes.SCIENCE_SANDBOX)]
-	public class VOID_CareerStatus : VOID_WindowModule
+	public class VOID_CareerStatus : VOID_SingletonWindow<VOID_CareerStatus>
 	{
-		public static VOID_CareerStatus Instance
-		{
-			get;
-			private set;
-		}
-
 		public static string formatDelta(double delta, string numberFormat)
 		{
 			if (delta > 0)
@@ -233,11 +227,6 @@
 		 * */
 		public VOID_CareerStatus() : base()
 		{
-			if (this.InValidGame && this.InValidScene)
-			{
-				VOID_CareerStatus.Instance = this;
-			}
-
 			this.Name = "Career Status";
 
 			GameEvents.OnFundsChanged.Add(this.onFundsChange);
@@ -269,14 +258,19 @@
 			this.currentReputation = float.NaN;
 		}
 
-		~VOID_CareerStatus()
+		public override void Dispose()
 		{
 			GameEvents.OnFundsChanged.Remove(this.onFundsChange);
 			GameEvents.OnReputationChanged.Remove(this.onRepChange);
 			GameEvents.OnScienceChanged.Remove(this.onScienceChange);
 			GameEvents.onGameStateLoad.Remove(this.onGameStateLoad);
 
-			VOID_CareerStatus.Instance = null;
+			base.Dispose();
+		}
+
+		~VOID_CareerStatus()
+		{
+			this.Dispose();
 		}
 	}
 }

--- a/VOID_ConfigWindow.cs
+++ b/VOID_ConfigWindow.cs
@@ -33,14 +33,8 @@
 
 namespace VOID
 {
-	public class VOID_ConfigWindow : VOID_WindowModule
+	public class VOID_ConfigWindow : VOID_SingletonWindow<VOID_ConfigWindow>
 	{
-		public static VOID_ConfigWindow Instance
-		{
-			get;
-			private set;
-		}
-
 		public override bool InValidScene
 		{
 			get
@@ -59,8 +53,6 @@
 
 		public VOID_ConfigWindow() : base()
 		{
-			VOID_ConfigWindow.Instance = this;
-
 			this.Name = "VOID Configuration";
 		}
 
@@ -71,12 +63,13 @@
 			this.core.DrawConfigurables();
 
 			GUILayout.EndVertical();
-			GUI.DragWindow();
+
+			base.ModuleWindow(id);
 		}
 
 		~VOID_ConfigWindow()
 		{
-			VOID_ConfigWindow.Instance = null;
+			this.Dispose();
 		}
 	}
 }

--- a/VOID_Data.cs
+++ b/VOID_Data.cs
@@ -116,29 +116,29 @@
 		public static readonly VOID_DoubleValue atmDensity =
 			new VOID_DoubleValue(
 				"Atmosphere Density",
-				new Func<double>(() => Core.Vessel.atmDensity * 1000f),
+				new Func<double>(() => Core.Vessel.atmDensity * 1000d),
 				"g/m³"
 			);
 
-		public static readonly VOID_FloatValue atmLimit =
-			new VOID_FloatValue(
-				"Atmosphere Limit",
-				new Func<float>(() => Core.Vessel.mainBody.maxAtmosphereAltitude),
+		public static readonly VOID_DoubleValue atmLimit =
+			new VOID_DoubleValue(
+				"Atmosphere Depth",
+				new Func<double>(() => Core.Vessel.mainBody.atmosphereDepth),
 				"m"
 			);
 
 		public static readonly VOID_DoubleValue atmPressure =
 			new VOID_DoubleValue(
-				"Pressure",
-				new Func<double>(() => Core.Vessel.staticPressure),
-				"atm"
-			);
-
-		public static readonly VOID_FloatValue temperature =
-			new VOID_FloatValue(
+				"Static Pressure",
+				new Func<double>(() => Core.Vessel.staticPressurekPa * 1000d),
+				"Pa"
+			);
+
+		public static readonly VOID_DoubleValue temperature =
+			new VOID_DoubleValue(
 				"Temperature",
-				new Func<float>(() => Core.Vessel.flightIntegrator.getExternalTemperature()),
-				"°C"
+				new Func<double>(() => Core.Vessel.atmosphericTemperature),
+				"K"
 			);
 
 		#endregion
@@ -269,22 +269,22 @@
 						return double.NaN;
 					}
 
+					return Core.LastStage.totalResourceMass;
+				},
+				"tons"
+			);
+
+		public static readonly VOID_DoubleValue stageResourceMass =
+			new VOID_DoubleValue(
+				"Resource Mass (Stage)",
+				delegate()
+				{
+					if (Core.LastStage == null)
+					{
+						return double.NaN;
+					}
+
 					return Core.LastStage.resourceMass;
-				},
-				"tons"
-			);
-
-		public static readonly VOID_DoubleValue stageResourceMass =
-			new VOID_DoubleValue(
-				"Resource Mass (Stage)",
-				delegate()
-				{
-					if (Core.LastStage == null)
-					{
-						return double.NaN;
-					}
-
-					return Core.LastStage.totalResourceMass;
 				},
 				"tons"
 			);
@@ -481,14 +481,16 @@
 						return Vector3d.zero;
 					}
 
-					List<PartModule> engineModules = Core.Vessel.getModulesOfType<PartModule>();
+					IList<PartModule> engineModules = Core.Vessel.getModulesOfType<PartModule>();
 
 					Vector3d thrustPos = Vector3d.zero;
 					Vector3d thrustDir = Vector3d.zero;
 					float thrust = 0;
 
-					foreach (PartModule engine in engineModules)
-					{
+					PartModule engine;
+					for (int idx = 0; idx < engineModules.Count; idx++)
+					{
+						engine = engineModules[idx];
 						float moduleThrust = 0;
 
 						switch (engine.moduleName)
@@ -579,8 +581,11 @@
 					currentAmount = 0d;
 					currentRequirement = 0d;
 
-					foreach (Part part in Core.Vessel.Parts)
-					{
+					Part part;
+					for (int idx = 0; idx < Core.Vessel.Parts.Count; idx++)
+					{
+						part = Core.Vessel.Parts[idx];
+
 						if (part.enabled)
 						{
 							ModuleEngines engineModule;
@@ -598,8 +603,11 @@
 
 							if (propellantList != null)
 							{
-								foreach (Propellant propellant in propellantList)
+								Propellant propellant;
+								for (int propIdx = 0; propIdx < propellantList.Count; propIdx++)
 								{
+									propellant = propellantList[propIdx];
+
 									if (propellant.name == "IntakeAir")
 									{
 										currentRequirement += propellant.currentRequirement / TimeWarp.fixedDeltaTime;
@@ -692,22 +700,25 @@
 					double vesselLongitude = Core.Vessel.longitude * Math.PI / 180d;
 					double vesselLatitude = Core.Vessel.latitude * Math.PI / 180d;
 
-					double diffLon = vesselLongitude - kscLongitude;
-					double diffLat = vesselLatitude - kscLatitude;
-
-					double sinHalfDiffLat = Math.Sin(diffLat / 2d);
-					double sinHalfDiffLon = Math.Sin(diffLon / 2d);
-
-					double cosVesselLon = Math.Cos(vesselLongitude);
-					double cosKSCLon = Math.Cos(kscLongitude);
-
-					double haversine =
-						sinHalfDiffLat * sinHalfDiffLat +
-						cosVesselLon * cosKSCLon * sinHalfDiffLon * sinHalfDiffLon;
-
-					double arc = 2d * Math.Atan2(Math.Sqrt(haversine), Math.Sqrt(1d - haversine));
-
-					return Core.Vessel.mainBody.Radius * arc;
+					double diffLon = Math.Abs(vesselLongitude - kscLongitude);
+
+					double cosVesselLatitude = Math.Cos(vesselLatitude);
+					double sinDiffLon = Math.Sin(diffLon);
+
+					double term1 = cosVesselLatitude * sinDiffLon;
+
+					double cosKSCLatitude = Math.Cos(kscLatitude);
+					double sinVesselLatitude = Math.Sin(vesselLatitude);
+					double sinKSCLatitude = Math.Sin(kscLatitude);
+					double cosDiffLon = Math.Cos(diffLon);
+
+					double term2 = cosKSCLatitude * sinVesselLatitude - sinKSCLatitude * cosVesselLatitude * cosDiffLon;
+
+					double term3 = sinKSCLatitude * sinVesselLatitude + cosKSCLatitude * cosVesselLatitude * cosDiffLon;
+
+					double arc = Math.Atan2(Math.Sqrt(term1 * term1 + term2 * term2), term3);
+
+					return arc * Core.Vessel.mainBody.Radius;
 				},
 				"m"
 			);

--- a/VOID_DataLogger.cs
+++ b/VOID_DataLogger.cs
@@ -305,7 +305,7 @@
 			//called if logging is on and interval has passed
 			//writes one line to the csvList
 
-			StringBuilder line = new StringBuilder();
+			StringBuilder line = Tools.GetStringBuilder();
 
 			if (firstWrite)
 			{
@@ -317,6 +317,8 @@
 					"\"Altitude above terrain (m)\"," +
 					"\"Surface Latitude (°)\"," +
 					"\"Surface Longitude (°)\"," +
+					"\"Apoapsis Altitude (m)\"," +
+					"\"Periapsis Altitude (m)\"," +
 					"\"Orbital Velocity (m/s)\"," +
 					"\"Surface Velocity (m/s)\"," +
 					"\"Vertical Speed (m/s)\"," +
@@ -358,6 +360,14 @@
 			line.Append('"');
 			line.Append(',');
 
+			// Apoapsis Altitude
+			line.Append(VOID_Data.orbitApoAlt.Value.ToString("G3"));
+			line.Append(',');
+
+			// Periapsis Altitude
+			line.Append(VOID_Data.oribtPeriAlt.Value.ToString("G3"));
+			line.Append(',');
+
 			//Orbital velocity
 			line.Append(VOID_Data.orbitVelocity.Value.ToString("F3"));
 			line.Append(',');
@@ -398,6 +408,8 @@
 			csvBytes.AddRange(this.utf8Encoding.GetBytes(line.ToString()));
 
 			this.csvCollectTimer = 0f;
+
+			Tools.PutStringBuilder(line);
 		}
 
 		#endregion

--- a/VOID_EditorHUD.cs
+++ b/VOID_EditorHUD.cs
@@ -30,7 +30,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using ToadicusTools;
 using UnityEngine;
@@ -58,9 +57,12 @@
 			{
 				if (this._vesselOverlays == null)
 				{
-					this._vesselOverlays = (EditorVesselOverlays)Resources
-						.FindObjectsOfTypeAll(typeof(EditorVesselOverlays))
-						.FirstOrDefault();
+					UnityEngine.Object[] overlayObjs = Resources.FindObjectsOfTypeAll(typeof(EditorVesselOverlays));
+
+					if (overlayObjs.Length > 0)
+					{
+						this._vesselOverlays = (EditorVesselOverlays)overlayObjs[0];
+					}
 				}
 
 				return this._vesselOverlays;
@@ -116,7 +118,7 @@
 
 		public void ehudWindowFunc(int id)
 		{
-			StringBuilder hudString = new StringBuilder();
+			StringBuilder hudString = Tools.GetStringBuilder();
 
 			if (this.core.LastStage == null)
 			{
@@ -190,6 +192,8 @@
 			}
 
 			GUI.BringWindowToBack(id);
+
+			Tools.PutStringBuilder(hudString);
 		}
 
 		public override void DrawGUI()

--- a/VOID_HUD.cs
+++ b/VOID_HUD.cs
@@ -70,7 +70,7 @@
 		{
 			StringBuilder leftHUD;
 
-			leftHUD = new StringBuilder();
+			leftHUD = Tools.GetStringBuilder();
 
 			VOID_Styles.labelHud.alignment = TextAnchor.UpperRight;
 
@@ -116,13 +116,15 @@
 			}
 
 			GUI.BringWindowToBack(id);
+
+			Tools.PutStringBuilder(leftHUD);
 		}
 
 		protected void rightHUDWindow(int id)
 		{
 			StringBuilder rightHUD;
 
-			rightHUD = new StringBuilder();
+			rightHUD = Tools.GetStringBuilder();
 
 			VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
 
@@ -182,6 +184,8 @@
 			}
 
 			GUI.BringWindowToBack(id);
+
+			Tools.PutStringBuilder(rightHUD);
 		}
 	}
 }

--- a/VOID_HUDAdvanced.cs
+++ b/VOID_HUDAdvanced.cs
@@ -30,7 +30,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using ToadicusTools;
 using UnityEngine;
@@ -104,7 +103,7 @@
 		{
 			StringBuilder leftHUD;
 
-			leftHUD = new StringBuilder();
+			leftHUD = Tools.GetStringBuilder();
 
 			VOID_Styles.labelHud.alignment = TextAnchor.UpperRight;
 
@@ -162,13 +161,15 @@
 			}
 
 			GUI.BringWindowToBack(id);
+
+			Tools.PutStringBuilder(leftHUD);
 		}
 
 		protected void rightHUDWindow(int id)
 		{
 			StringBuilder rightHUD;
 
-			rightHUD = new StringBuilder();
+			rightHUD = Tools.GetStringBuilder();
 
 			VOID_Styles.labelHud.alignment = TextAnchor.UpperLeft;
 
@@ -226,14 +227,19 @@
 			}
 
 			GUI.BringWindowToBack(id);
+
+			Tools.PutStringBuilder(rightHUD);
 		}
 
 		public override void DrawGUI()
 		{
 			if (this.primaryHUD == null)
 			{
-				foreach (IVOID_Module module in this.core.Modules)
-				{
+				IVOID_Module module;
+				for (int idx = 0; idx < this.core.Modules.Count; idx++)
+				{
+					module = this.core.Modules[idx];
+
 					if (module is VOID_HUD)
 					{
 						this.primaryHUD = module as VOID_HUD;
@@ -259,8 +265,11 @@
 
 			if (GUILayout.Button(string.Intern("Reset Advanced HUD Positions"), GUILayout.ExpandWidth(false)))
 			{
-				foreach (HUDWindow window in this.Windows)
-				{
+				HUDWindow window;
+				for (int idx = 0; idx < this.Windows.Count; idx++)
+				{
+					window = this.Windows[idx];
+
 					window.WindowPos = new Rect(window.defaultWindowPos);
 				}
 			}

--- a/VOID_Orbital.cs
+++ b/VOID_Orbital.cs
@@ -39,7 +39,7 @@
 		protected VOID_SaveValue<bool> toggleExtended;
 
 		[AVOID_SaveValue("precisionValues")]
-		protected long _precisionValues;
+		protected VOID_SaveValue<long> _precisionValues;
 		protected IntCollection precisionValues;
 
 		public VOID_Orbital()
@@ -51,7 +51,7 @@
 
 			this.toggleExtended = (VOID_SaveValue<bool>)false;
 
-			this._precisionValues = 230584300921369395;
+			this._precisionValues = (VOID_SaveValue<long>)384307168202282325;
 		}
 
 		public override void ModuleWindow(int id)
@@ -125,7 +125,7 @@
 
 		public override void Save (KSP.IO.PluginConfiguration config)
 		{
-			this._precisionValues = this.precisionValues.collection;
+			this._precisionValues.value = this.precisionValues.collection;
 
 			base.Save (config);
 		}

--- a/VOID_Rendezvous.cs
+++ b/VOID_Rendezvous.cs
@@ -29,7 +29,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using ToadicusTools;
 using UnityEngine;
 
@@ -58,12 +57,19 @@
 
 		public override void ModuleWindow(int id)
 		{
-			Vessel rendezvessel = new Vessel();
-			CelestialBody rendezbody = new CelestialBody();
+			Vessel rendezvessel;
+			CelestialBody rendezbody;
 
 			if (this.RegisterModule == null)
 			{
-				this.RegisterModule = this.core.Modules.Where(m => typeof(VOID_VesselRegister).IsAssignableFrom(m.GetType())).FirstOrDefault() as VOID_VesselRegister;
+				for (int idx = 0; idx < this.core.Modules.Count; idx++)
+				{
+					if (this.core.Modules[idx] is VOID_VesselRegister)
+					{
+						this.RegisterModule = this.core.Modules[idx] as VOID_VesselRegister;
+						break;
+					}
+				}
 			}
 
 			GUILayout.BeginVertical();

--- a/VOID_StageInfo.cs
+++ b/VOID_StageInfo.cs
@@ -7,7 +7,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using ToadicusTools;
 using UnityEngine;
 
@@ -35,7 +34,7 @@
 
 		private bool showColumnSelection;
 
-		private CelestialBody selectedBody;
+		private CelestialBody _selectedBody;
 		[AVOID_SaveValue("bodyIdx")]
 		private VOID_SaveValue<int> bodyIdx;
 		private int lastIdx;
@@ -45,6 +44,19 @@
 		[AVOID_SaveValue("UseSealLevel")]
 		private VOID_SaveValue<bool> useSeaLevel;
 		private GUIContent seaLevelToggle;
+
+		private CelestialBody selectedBody
+		{
+			get
+			{
+				return this._selectedBody;
+			}
+			set
+			{
+				this._selectedBody = value;
+				KerbalEngineer.Helpers.CelestialBodies.SelectedBody = value;
+			}
+		}
 
 		public VOID_StageInfo() : base()
 		{
@@ -151,15 +163,18 @@
 
 			if (HighLogic.LoadedSceneIsEditor && this.selectedBody.atmosphere && this.useSeaLevel)
 			{
-				SimManager.Atmosphere = this.selectedBody.atmosphereMultiplier * 101.325d;
+				SimManager.Atmosphere = this.selectedBody.GetPressure(0) * PhysicsGlobals.KpaToAtmospheres;
 			}
 			else
 			{
 				SimManager.Atmosphere = 0d;
 			}
 
-			foreach (Stage stage in core.Stages)
-			{
+			Stage stage;
+			for (int idx = 0; idx < core.Stages.Length; idx++)
+			{
+				stage = core.Stages[idx];
+
 				if (stage.deltaV == 0 && stage.mass == 0)
 				{
 					continue;
@@ -275,8 +290,10 @@
 
 		private void BodyPickerWindow(int _)
 		{
-			foreach (CelestialBody body in core.SortedBodyList)
-			{
+			CelestialBody body;
+			for (int idx = 0; idx < core.SortedBodyList.Count; idx++)
+			{
+				body = core.SortedBodyList[idx];
 				if (GUILayout.Button(body.bodyName, VOID_Styles.labelDefault))
 				{
 					Debug.Log("Picked new body focus: " + body.bodyName);

--- a/VOID_SurfAtmo.cs
+++ b/VOID_SurfAtmo.cs
@@ -41,12 +41,12 @@
 
 		public VOID_SurfAtmo()
 		{
-			this.Name = "Surface & Atmospheric Information";
+			this.Name = "Surface & Atmospheric Info";
 
 			this.WindowPos.x = Screen.width - 260f;
 			this.WindowPos.y = 85;
 
-			this._precisionValues = (VOID_SaveValue<long>)230584300921369395;
+			this._precisionValues = (VOID_SaveValue<long>)384307168202282325;
 		}
 
 		public override void ModuleWindow(int id)
@@ -55,60 +55,61 @@
 
 			GUILayout.BeginVertical();
 
-			this.precisionValues [idx]= (ushort)VOID_Data.trueAltitude.DoGUIHorizontal (this.precisionValues [idx]);
+			this.precisionValues[idx] = (ushort)VOID_Data.trueAltitude.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
-			VOID_Data.surfLatitude.DoGUIHorizontal ();
+			VOID_Data.surfLatitude.DoGUIHorizontal();
 
-			VOID_Data.surfLongitude.DoGUIHorizontal ();
+			VOID_Data.surfLongitude.DoGUIHorizontal();
 
-			VOID_Data.vesselHeading.DoGUIHorizontal ();
+			VOID_Data.vesselHeading.DoGUIHorizontal();
 
-			this.precisionValues [idx]= (ushort)VOID_Data.terrainElevation.DoGUIHorizontal (this.precisionValues [idx]);
+			this.precisionValues[idx] = (ushort)VOID_Data.terrainElevation.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
 			this.precisionValues[idx] = (ushort)VOID_Data.downrangeDistance.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
-			this.precisionValues [idx]= (ushort)VOID_Data.surfVelocity.DoGUIHorizontal (this.precisionValues [idx]);
+			this.precisionValues[idx] = (ushort)VOID_Data.surfVelocity.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
-			this.precisionValues [idx]= (ushort)VOID_Data.vertVelocity.DoGUIHorizontal (this.precisionValues [idx]);
+			this.precisionValues[idx] = (ushort)VOID_Data.vertVelocity.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
-			this.precisionValues [idx]= (ushort)VOID_Data.horzVelocity.DoGUIHorizontal (this.precisionValues [idx]);
+			this.precisionValues[idx] = (ushort)VOID_Data.horzVelocity.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
-			VOID_Data.temperature.DoGUIHorizontal ("F2");
+			VOID_Data.temperature.DoGUIHorizontal("F2");
 
-			this.precisionValues [idx]= (ushort)VOID_Data.atmDensity.DoGUIHorizontal (this.precisionValues [idx]);
+			this.precisionValues[idx] = (ushort)VOID_Data.atmDensity.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
-			VOID_Data.atmPressure.DoGUIHorizontal ("F2");
+			this.precisionValues[idx] = (ushort)VOID_Data.atmPressure.DoGUIHorizontal(this.precisionValues[idx]);
+			idx++;
 
-			this.precisionValues [idx]= (ushort)VOID_Data.atmLimit.DoGUIHorizontal (this.precisionValues [idx]);
+			this.precisionValues[idx] = (ushort)VOID_Data.atmLimit.DoGUIHorizontal(this.precisionValues[idx]);
 			idx++;
 
 			// Toadicus edit: added Biome
-			VOID_Data.currBiome.DoGUIHorizontal ();
+			VOID_Data.currBiome.DoGUIHorizontal();
 
 			GUILayout.EndVertical();
 
 			base.ModuleWindow(id);
 		}
 
-		public override void LoadConfig ()
+		public override void LoadConfig()
 		{
-			base.LoadConfig ();
+			base.LoadConfig();
 
-			this.precisionValues = new IntCollection (4, this._precisionValues);
+			this.precisionValues = new IntCollection(4, this._precisionValues);
 		}
 
-		public override void Save (KSP.IO.PluginConfiguration config)
+		public override void Save(KSP.IO.PluginConfiguration config)
 		{
 			this._precisionValues.value = this.precisionValues.collection;
 
-			base.Save (config);
+			base.Save(config);
 		}
 	}
 }

--- a/VOID_TWR.cs
+++ b/VOID_TWR.cs
@@ -3,11 +3,9 @@
 // This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
 // copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
 
+using KerbalEngineer.VesselSimulator;
 using KSP;
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using ToadicusTools;
 using UnityEngine;
 
 namespace VOID
@@ -28,7 +26,7 @@
 				(TimeWarp.CurrentRate <= TimeWarp.MaxPhysicsRate)
 			)
 			{
-				KerbalEngineer.VesselSimulator.SimManager.RequestSimulation();
+				SimManager.RequestSimulation();
 			}
 
 			GUILayout.BeginVertical();
@@ -43,8 +41,11 @@
 			}
 			else
 			{
-				foreach (CelestialBody body in core.SortedBodyList)
+				CelestialBody body;
+				for (int idx = 0; idx < core.SortedBodyList.Count; idx++)
 				{
+					body = core.SortedBodyList[idx];
+
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 
 					GUILayout.Label(body.bodyName);

--- a/VOID_Transfer.cs
+++ b/VOID_Transfer.cs
@@ -29,7 +29,6 @@
 using KSP;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using ToadicusTools;
 using UnityEngine;
 
@@ -50,12 +49,16 @@
 
 		public override void ModuleWindow(int id)
 		{
+			CelestialBody body;
+
 			GUILayout.BeginVertical();
 
 			if (Vessel.mainBody.name == "Sun")  //Vessel is orbiting the Sun
 			{
-			    foreach (CelestialBody body in Vessel.mainBody.orbitingBodies)
+			    for (int idx = 0; idx < Vessel.mainBody.orbitingBodies.Count; idx++)
 			    {
+					body = Vessel.mainBody.orbitingBodies[idx];
+
 					GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 					if (GUILayout.Button(body.bodyName))
 					{
@@ -75,8 +78,9 @@
 			}
 			else if (Vessel.mainBody.referenceBody.name == "Sun")	//Vessel is orbiting a planet
 			{
-			    foreach (CelestialBody body in Vessel.mainBody.referenceBody.orbitingBodies)
-			    {
+			    for (int idx = 0; idx < Vessel.mainBody.referenceBody.orbitingBodies.Count; idx++)
+				{
+					body = Vessel.mainBody.referenceBody.orbitingBodies[idx];
 			        if (body.name != Vessel.mainBody.name)	// show other planets
 			        {
 			            GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
@@ -96,8 +100,10 @@
 			            }
 			        }
 			    }
-			    foreach (CelestialBody body in Vessel.mainBody.orbitingBodies)	// show moons
+			    for (int moonIdx = 0; moonIdx < Vessel.mainBody.orbitingBodies.Count; moonIdx++)
 			    {
+					body = Vessel.mainBody.orbitingBodies[moonIdx];
+
 			        GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
 			        if (GUILayout.Button(body.bodyName))
 			        {
@@ -117,8 +123,10 @@
 			}
 			else if (Vessel.mainBody.referenceBody.referenceBody.name == "Sun")	// Vessel is orbiting a moon
 			{
-			    foreach (CelestialBody body in Vessel.mainBody.referenceBody.orbitingBodies)
+			    for (int idx = 0; idx < Vessel.mainBody.referenceBody.orbitingBodies.Count; idx++)
 			    {
+					body = Vessel.mainBody.referenceBody.orbitingBodies[idx];
+
 					if (body.name != Vessel.mainBody.name)	// show other moons
 					{
 						GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));

--- a/VOID_VesselInfo.cs
+++ b/VOID_VesselInfo.cs
@@ -66,9 +66,9 @@
 
 			VOID_Data.totalMass.DoGUIHorizontal ("F3");
 
-			VOID_Data.stageResourceMass.DoGUIHorizontal("F2");
+			VOID_Data.stageResourceMass.DoGUIHorizontal("F3");
 
-			VOID_Data.resourceMass.DoGUIHorizontal("F2");
+			VOID_Data.resourceMass.DoGUIHorizontal("F3");
 
 			VOID_Data.stageDeltaV.DoGUIHorizontal (3, false);
 

--- a/VOID_VesselRegister.cs
+++ b/VOID_VesselRegister.cs
@@ -28,7 +28,6 @@
 
 using KSP;
 using System;
-using System.Linq;
 using ToadicusTools;
 using UnityEngine;
 
@@ -76,7 +75,7 @@
 
 		public override void ModuleWindow(int id)
 		{
-			if (!this.core.AllVesselTypes.Any())
+			if (this.core.AllVesselTypes.Length < 1)
 			{
 				return;
 			}
@@ -141,8 +140,11 @@
 
 			selectorScrollPos = GUILayout.BeginScrollView(selectorScrollPos, false, false);
 
-			foreach (Vessel v in FlightGlobals.Vessels)
+			Vessel v;
+			for (int idx = 0; idx < FlightGlobals.Vessels.Count; idx++)
 			{
+				v = FlightGlobals.Vessels[idx];
+
 				if (v != Vessel && v.vesselType == selectedVesselType && v.mainBody == seletedBody)
 				{
 					if ((vesselSituation == "Landed" &&