/// <summary>
        /// Called by the part every refresh frame where it is active, which can be less frequent than FixedUpdate which is called every processing frame
        /// </summary>
        void FixedUpdate()
        {
            // for each vessel
            foreach (Vessel vessel in FlightGlobals.Vessels)
            {
                // ignore Kerbals
                if (vessel.isEVA)
                {
                    continue;
                }

                // ignore landed or floating vessels
                if (vessel.LandedOrSplashed)
                {
                    continue;
                }

                // ignore irrelevant vessel types
                if (vessel.vesselType == VesselType.Debris ||
                    vessel.vesselType == VesselType.Flag ||
                    vessel.vesselType == VesselType.SpaceObject ||
                    vessel.vesselType == VesselType.DeployedSciencePart ||
                    vessel.vesselType == VesselType.DeployedScienceController
                    )
                {
                    continue;
                }

                // lookup vesselData
                if (!vesselDataDict.TryGetValue(vessel.id, out VesselData vesselData))
                {
                    vesselData = new VesselData(vessel);
                    vesselDataDict.Add(vessel.id, vesselData);
                }

                if (vessel.loaded)
                {
                    ProcessesLoadedVessel(vessel, vesselData);
                    continue;
                }

                // skip further processing if no solar sail present
                if (vesselData.HasSolarSail.HasValue && vesselData.HasSolarSail.Value == false)
                {
                    continue;
                }

                if (vesselData.HasSolarSail.HasValue == false)
                {
                    // look for a solar sail
                    foreach (ProtoPartSnapshot protoPartSnapshot in vessel.protoVessel.protoPartSnapshots)
                    {
                        if (LoadSolarSail(protoPartSnapshot, vesselData))
                        {
                            break;
                        }
                    }

                    // stop searching is no sail was found
                    if (vesselData.HasSolarSail.HasValue == false)
                    {
                        vesselData.HasSolarSail = false;
                        continue;
                    }
                }

                BackgroundSolarSail(vesselData);
            }
        }
        private static void ProcessesLoadedVessel(Vessel vessel, VesselData vesselData)
        {
            vesselData.ModulePhotonSail = vessel.FindPartModuleImplementing <ModulePhotonSail>();

            vesselData.HasSolarSail = vesselData.ModulePhotonSail?.IsEnabled;
        }