ARMapRenderer: Move last/thisColor to Class scope to avoid GC, add some basic code tidying.
ARMapRenderer: Move last/thisColor to Class scope to avoid GC, add some basic code tidying.

--- a/ARMapRenderer.cs
+++ b/ARMapRenderer.cs
@@ -39,7 +39,12 @@
 		#region Fields
 		private Dictionary<Guid, LineRenderer> vesselLineRenderers;
 		private Dictionary<Guid, bool> vesselFrameCache;
+
+		#pragma warning disable 414
 		private bool dumpBool;
+		private Color lastColor;
+		private Color thisColor;
+		#pragma warning restore 414
 		#endregion
 
 		#region Properties
@@ -174,10 +179,10 @@
 		}
 		#endregion
 
+		#region Utility
 		private void SetRelayVertices(IAntennaRelay relay)
 		{
-			Color lastColor = default(Color);
-			Color thisColor;
+			lastColor = default(Color);
 
 			LineRenderer renderer = this[relay.vessel.id];
 			Vector3d start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());
@@ -262,7 +267,7 @@
 			}
 		}
 
-		public void Cleanup()
+		private void Cleanup()
 		{
 			if (this.vesselLineRenderers != null && this.vesselLineRenderers.Count > 0)
 			{
@@ -279,6 +284,7 @@
 				this.vesselFrameCache.Clear();
 			}
 		}
+		#endregion
 	}
 }
 

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -38,6 +38,9 @@
 	/// </summary>
 	public class AntennaRelay
 	{
+		private static readonly System.Diagnostics.Stopwatch searchTimer = new System.Diagnostics.Stopwatch();
+		private const long millisecondsBetweenSearches = 125L;
+
 		// We don't have a Bard, so we'll hide Kerbin here.
 		private static CelestialBody _Kerbin;
 
@@ -57,14 +60,13 @@
 			}
 		}
 
+		private long lastSearch;
+
 		private bool canTransmit;
 
 		private IAntennaRelay nearestRelay;
 		private IAntennaRelay bestOccludedRelay;
 
-		private System.Diagnostics.Stopwatch searchTimer;
-		private long millisecondsBetweenSearches;
-
 		/// <summary>
 		/// The <see cref="AntennaRange.ModuleLimitedDataTransmitter"/> reference underlying this AntennaRelay, as an
 		/// <see cref="AntennaRange.IAntennaRelay"/>
@@ -167,14 +169,23 @@
 		/// <returns>The nearest relay or null, if no relays in range.</returns>
 		private void FindNearestRelay()
 		{
-			if (!this.searchTimer.IsRunning || this.searchTimer.ElapsedMilliseconds > this.millisecondsBetweenSearches)
-			{
-				this.searchTimer.Reset();
-			}
-			else
+			if (!searchTimer.IsRunning)
+			{
+				searchTimer.Start();
+			}
+
+			long searchTime = searchTimer.ElapsedMilliseconds;
+			long timeSinceLast = searchTime - this.lastSearch;
+
+			if (timeSinceLast < Math.Max(millisecondsBetweenSearches, UnityEngine.Time.smoothDeltaTime))
 			{
 				return;
 			}
+
+			Tools.PostDebugMessage("{0}: Updating at {1}ms, {2}ms since last search.",
+				this.ToString(), searchTime, timeSinceLast);
+
+			this.lastSearch = searchTime;
 
 			// Skip vessels that have already been checked for a nearest relay this pass.
 			if (RelayDatabase.Instance.CheckedVesselsTable.ContainsKey(this.vessel.id))
@@ -377,26 +388,63 @@
 
 					this.canTransmit = false;
 
-					// If the best occluded relay is closer than Kerbin, target it.
+					// If the best occluded relay is closer than Kerbin, check it against the nearest relay.
+					// Since bestOccludedSqrDistance is infinity if there are no occluded relays, this is safe
 					if (bestOccludedSqrDistance < kerbinSqrDistance)
 					{
-						log.AppendFormat("\n\t\tPicking occluded relay {0} as target ({1} < {2}).",
-							this.bestOccludedRelay == null ? "null" : this.bestOccludedRelay.ToString(),
-							bestOccludedSqrDistance, kerbinSqrDistance);
-
+						log.AppendFormat("\n\tBest occluded relay is closer than Kerbin ({0} < {1})",
+							bestOccludedRelay, kerbinSqrDistance);
+						
 						this.KerbinDirect = false;
-						this.targetRelay = this.bestOccludedRelay;
-						this.firstOccludingBody = bodyOccludingBestOccludedRelay;
-					}
-					// Otherwise, target Kerbin and report the first body blocking it.
+
+						// If the nearest relay is closer than the best occluded relay, pick it.
+						// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
+						if (nearestRelaySqrDistance < bestOccludedSqrDistance)
+						{
+							log.AppendFormat("\n\t\t...but the nearest relay is closer ({0} < {1}), so picking it.",
+								nearestRelaySqrDistance, bestOccludedSqrDistance);
+							
+							this.targetRelay = nearestRelay;
+							this.firstOccludingBody = null;
+						}
+						// Otherwise, target the best occluded relay.
+						else
+						{
+							log.AppendFormat("\n\t\t...and closer than the nearest relay ({0} >= {1}), so picking it.",
+								nearestRelaySqrDistance, bestOccludedSqrDistance);
+							
+							this.targetRelay = bestOccludedRelay;
+							this.firstOccludingBody = bodyOccludingBestOccludedRelay;
+						}
+					}
+					// Otherwise, check Kerbin against the nearest relay.
+					// Since we have LOS, blank the first occluding body.
 					else
 					{
-						log.AppendFormat("\n\t\tPicking Kerbin as target ({0} >= {1}).",
-							bestOccludedSqrDistance, kerbinSqrDistance);
-
-						this.KerbinDirect = true;
-						this.targetRelay = null;
-						this.firstOccludingBody = bodyOccludingKerbin;
+						log.AppendFormat("\n\tKerbin is closer than the best occluded relay ({0} >= {1})",
+							bestOccludedRelay, kerbinSqrDistance);
+						
+						this.firstOccludingBody = null;
+
+						// If the nearest relay is closer than Kerbin, pick it.
+						// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
+						if (nearestRelaySqrDistance < kerbinSqrDistance)
+						{
+							log.AppendFormat("\n\t\t...but the nearest relay is closer ({0} < {1}), so picking it.",
+								nearestRelaySqrDistance, kerbinSqrDistance);
+							
+							this.KerbinDirect = false;
+							this.targetRelay = nearestRelay;
+						}
+						// Otherwise, pick Kerbin.
+						else
+						{
+							log.AppendFormat("\n\t\t...and closer than the nearest relay ({0} >= {1}), so picking it.",
+								nearestRelaySqrDistance, kerbinSqrDistance);
+							
+							this.KerbinDirect = true;
+							this.targetRelay = null;
+						}
 					}
 				}
 			}
@@ -461,28 +509,45 @@
 
 						this.canTransmit = false;
 
-						// If the best occluded relay is closer than Kerbin, use it.
-						// Since bestOccludedSqrDistance is infinity if there are no occluded relays,
-						// this is safe
+						// If the best occluded relay is closer than Kerbin, check it against the nearest relay.
+						// Since bestOccludedSqrDistance is infinity if there are no occluded relays, this is safe
 						if (bestOccludedSqrDistance < kerbinSqrDistance)
 						{
-							log.AppendFormat("\n\t\tPicking occluded relay {0} as target ({1} < {2}).",
-								this.bestOccludedRelay == null ? "null" : this.bestOccludedRelay.ToString(),
-									bestOccludedSqrDistance, kerbinSqrDistance);
-
 							this.KerbinDirect = false;
-							this.targetRelay = bestOccludedRelay;
-							this.firstOccludingBody = bodyOccludingBestOccludedRelay;
-						}
-						// Otherwise, target Kerbin.  Since we have LOS, blank the first occluding body.
+
+							// If the nearest relay is closer than the best occluded relay, pick it.
+							// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
+							if (nearestRelaySqrDistance < bestOccludedSqrDistance)
+							{
+								this.targetRelay = nearestRelay;
+								this.firstOccludingBody = null;
+							}
+							// Otherwise, target the best occluded relay.
+							else
+							{
+								this.targetRelay = bestOccludedRelay;
+								this.firstOccludingBody = bodyOccludingBestOccludedRelay;
+							}
+						}
+						// Otherwise, check Kerbin against the nearest relay.
+						// Since we have LOS, blank the first occluding body.
 						else
 						{
-							log.AppendFormat("\n\t\tPicking Kerbin as target ({0} >= {1}).",
-								bestOccludedSqrDistance, kerbinSqrDistance);
-
-							this.KerbinDirect = true;
-							this.targetRelay = null;
 							this.firstOccludingBody = null;
+
+							// If the nearest relay is closer than Kerbin, pick it.
+							// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
+							if (nearestRelaySqrDistance < kerbinSqrDistance)
+							{
+								this.KerbinDirect = false;
+								this.targetRelay = nearestRelay;
+							}
+							// Otherwise, pick Kerbin.
+							else
+							{
+								this.KerbinDirect = true;
+								this.targetRelay = null;
+							}
 						}
 					}
 				}
@@ -518,9 +583,6 @@
 		public AntennaRelay(IAntennaRelay module)
 		{
 			this.moduleRef = module;
-
-			this.searchTimer = new System.Diagnostics.Stopwatch();
-			this.millisecondsBetweenSearches = 125L;
 		}
 	}
 }

--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -126,11 +126,16 @@
 		/// <returns>A <see cref="System.String"/> that represents the current <see cref="AntennaRange.ProtoAntennaRelay"/>.</returns>
 		public override string ToString()
 		{
-			return string.Format(
-				"{0} on {1}",
-				this.Title,
-				this.protoPart.pVesselRef.vesselName
-			);
+			System.Text.StringBuilder sb = new System.Text.StringBuilder();
+
+			sb.Append(this.Title);
+
+			if (this.protoPart != null && this.protoPart.pVesselRef != null)
+			{
+				sb.AppendFormat(" on {0}", this.protoPart.pVesselRef.vesselName);
+			}
+
+			return sb.ToString();
 		}
 
 		/// <summary>