Jump to content

xEvilReeperx

Members
  • Posts

    894
  • Joined

  • Last visited

Everything posted by xEvilReeperx

  1. Sorry, for some reason I didn't get a notification. I'll have a look and see what's up
  2. Looks like the complete list of part tags has already been found ... at least, those in use Layer 0: Default Layer 1: TransparentFX Layer 2: Ignore Raycast Layer 3: Layer 4: Water Layer 5: UI Layer 6: Layer 7: Layer 8: PartsList_Icons Layer 9: Atmosphere Layer 10: Scaled Scenery Layer 11: UI_Culled Layer 12: UI_Main Layer 13: UI_Mask Layer 14: Screens Layer 15: Local Scenery Layer 16: kerbals Layer 17: Editor_UI Layer 18: SkySphere Layer 19: Disconnected Parts Layer 20: Internal Space Layer 21: Part Triggers Layer 22: KerbalInstructors Layer 23: ScaledSpaceSun Layer 24: MapFX Layer 25: EzGUI_UI Layer 26: WheelCollidersIgnore Layer 27: WheelColliders Layer 28: TerrainColliders Layer 29: DragRender Layer 30: SurfaceFX Layer 31: Vectors // Parts Tag: Airlock Tag: Icon_Hidden Tag: Icon_Only Tag: Ladder Tag: NoAttach Tag: Untagged // could be used by other than parts // misc Tag: MainCamera Tag: LaunchpadFX
  3. You can also enable VERBOSE_DEBUG_LOG in settings.cfg to get a stack trace inside the Alt+F2 log/Alt+F12 debug menu. I find that it generally has a faster turnaround than looking in the on-disk logs although you'll still need them from time to time for harder-to-find bugs or in cases where the exception is being spammed continuously: public class ThrowAnExceptionInStart : MonoBehaviour { private void Start() { print("The vessel name is: " + FlightGlobals.ActiveVessel.name); } }[KSPAddon(KSPAddon.Startup.MainMenu, false)] [table=width: 500] [tr] [td][/td] [td][/td] [/tr] [/table]
  4. That should've been fixed in 1.8.8+. Can you confirm that you're running 1.8.9? Also 300-400 MB sounds pretty extreme. ScienceAlert should only be using ~12MB at a maximum
  5. Hard to say why the other mod doesn't have problems without seeing its code. 1) Rather than simply run in all scenes and then not do anything on the wrong ones, I suggest you set out to target the correct scenes directly. 2) once you eliminate that erroneous scene, your addon is registering for the GUILauncherReady event too late and missing it. Based on output from the log I posted, I suspect you won't be able to catch it in time with a KSPAddon initialized in the space center. My suggestion there is to avoid using events entirely. Wait (if necessary) for the toolbar to exist using a coroutine instead. Here's what my version of KFGUIManager looks like with those two implemented; sorry for the odd formatting I'm not sure why the code tags are doing that public class KFGUIManager : MonoBehaviour { private abstract class GuiRunner : MonoBehaviour { private void Awake() { gameObject.AddComponent<KFGUIManager>(); } } [KSPAddon(KSPAddon.Startup.Flight, false)] private sealed class RunInFlightScene : GuiRunner { } [KSPAddon(KSPAddon.Startup.SpaceCentre, false)] private sealed class RunInSpaceCentre : GuiRunner { } [KSPAddon(KSPAddon.Startup.EditorAny, false)] private sealed class RunInEditor : GuiRunner { } #region Initialization // AppLauncher Elements. ApplicationLauncherButton appButton; Texture2D appTextureGrey; Texture2D appTextureColor; // Icon Constants const string strIconBasePath = "KerbalFoundries/Assets"; const string strIconGrey = "KFIconGrey"; const string strIconColor = "KFIconColor"; // GUI Constants private Rect settingsRect = new Rect(Screen.width - 258f, 42f, 100f, 100f); /// <summary>Local name of the KFLogUtil class.</summary> readonly KFLogUtil KFLog = new KFLogUtil(); /// <summary>Name of the class for logging purposes.</summary> public string strClassName = "KFGUIManager"; #endregion Initialization #region Startup private IEnumerator Start() { enabled = false; while (ApplicationLauncher.Instance == null || !ApplicationLauncher.Ready) yield return 0; InitGUIElements(); appButton = ApplicationLauncher.Instance.AddModApplication(onTrue, onFalse, onHover, onNotHover, null, null, ApplicationLauncher.AppScenes.FLIGHT | ApplicationLauncher.AppScenes.SPACECENTER | ApplicationLauncher.AppScenes.VAB, appTextureGrey); } private void OnDestroy() { if (appButton != null) ApplicationLauncher.Instance.RemoveModApplication(appButton); } /// <summary>Retrieves button textures.</summary> void InitGUIElements() { appTextureGrey = GameDatabase.Instance.GetTexture(string.Format("{0}/{1}", strIconBasePath, strIconGrey), false); appTextureColor = GameDatabase.Instance.GetTexture(string.Format("{0}/{1}", strIconBasePath, strIconColor), false); } #endregion Startup #region AppLauncher Button /// <summary>Called when the button is put into a "true" state, or when it is activated.</summary> void onTrue() { appButton.SetTexture(appTextureColor); enabled = true; } /// <summary>Called when the button is in a "false" state. Saves configuration.</summary> void onFalse() { appButton.SetTexture(appTextureGrey); enabled = false; KFPersistenceManager.SaveConfig(); } /// <summary>Called when the cursor enters a hovered state over the button.</summary> void onHover() { appButton.SetTexture(appTextureColor); } /// <summary>Called when the cursor leaves the hovering state over the button.</summary> void onNotHover() { if (!enabled) appButton.SetTexture(appTextureGrey); } #endregion AppLauncher Button #region GUI Setup /// <summary>Called by Unity when it's time to draw the GUI.</summary> void OnGUI() { settingsRect = KSPUtil.ClampRectToScreen(GUILayout.Window(GetInstanceID(), settingsRect, DrawWindow, "Kerbal Foundries Settings", HighLogic.Skin.window, GUILayout.Width(256f))); } /// <summary>Creates the GUI content.</summary> /// <param name="windowID">ID of the window to create the content for.</param> void DrawWindow(int windowID) { GUI.skin = HighLogic.Skin; if (HighLogic.LoadedSceneIsFlight || Equals(HighLogic.LoadedScene, GameScenes.SPACECENTER)) { KFPersistenceManager.isDustEnabled = GUILayout.Toggle(KFPersistenceManager.isDustEnabled, "Enable DustFX"); if (KFPersistenceManager.isDustEnabled) KFPersistenceManager.isDustCameraEnabled = GUILayout.Toggle(KFPersistenceManager.isDustCameraEnabled, "Enable DustFX Camera"); } if (HighLogic.LoadedSceneIsEditor || Equals(HighLogic.LoadedScene, GameScenes.SPACECENTER)) KFPersistenceManager.isMarkerEnabled = GUILayout.Toggle(KFPersistenceManager.isMarkerEnabled, "Enable Orientation Markers"); GUILayout.Space(10f); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Save & Close")) appButton.SetFalse(); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUI.DragWindow(); } #endregion GUI Setup }
  6. Look, I'm trying to explain that the reason it's null is that you're dealing with an uninitialized instance of KFGUIManager. You have accidentally created two copies of KFGUIManager and the one that owns the button is not the same as the one that is displaying the GUI. Add some logging statements: private string MyId = ""; void Awake() { MyId = Guid.NewGuid().ToString("n").Substring(0, 6); KFLog.Log("KFGUIManager.Awake - " + MyId); print(string.Format("States: LoadedSceneIsFlight {0}, LoadedSceneIsEditor {1}, LoadedScene == SpaceCentre? {2}, LoadedScene = {3}", HighLogic.LoadedSceneIsFlight, HighLogic.LoadedSceneIsEditor, HighLogic.LoadedScene == GameScenes.SPACECENTER, HighLogic.LoadedScene)); if (HighLogic.LoadedSceneIsFlight || HighLogic.LoadedSceneIsEditor || HighLogic.LoadedScene == GameScenes.SPACECENTER) { KFLog.Log("KFGUIManager: " + MyId + " Adding event calls"); GameEvents.onGUIApplicationLauncherReady.Add(SetupAppButton); GameEvents.onGameSceneSwitchRequested.Add(OnSwitchScene); } } Make sure you add OnDestroy and sprinkle the new MyId throughout the others. Add this too: [KSPAddon(KSPAddon.Startup.Instantly, false)] public class OnLevelWasLoadedPrinter : MonoBehaviour { private void Awake() { DontDestroyOnLoad(this); } private void OnLevelWasLoaded(int level) { print("OnLevelWasLoadedPrinter: " + ((GameScenes) level) + " (raw: " + level + ")"); } } It'll make what's going on more apparent. Also add this: if (GUI.Button(new Rect(8f, 120f, 240f, 24f), "Save and Close")) { KFLog.Log("You clicked " + MyId + "'s button"); KFLog.Log("Save & closed was clicked"); if (appButton == null) KFLog.Error("appButton is most definitely null"); appButton.SetFalse(); KFLog.Debug("Save-button clicked, called \"appButton.SetFalse()\"", strClassName); } Go to the space center, open the GUI, click the button once. Let's look at the log (I've snipped some unrelated parts): [WRN 05:22:00.752] [HighLogic]: =========================== Scene Change : From MAINMENU to SPACECENTER (Async) ===================== [LOG 05:22:01.029] [Kerbal Foundries]: KFGUIManager.OnDestroy ec3b52 // here is the one from MainMenu dying; that's fine [LOG 05:22:01.241] OnLevelWasLoadedPrinter: LOADINGBUFFER (raw: 1) [LOG 05:22:01.255] AddonLoader: Instantiating addon 'KFGUIManager' from assembly 'KerbalFoundries' // uh oh -- this is being created from the LOADINGBUFFER scene? [LOG 05:22:01.256] [Kerbal Foundries]: KFGUIManager.Awake - [B][SIZE=3]0ab385[/SIZE][/B] [LOG 05:22:01.260] States: LoadedSceneIsFlight False, LoadedSceneIsEditor False, LoadedScene == SpaceCentre? True, LoadedScene = SPACECENTER [B][I][LOG 05:22:01.262] [Kerbal Foundries]: KFGUIManager: [B][SIZE=3]0ab385 [/SIZE][/B]Adding event calls [LOG 05:22:01.958] [Kerbal Foundries]: [SIZE=3]KFGUIManager.OnDestroy [/SIZE][B][SIZE=4]0ab385[/SIZE][/B][/I][/B] [LOG 05:22:02.218] OnLevelWasLoadedPrinter: SPACECENTER (raw: 5) [LOG 05:22:02.227] [Kerbal Foundries]: [B][SIZE=4]0ab385[/SIZE][/B]: SetupAppButton event from GUIApplicationLauncherReady [LOG 05:22:02.262] [Kerbal Foundries - KFGUIManager()]: App button added by [B][SIZE=3]0ab385[/SIZE][/B] [LOG 05:22:02.292] AddonLoader: Instantiating addon 'AddScenarioModules' from assembly 'KSP' [LOG 05:22:02.294] AddonLoader: Instantiating addon 'ContractDefs' from assembly 'KSP' [LOG 05:22:02.328] AddonLoader: Instantiating addon 'CustomConfigsManager' from assembly 'ModuleManager' [LOG 05:22:02.334] AddonLoader: Instantiating addon 'KFGUIManager' from assembly 'KerbalFoundries' [LOG 05:22:02.336] [Kerbal Foundries]: KFGUIManager.Awake - [B][SIZE=5][SIZE=3]c6d96a[/SIZE][/SIZE][/B] [LOG 05:22:02.339] States: LoadedSceneIsFlight False, LoadedSceneIsEditor False, LoadedScene == SpaceCentre? True, LoadedScene = SPACECENTER [LOG 05:22:02.341] [Kerbal Foundries]: KFGUIManager: [B][SIZE=3]c6d96a [/SIZE][/B]Adding event calls [LOG 05:22:02.880] [CustomConfigsManager] Setting moddeed physics as the active one [LOG 05:22:02.883] PhysicsGlobals: Loading database [ContractSystem] [Building ScenarioModule] [Resource system init] [B][LOG 05:22:10.335] [Kerbal Foundries]: You clicked [SIZE=3]c6d96a[/SIZE]'s button[/B] [LOG 05:22:10.338] [Kerbal Foundries]: Save & closed was clicked [ERR 05:22:10.341] [Kerbal Foundries]: appButton is most definitely null [EXC 05:22:10.346] NullReferenceException: Object reference not set to an instance of an object KerbalFoundries.KFGUIManager.DrawWindow (Int32 windowID) (at d:/For New Computer/KSPCustomMods/KF_plugin-master/KF_plugin/KFGUIManager.cs:243) UnityEngine.GUI.CallWindowDelegate (UnityEngine.WindowFunction func, Int32 id, UnityEngine.GUISkin _skin, Int32 forceRect, Single width, Single height, UnityEngine.GUIStyle style) Look at this very, very closely. 0ab385 adds itself to the events in the LOADINGBUFFER scene. It's been tricked into doing this because HighLogic.LoadedScene just happens to be SPACECENTER while in LOADINGBUFFER. The scene then changes, destroying its GameObject... but the C# side of it isn't garbage collected because it has been pinned in memory by the events it signed itself up for. Now, immediately after the space center begins loading, we see SetupAppButton. But wait, that KFGUIManager (0ab385) was destroyed! That one won't have a functioning GUI because Unity destroyed its GameObject. Moving on, the correct, functioning KFGUIManager (c6d96a) has added itself to those callbacks. It should initialize soon. But wait a minute, look around -- c6d96a never initializes! Where is its button? Now at this point there are two instances of KFGUIManager. 0ab385 was clearly destroyed but owns a button and is still stuck in memory because other things have references to it. c6d96a registered for events but those events never came and it remains uninitialized. They share the static isGUIEnabled so when 0ab385 toggles isGUIEnabled, BOTH 0ab385 and c6de96a should begin showing their GUI. Except that 0ab385 had its GameObject destroyed and never receives any OnGUI calls. The OnGUI you see is from c6d96a. Accessing any of the things inside c6d96a that should've initialized (appButton) will throw NullReferenceException because it was never initialized -- it's still patiently waiting for those GameEvents to occur. Accessing any MonoBehaviour properties of 0ab385 will throw because it was destroyed. Try printing the name of KFGUIManager's gameObject inside SetupAppButton and you'll see another exception involving get_gameObject to prove this is the case.
  7. You're becoming quite hard to help. All I wanted was for you to add some statements inside your button code: if (GUI.Button(new Rect(8f, 120f, 240f, 24f), "Save and Close")) { KFLog.Log("Save & closed was clicked"); if (appButton == null) KFLog.Error("appButton is most definitely null"); KFLog.Log("This next line will definitely throw"); try { appButton.SetFalse(); } catch (NullReferenceException e) { KFLog.Error("Received expected exception: " + e); } KFLog.Debug("Save-button clicked, called \"appButton.SetFalse()\"", strClassName); } If you can't even acknowledge where the problem might lie, you don't really have any chance of solving it
  8. Maybe I shouldn't have used "ponder" and "what if" like I wasn't sure. I tracked down the problems and know exactly what they are. If you remove the appButton portion from your GUI.Button call, it won't throw. You've fixated on that for some reason. Maybe the easiest way to convince you is to have you make IsGUIEnabled private instead of static. When your GUI suddenly stops appearing when the button is clicked, you can then ponder about why changing a shared variable to a per-instance variable has affected anything when there should only be one instance to begin with.
  9. You seriously couldn't take two seconds to add a null check in there and instead wrote an entire ironic paragraph berating me for not taking the time to look? I don't think I said anything about the state of the GUI, I just used the power of deduction. There is a perfect storm of logic that leads to what you claim is impossible. Ponder this: what if, somehow, there are two KFGUIManagers. One of them created the toolbar button but leads a sad half-existence because the GameObject it was riding was destroyed in a scene change and it got stuck in memory, making it incapable of OnGUI. The other never initializes. What if the first one (again, not capable of showing any GUI) were to toggle isGUIEnabled? How would that second, uninitialized manager react? Why ... it would start displaying its GUI. But you never know it's completely uninitialized until you try and access one of the things that was supposed to initialize. Anyway, good luck
  10. It does tell you quite a lot. No reason to see if onFalse is getting called, stack trace shows it isn't. If your code is the same as on github, then appButton is clearly null for some reason. No problem with the GUI code, then. Your new job is to figure out why appButton is null, assuming you're testing in the flight, space center or editor scene. If not, it should be fairly simple to see why you're getting a nullref Where are the art assets kept?
  11. You can disable the camera to prevent it from rendering automatically
  12. Same, StopWatch. Using a camera isn't what's expensive, it's the ReadPixels. You can have your camera send its output directly to a texture property on a material set up to use a custom shader that does whatever work you need and avoid that performance penalty. That's what those other mods do. I think the current solution is good enough for now though, aside from a little texture memory leak
  13. It is. The current routine you have takes 4-5ms on average on my machine. If you eliminate the unnecessary allocations in there you can drop the average to 1-2ms. That's faster than I thought it would be though, so if you go with your strategy of only sampling every x frames it works out I guess
  14. I had to download the log twice, so powerful was the deja-vu! You have exactly the same issue herman had. All you need to do is update ContractConfigurator to 1.5.2 and you'll be all set
  15. Read "community tech tree" and thought "nah, that couldn't possibly be affecting anything. Skip" My own fault for rushing the process
  16. Great, thanks! The log led me straight to the suspicious bit and revealed why I couldn't reproduce your results with your craft: a missing transmitter (maybe you have a config patch that adds one?). Anyway, this should take care of the problem. It's probably fairly widespread so once I get your confirmation that the issue is fixed, I'll release it right away Download 1.8.9 Is there anything suspicious in the log? Any exception that has something to do with ScenarioRunner is usually the cause. Post your output_log and I'll have a look
  17. Still no joy Could you try reinstalling? If that doesn't help, edit ScienceAlert/settings.cfg/LogSettings/LogMask to -1 and post the log again next time you see the problem
  18. I haven't been able to replicate it so far. Is there a certain craft or sequence of steps you can describe that will cause the exception reliably?
  19. This is your problem: [EXC 13:40:46.292] ArgumentException: 'Tekto' is not a valid CelestialBody. ContractConfigurator.ConfigNodeUtil.ParseCelestialBodyValue (System.String celestialName) ContractConfigurator.ConfigNodeUtil.ParseSingleValue[CelestialBody] (System.String key, System.String stringValue, Boolean allowExpression) ContractConfigurator.ConfigNodeUtil.ParseValue[CelestialBody] (.ConfigNode configNode, System.String key, Boolean allowExpression) ContractConfigurator.BiomeTracker.OnLoad (.ConfigNode node) ScenarioModule.Load (.ConfigNode node) ScenarioRunner.AddModule (.ConfigNode node) ProtoScenarioModule.Load (.ScenarioRunner host) ScenarioRunner+.MoveNext () ScienceAlert is actually running, it's just forever waiting on its own ScenarioModule which never gets initialized due to this exception. I've reported it to the author. In the meantime, you might be able to remove the offending names from your persistence file to get it working again, or else wait for a fix.
  20. Judging by a previous poster's exceptions, it looks like somehow a bug has wormed its way into a piece of code I changed despite all the precautions I took. I would say the bug is most likely in SA itself and those other mods aren't causing any issues at this point. Hunting it now
  21. Exceptions are bad. Do you have the rest of the log (output_log.txt), or at least the stack trace from the NullReferenceException, assuming SA caused it?
×
×
  • Create New...