Probably fixed the flickering lines by only checking one relay per inactive vessel, and by setting BestVesselRelay per vessel in RelayDatabase.
Probably fixed the flickering lines by only checking one relay per inactive vessel, and by setting BestVesselRelay per vessel in RelayDatabase.

--- a/ARFlightController.cs
+++ b/ARFlightController.cs
@@ -241,6 +241,35 @@
 				FlightGlobals.ActiveVessel != null
 			)
 			{
+				Vessel vessel;
+				IAntennaRelay relay;
+				IList<IAntennaRelay> activeVesselRelays;
+
+				for (int vIdx = 0; vIdx < FlightGlobals.Vessels.Count; vIdx++)
+				{
+					vessel = FlightGlobals.Vessels[vIdx];
+
+					if (vessel == FlightGlobals.ActiveVessel)
+					{
+						continue;
+					}
+
+					relay = vessel.GetBestRelay();
+
+					if (relay != null)
+					{
+						relay.FindNearestRelay();
+					}
+				}
+
+				activeVesselRelays = RelayDatabase.Instance[FlightGlobals.ActiveVessel];
+				for (int rIdx = 0; rIdx < activeVesselRelays.Count; rIdx++)
+				{
+					relay = activeVesselRelays[rIdx];
+
+					relay.FindNearestRelay();
+				}
+
 				log.Append("Checking vessel relay status.\n");
 
 				this.currentConnectionStatus = FlightGlobals.ActiveVessel.GetConnectionStatus();

--- a/ARMapRenderer.cs
+++ b/ARMapRenderer.cs
@@ -26,8 +26,6 @@
 // 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.
 
-#define DEBUG
-
 #pragma warning disable 1591
 
 using KSP;
@@ -43,8 +41,15 @@
 		#region Fields
 		private Dictionary<Guid, LineRenderer> vesselLineRenderers;
 
+		// Debug Stuff
+		#pragma warning disable 649
+		private System.Diagnostics.Stopwatch timer;
+		private Tools.DebugLogger log;
+		private long relayStart;
+		private long start;
+		#pragma warning restore 649
+
 		#pragma warning disable 414
-		private bool dumpBool;
 		private Color thisColor;
 		#pragma warning restore 414
 		#endregion
@@ -91,12 +96,12 @@
 			{
 				this.vesselLineRenderers = new Dictionary<Guid, LineRenderer>();
 			}
-		}
-
-		#if DEBUG
-		private System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
-		#endif
-		private Tools.DebugLogger log = Tools.DebugLogger.New(typeof(ARMapRenderer));
+
+			#if DEBUG
+			this.timer = new System.Diagnostics.Stopwatch();
+			this.log = Tools.DebugLogger.New(this);
+			#endif
+		}
 
 		private void OnPreCull()
 		{
@@ -109,7 +114,6 @@
 
 			#if DEBUG
 			timer.Restart();
-			long start;
 			#endif
 
 			try
@@ -134,9 +138,7 @@
 					{
 						Vessel vessel = FlightGlobals.Vessels[i];
 
-						#if DEBUG
 						log.AppendFormat("\nStarting check for vessel {0} at {1}ms", vessel, timer.ElapsedMilliseconds);
-						#endif
 
 						if (vessel == null)
 						{
@@ -157,29 +159,26 @@
 
 						log.AppendFormat("\n\tChecking vessel {0}.", vessel.vesselName);
 
-						#if DEBUG
 						start = timer.ElapsedMilliseconds;
-						#endif
 
 						IAntennaRelay vesselRelay = vessel.GetBestRelay();
 
-						#if DEBUG
-						log.AppendFormat("\n\tGot best relay {0} for vessel {1} in {2} ms",
-							vesselRelay, vessel, timer.ElapsedMilliseconds - start);
-						#endif
+						if (vesselRelay == null)
+						{
+							continue;
+						}
+
+						log.AppendFormat("\n\tGot best relay {0} ({3}) for vessel {1} in {2} ms",
+							vesselRelay, vessel, timer.ElapsedMilliseconds - start, vesselRelay.GetType().Name);
 
 						if (vesselRelay != null)
 						{
-							#if DEBUG
 							start = timer.ElapsedMilliseconds;
-							#endif
 
 							this.SetRelayVertices(vesselRelay);
 
-							#if DEBUG
 							log.AppendFormat("\n\tSet relay vertices for {0} in {1}ms",
 								vessel, timer.ElapsedMilliseconds - start);
-							#endif
 						}
 					}
 				}
@@ -208,12 +207,15 @@
 		#endregion
 
 		#region Utility
-		#if DEBUG
-		private long relayStart;
-		#endif
 		private void SetRelayVertices(IAntennaRelay relay)
 		{
 			log.AppendFormat("\n\t\tDrawing line for relay chain starting at {0}.", relay);
+
+			if (relay.vessel == null)
+			{
+				log.Append("\n\t\tvessel is null, bailing out");
+				return;
+			}
 
 			LineRenderer renderer = this[relay.vessel.id];
 			Vector3d start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -111,8 +111,6 @@
 		{
 			get
 			{
-				//this.FindNearestRelay();
-
 				if (this.KerbinDirect || this.targetRelay == null)
 				{
 					return this.DistanceTo(Kerbin);
@@ -159,7 +157,6 @@
 		/// <returns><c>true</c> if this instance can transmit; otherwise, <c>false</c>.</returns>
 		public virtual bool CanTransmit()
 		{
-			//this.FindNearestRelay();
 			return this.canTransmit;
 		}
 
@@ -167,7 +164,7 @@
 		/// Finds the nearest relay.
 		/// </summary>
 		/// <returns>The nearest relay or null, if no relays in range.</returns>
-		private void FindNearestRelay()
+		public void FindNearestRelay()
 		{
 			if (!FlightGlobals.ready)
 			{
@@ -666,6 +663,8 @@
 		{
 			this.moduleRef = module;
 			this.isChecked = false;
+
+			Tools.PostLogMessage("{0}: constructed {1}", this.GetType().Name, this.ToString());
 		}
 	}
 }

--- a/IAntennaRelay.cs
+++ b/IAntennaRelay.cs
@@ -83,6 +83,8 @@
 		/// </summary>
 		bool CanTransmit();
 
+		void FindNearestRelay();
+
 		/// <summary>
 		/// Returns a <see cref="System.String"/> that represents the current <see cref="AntennaRange.IAntennaRelay"/>.
 		/// </summary>

--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -436,6 +436,14 @@
 			return this.relay.CanTransmit();
 		}
 
+		public void FindNearestRelay()
+		{
+			if (this.relay != null)
+			{
+				this.relay.FindNearestRelay();
+			}
+		}
+
 		/// <summary>
 		/// Override ModuleDataTransmitter.TransmitData to check against CanTransmit and fail out when CanTransmit
 		/// returns false.
@@ -444,6 +452,8 @@
 		/// <param name="callback">Callback function</param>
 		public new void TransmitData(List<ScienceData> dataQueue, Callback callback)
 		{
+			this.FindNearestRelay();
+
 			this.PreTransmit_SetPacketSize();
 			this.PreTransmit_SetPacketResourceCost();
 
@@ -558,6 +568,8 @@
 		/// </summary>
 		public new void StartTransmission()
 		{
+			this.FindNearestRelay();
+
 			PreTransmit_SetPacketSize ();
 			PreTransmit_SetPacketResourceCost ();
 

--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -54,6 +54,12 @@
 				}
 				else
 				{
+					Tools.PostLogMessage("{0}: Could not fetch vessel!  {1}{2}{3}",
+						this.ToString(),
+						this.protoPart == null ? "\n\tprotoPart=Null" : string.Empty,
+						this.protoPart != null && this.protoPart.pVesselRef == null ? "\n\tthis.protoPart.pVesselRef=Null" : string.Empty,
+						this.protoPart != null && this.protoPart.pVesselRef != null && this.protoPart.pVesselRef.vesselRef == null ? "\n\tthis.protoPart.pVesselRef.vesselRef=Null" : string.Empty
+					);
 					return null;
 				}
 			}
@@ -146,6 +152,8 @@
 		public ProtoAntennaRelay(IAntennaRelay prefabRelay, ProtoPartSnapshot pps) : base(prefabRelay)
 		{
 			this.protoPart = pps;
+
+			Tools.PostLogMessage("{0}: constructed {1}", this.GetType().Name, this.ToString());
 		}
 	}
 }

--- a/RelayDatabase.cs
+++ b/RelayDatabase.cs
@@ -43,7 +43,7 @@
 		 * Static members
 		 * */
 		// Singleton storage
-		protected static RelayDatabase _instance;
+		private static RelayDatabase _instance;
 		// Gets the singleton
 		public static RelayDatabase Instance
 		{
@@ -66,18 +66,17 @@
 		 * Fields
 		 * */
 		// Vessel.id-keyed hash table of Part.GetHashCode()-keyed tables of relay objects.
-		protected Dictionary<Guid, List<IAntennaRelay>> relayDatabase;
+		private Dictionary<Guid, List<IAntennaRelay>> relayDatabase;
+		private Dictionary<Guid, IAntennaRelay> bestRelayTable;
 
 		// Vessel.id-keyed hash table of part counts, used for caching
-		protected Dictionary<Guid, int> vesselPartCountTable;
-
-		protected Dictionary<Guid, BestVesselRelayCache> bestRelayTable;
+		private Dictionary<Guid, int> vesselPartCountTable;
 
 		// Vessel.id-keyed hash table of booleans to track what vessels have been checked so far this time.
 		public Dictionary<Guid, bool> CheckedVesselsTable;
 
-		protected int cacheHits;
-		protected int cacheMisses;
+		private int cacheHits;
+		private int cacheMisses;
 
 		/*
 		 * Properties
@@ -115,9 +114,43 @@
 		/* 
 		 * Methods
 		 * */
+		// Remove a vessel from the cache, if it exists.
+		public void DirtyVessel(Vessel vessel)
+		{
+			this.relayDatabase.Remove(vessel.id);
+			this.vesselPartCountTable.Remove(vessel.id);
+			this.relayDatabase.Remove(vessel.id);
+		}
+
+		// Returns true if both the relayDatabase and the vesselPartCountDB contain the vessel id.
+		public bool ContainsKey(Guid key)
+		{
+			return this.relayDatabase.ContainsKey(key);
+		}
+
+		// Returns true if both the relayDatabase and the vesselPartCountDB contain the vessel.
+		public bool ContainsKey(Vessel vessel)
+		{
+			return this.ContainsKey(vessel.id);
+		}
+
+		public IAntennaRelay GetBestVesselRelay(Vessel vessel)
+		{
+			IAntennaRelay relay;
+			if (this.bestRelayTable.TryGetValue(vessel.id, out relay))
+			{
+				return relay;
+			}
+			else
+			{
+				var dump = this[vessel];
+				return null;
+			}
+		}
+
 		// Adds a vessel to the database
 		// The return for this function isn't used yet, but seems useful for potential future API-uses
-		public bool AddVessel(Vessel vessel)
+		private bool AddVessel(Vessel vessel)
 		{
 			// If this vessel is already here...
 			if (this.ContainsKey(vessel))
@@ -148,7 +181,7 @@
 		}
 
 		// Update the vessel's entry in the table
-		public void UpdateVessel(Vessel vessel)
+		private void UpdateVessel(Vessel vessel)
 		{
 			// Squak if the database doesn't have the vessel
 			if (!this.ContainsKey(vessel))
@@ -169,54 +202,6 @@
 			this.vesselPartCountTable[vessel.id] = vessel.Parts.Count;
 		}
 
-		// Remove a vessel from the cache, if it exists.
-		public void DirtyVessel(Vessel vessel)
-		{
-			if (this.relayDatabase.ContainsKey(vessel.id))
-			{
-				this.relayDatabase.Remove(vessel.id);
-			}
-			if (this.vesselPartCountTable.ContainsKey(vessel.id))
-			{
-				this.vesselPartCountTable.Remove(vessel.id);
-			}
-		}
-
-		public void SetBestVesselRelay(Vessel vessel, BestVesselRelayCache relay)
-		{
-			this.bestRelayTable[vessel.id] = relay;
-		}
-
-		public bool TryGetBestVesselRelay(Vessel vessel, out BestVesselRelayCache relay)
-		{
-			return this.bestRelayTable.TryGetValue(vessel.id, out relay);
-		}
-
-		public BestVesselRelayCache GetBestVesselRelay(Vessel vessel)
-		{
-			BestVesselRelayCache relayCache;
-			if (this.TryGetBestVesselRelay(vessel, out relayCache))
-			{
-				return relayCache;
-			}
-
-			throw new ArgumentOutOfRangeException(
-				string.Format("RelayDatabase: Vessel {0} not in best vessel relay table.", vessel)
-			);
-		}
-
-		// Returns true if both the relayDatabase and the vesselPartCountDB contain the vessel id.
-		public bool ContainsKey(Guid key)
-		{
-			return this.relayDatabase.ContainsKey(key);
-		}
-
-		// Returns true if both the relayDatabase and the vesselPartCountDB contain the vessel.
-		public bool ContainsKey(Vessel vessel)
-		{
-			return this.ContainsKey(vessel.id);
-		}
-
 		// Runs when a vessel is modified (or when we switch to one, to catch docking events)
 		public void onVesselEvent(Vessel vessel)
 		{
@@ -241,7 +226,7 @@
 		}
 
 		// Runs when the player requests a scene change, such as when changing vessels or leaving flight.
-		public void onSceneChange(GameScenes scene)
+		private void onSceneChange(GameScenes scene)
 		{
 			// If the active vessel is a real thing...
 			if (FlightGlobals.ActiveVessel != null)
@@ -252,7 +237,7 @@
 		}
 
 		// Runs when parts are undocked
-		public void onPartEvent(Part part)
+		private void onPartEvent(Part part)
 		{
 			if (part != null && part.vessel != null)
 			{
@@ -261,14 +246,14 @@
 		}
 
 		// Runs when parts are coupled, as in docking
-		public void onFromPartToPartEvent(GameEvents.FromToAction<Part, Part> data)
+		private void onFromPartToPartEvent(GameEvents.FromToAction<Part, Part> data)
 		{
 			this.onPartEvent(data.from);
 			this.onPartEvent(data.to);
 		}
 
 		// Produce a Part-hashed table of relays for the given vessel
-		protected void getVesselRelays(Vessel vessel, ref List<IAntennaRelay> relays)
+		private void getVesselRelays(Vessel vessel, ref List<IAntennaRelay> relays)
 		{
 			// We're going to completely regen this table, so dump the current contents.
 			relays.Clear();
@@ -278,6 +263,10 @@
 				"IAntennaRelay",
 				vessel.vesselName
 			));
+
+			double bestRelayRange = double.NegativeInfinity;
+			IAntennaRelay bestRelay = null;
+			IAntennaRelay relay;
 
 			// If the vessel is loaded, we can fetch modules implementing IAntennaRelay directly.
 			if (vessel.loaded) {
@@ -302,8 +291,16 @@
 						// ...if the module is a relay...
 						if (module is IAntennaRelay)
 						{
+							relay = (module as IAntennaRelay);
+
+							if (relay.maxTransmitDistance > bestRelayRange)
+							{
+								bestRelayRange = relay.maxTransmitDistance;
+								bestRelay = relay;
+							}
+
 							// ...add the module to the table
-							relays.Add(module as IAntennaRelay);
+							relays.Add(relay);
 							// ...neglect relay objects after the first in each part.
 							break;
 						}
@@ -362,14 +359,24 @@
 								module
 							));
 
+							relay = new ProtoAntennaRelay(module as IAntennaRelay, pps);
+
+							if (relay.maxTransmitDistance > bestRelayRange)
+							{
+								bestRelayRange = relay.maxTransmitDistance;
+								bestRelay = relay;
+							}
+
 							// ...build a new ProtoAntennaRelay and add it to the table
-							relays.Add(new ProtoAntennaRelay(module as IAntennaRelay, pps));
+							relays.Add(relay);
 							// ...neglect relay objects after the first in each part.
 							break;
 						}
 					}
 				}
 			}
+
+			this.bestRelayTable[vessel.id] = bestRelay;
 
 			Tools.PostDebugMessage(string.Format(
 				"{0}: vessel '{1}' ({2}) has {3} transmitters.",
@@ -381,13 +388,13 @@
 		}
 
 		// Construct the singleton
-		protected RelayDatabase()
+		private RelayDatabase()
 		{
 			// Initialize the databases
 			this.relayDatabase = new Dictionary<Guid, List<IAntennaRelay>>();
+			this.bestRelayTable = new Dictionary<Guid, IAntennaRelay>();
 			this.vesselPartCountTable = new Dictionary<Guid, int>();
 			this.CheckedVesselsTable = new Dictionary<Guid, bool>();
-			this.bestRelayTable = new Dictionary<Guid, BestVesselRelayCache>();
 
 			this.cacheHits = 0;
 			this.cacheMisses = 0;
@@ -448,21 +455,6 @@
 		}
 		#endif
 	}
-
-	public class BestVesselRelayCache
-	{
-		public Vessel vessel;
-		public IAntennaRelay relay;
-		public long timeStamp;
-
-		public BestVesselRelayCache() {}
-		public BestVesselRelayCache(Vessel _vessel, IAntennaRelay _relay, long _timeStamp)
-		{
-			this.vessel = _vessel;
-			this.relay = _relay;
-			this.timeStamp = _timeStamp;
-		}
-	}
 }
 
 

--- a/RelayExtensions.cs
+++ b/RelayExtensions.cs
@@ -166,45 +166,7 @@
 		/// <param name="vessel">This <see cref="Vessel"/></param>
 		public static IAntennaRelay GetBestRelay(this Vessel vessel)
 		{
-			BestVesselRelayCache relayCache;
-
-			if (RelayDatabase.Instance.TryGetBestVesselRelay(vessel, out relayCache))
-			{
-				if (
-					AntennaRelay.searchTimer.ElapsedMilliseconds - relayCache.timeStamp <
-					AntennaRelay.millisecondsBetweenSearches
-				)
-				{
-					return relayCache.relay;
-				}
-			}
-			else
-			{
-				relayCache = new BestVesselRelayCache();
-				relayCache.vessel = vessel;
-				RelayDatabase.Instance.SetBestVesselRelay(vessel, relayCache);
-			}
-
-			double bestScore = double.PositiveInfinity;
-			double relayScore = double.NaN;
-
-			IList<IAntennaRelay> vesselRelays = RelayDatabase.Instance[vessel];
-			IAntennaRelay relay;
-			for (int rIdx = 0; rIdx < vesselRelays.Count; rIdx++)
-			{
-				relay = vesselRelays[rIdx];
-				relayScore = relay.transmitDistance / relay.maxTransmitDistance;
-
-				if (relayScore < bestScore)
-				{
-					bestScore = relayScore;
-					relayCache.relay = relay;
-				}
-			}
-
-			relayCache.timeStamp = AntennaRelay.searchTimer.ElapsedMilliseconds;
-
-			return relayCache.relay;
+			return RelayDatabase.Instance.GetBestVesselRelay(vessel);
 		}
 	}