Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

8 minutes ago, royals said:

Duh. Thanks lol. Is there a thread or something somewhere with things that mod developers should know, considering the update? What with the move to Unity 5 and all that, or is everything basically the same?

Do you mean something like this:

 

Link to comment
Share on other sites

Hey, I'm very new to KSP and I'm really struggling with creating a plugin.

I'm not sure how to get a custom plugin to work. I've tried following the tutorial on the Wiki (http://wiki.kerbalspaceprogram.com/wiki/Tutorial:Creating_your_first_module) as well as the video tutorials by Nifty255 (https://www.youtube.com/watch?v=XqrOVKEj2i0) but I can't seem to get the plugin to actually do anything. I also tried using the examples by Taranis (https://github.com/taraniselsu/TacExamples) but nothing happens (in the log).

The code works fine, compiles without a problem and I don't know what I'm doing wrong. One thing I really know is what to do with the .dll. Does it go in KSP/Plugins or KSP/GameData or KSP/GameData/<MyFolder> or KSP/GameData/<MyFolder>/Plugins? I'm a little confused because none of them work. :(

At this point I'm just looking for some debug output so I know that my plugin is being loaded/run. Is there something I'm missing between compile to DLL, add to folder, run KSP?

 

Link to comment
Share on other sites

34 minutes ago, michaelenger said:

Hey, I'm very new to KSP and I'm really struggling with creating a plugin.

I'm not sure how to get a custom plugin to work. I've tried following the tutorial on the Wiki (http://wiki.kerbalspaceprogram.com/wiki/Tutorial:Creating_your_first_module) as well as the video tutorials by Nifty255 (https://www.youtube.com/watch?v=XqrOVKEj2i0) but I can't seem to get the plugin to actually do anything. I also tried using the examples by Taranis (https://github.com/taraniselsu/TacExamples) but nothing happens (in the log).

The code works fine, compiles without a problem and I don't know what I'm doing wrong. One thing I really know is what to do with the .dll. Does it go in KSP/Plugins or KSP/GameData or KSP/GameData/<MyFolder> or KSP/GameData/<MyFolder>/Plugins? I'm a little confused because none of them work. :(

At this point I'm just looking for some debug output so I know that my plugin is being loaded/run. Is there something I'm missing between compile to DLL, add to folder, run KSP?

 

Generally, mods go in (KSP)/GameData/(your_mod). The main class in your .dll (the class you want to instantiate when the mod loads) should have a [KDPAddon(KSPAddon.Startup.... tag on it declaring in what scenes it should start up (and whether it should only start up once), and you should be requiring UnityEngine.dll and Assembly-CSharp.dll at the least. You'll also need to make sure that your main class subs from MonoBehaviour.

If you use Debug.Log("foo"), the debug log will have a "foo" in it when the code reaches that point. Useful for.. well, debugging.

HTH.

Link to comment
Share on other sites

4 hours ago, michaelenger said:

At this point I'm just looking for some debug output so I know that my plugin is being loaded/run. Is there something I'm missing between compile to DLL, add to folder, run KSP?

If you open the KSP.log you should see if your mod is loaded. Look for the "Mod DLLs found" line near the start of the log.

Link to comment
Share on other sites

Hello all, I'm trying to figure out how to implement a few classes.  Right now, I have a class called OldClass.  Despite my best efforts, it is trying to do too many things and needs to be split into two classes that both inherit from a third.  To avoid confusion, here is a quick key for what I'm talking about:

Current (bloated) class  -> OldClass

Base class to be inherited from  -> newBaseClass

Class to extend newBaseClass  -> extendingClass1

Class to extend newBaseClass  -> extendingClass2

Currently, OldClass has a few methods to generate a list of all parts extending itself.  These methods will have to be used again for each of the inheriting classes.  However, these methods are set up to use that list as arguments of type OldClass.  For example, method:

    int countCiviliansOnShip (List<OldClass> listOfMembers)
    {
      int numberCivilians = 0;
      foreach (OldClass myRegulator in listOfMembers) {//check for each part implementing CivilianPopulationRegulator
        if (myRegulator.part.protoModuleCrew.Count > 0) {
          foreach (ProtoCrewMember kerbalCrewMember in myRegulator.part.protoModuleCrew) {//check for each crew member within each part above
            if (kerbalCrewMember.trait == debuggingClass.civilianTrait) {
              numberCivilians++;
            }//end if civilian
          }//end foreach kerbalCrewMember
        }//end if crew capacity
      }//end foreach part implementing class
      return numberCivilians;//number of Kerbals with trait: debuggingClass.civilianTrait -> Civilian
    }

 

In brief, the above code iterates across every member of the list, gets the crew types within those parts, and checks if it is a civilian.  All of that is exactly what I want both classes to do.  The only change that needs to be made is changing from an argument of List<extendingClass1> or List<extendingClass2>, pending which class is calling it.  Is that possible/advisable?  Or would I be better off copy/pasting that function in each class?

And another question:  Currently OldClass is overriding OnFixedUpdate().  Should I leave it and the common method invocations in newBaseClass, with extendingClass1 and extendingClass2 calling only what is different?  Or should there be no OnFixedUpdate() method in newBaseClass, instead have it only called in extendingClass1 and extendingClass2?

 

Thank you!

Link to comment
Share on other sites

8 minutes ago, Tralfagar said:

Hello all, I'm trying to figure out how to implement a few classes.  Right now, I have a class called OldClass.  Despite my best efforts, it is trying to do too many things and needs to be split into two classes that both inherit from a third.  To avoid confusion, here is a quick key for what I'm talking about:

Current (bloated) class  -> OldClass

Base class to be inherited from  -> newBaseClass

Class to extend newBaseClass  -> extendingClass1

Class to extend newBaseClass  -> extendingClass2

Currently, OldClass has a few methods to generate a list of all parts extending itself.  These methods will have to be used again for each of the inheriting classes.  However, these methods are set up to use that list as arguments of type OldClass.  For example, method:


    int countCiviliansOnShip (List<OldClass> listOfMembers)
    {
      int numberCivilians = 0;
      foreach (OldClass myRegulator in listOfMembers) {//check for each part implementing CivilianPopulationRegulator
        if (myRegulator.part.protoModuleCrew.Count > 0) {
          foreach (ProtoCrewMember kerbalCrewMember in myRegulator.part.protoModuleCrew) {//check for each crew member within each part above
            if (kerbalCrewMember.trait == debuggingClass.civilianTrait) {
              numberCivilians++;
            }//end if civilian
          }//end foreach kerbalCrewMember
        }//end if crew capacity
      }//end foreach part implementing class
      return numberCivilians;//number of Kerbals with trait: debuggingClass.civilianTrait -> Civilian
    }

 

In brief, the above code iterates across every member of the list, gets the crew types within those parts, and checks if it is a civilian.  All of that is exactly what I want both classes to do.  The only change that needs to be made is changing from an argument of List<extendingClass1> or List<extendingClass2>, pending which class is calling it.  Is that possible/advisable?  Or would I be better off copy/pasting that function in each class?

And another question:  Currently OldClass is overriding OnFixedUpdate().  Should I leave it and the common method invocations in newBaseClass, with extendingClass1 and extendingClass2 calling only what is different?  Or should there be no OnFixedUpdate() method in newBaseClass, instead have it only called in extendingClass1 and extendingClass2?

 

Thank you!

On the first question.. I think you are talking about Method overloading.
http://www.dotnetperls.com/overload

On the second question, depends on what FixedUpdate is doing. I'm not sure I am following what you are asking. Should you split your FixedUpdate processing across the extension classes? or keep it all in the one class?

Link to comment
Share on other sites

I'd need some more code to tell you what my correct answer would be, but I'd look at casting the type of the list.

By that I mean, write the function to accept a type of List<newBaseClassMember>, then in each inherited class, cast the List<extendingClass1Member> back to List<newBaseClassMember> when calling the method.

Alternatively, define the list in the base class then just use it in the inherited classes.

There are other ways of handling this, but without seeing how newBaseClass and the extendingClasses are going to define stuff I can't tell you which method I would prefer using.

On the FixedUpdate() question, I don't think it matters. Unity (and so KSP) only calls the FixedUpdate methods on instances of the class that exist. If there are no instances of the newBaseClass object, the FixedUpdate method in that class will never run even if it exists.

Hope that helps,

D.

Edited by Diazo
Link to comment
Share on other sites

43 minutes ago, JPLRepo said:

On the first question.. I think you are talking about Method overloading.
http://www.dotnetperls.com/overload

On the second question, depends on what FixedUpdate is doing. I'm not sure I am following what you are asking. Should you split your FixedUpdate processing across the extension classes? or keep it all in the one class?

Thank you.  I knew about overloading constructors but didn't put it together with the fact that constructors are methods, too...oops!  And then I can have the overloaded methods call a common (regular) method.

For the second question, you're spot on.  I'm asking how I can split OnFixedUpdate process between an extended class and the extending class.  In the testing I've done thusfar, it looks like the override modifier overrides all instances of OnFixedUpdate().  I was wondering if there was a way around that.  If not, I will call the methods and logic within the respective extending classes.

edit:  Here is the code I am using to check if OnFixedUpdate() will run in extended classes:

using System;
using UnityEngine;
using KSP;

namespace PopulationMod
{
  public class CivilianDockGrowth: PartModule
  {
    public override void OnFixedUpdate ()
    {
      Debug.Log (debuggingClass.modName + "CivilianDockGrowth checking in!");
    }


  public class CivilianSpawnGrowth: CivilianDockGrowth
  {
    public override void OnFixedUpdate ()
    {
      Debug.Log (debuggingClass.modName + "CivilianSpawnGrowth checking in!");
    }
  }
}

And I'm implementing it in a part's .cfg within module like so:

MODULE
	{
		name = CivilianSpawnGrowth
	}

Which outputs:

[LOG 17:28:09.198] [CivilianPop Revamp]CivilianSpawnGrowth checking in!
[LOG 17:28:09.202] [CivilianPop Revamp]CivilianSpawnGrowth checking in!
[LOG 17:28:09.204] [CivilianPop Revamp]CivilianSpawnGrowth checking in!
[LOG 17:28:09.257] [CivilianPop Revamp]CivilianSpawnGrowth checking in!
[LOG 17:28:09.258] [CivilianPop Revamp]CivilianSpawnGrowth checking in!

Note that CivilainDockGrowth is never reported to the log.

Edited by Tralfagar
adding code and findings
Link to comment
Share on other sites

Yes, that is how overiding works, the FixedUpdate in the sub-class runs in place of the FixedUpdate in the parent class.

You can make use of the BASE modifier however, if you stick "base.FixedUpdate()" on a line in the sub-class, it will run the FixedUpdate in the parent class at that point, then finish off running the FixedUpdate() in the sub-class.

public class CivilianSpawnGrowth: CivilianDockGrowth
  {
    public override void OnFixedUpdate ()
    {
      Debug.Log (debuggingClass.modName + "CivilianSpawnGrowth checking in!");
	  base.OnFixedUpdate(); //as so
    }
  }

D.

Link to comment
Share on other sites

38 minutes ago, Diazo said:

I'd need some more code to tell you what my correct answer would be, but I'd look at casting the type of the list.

By that I mean, write the function to accept a type of List<newBaseClassMember>, then in each inherited class, cast the List<extendingClass1Member> back to List<newBaseClassMember> when calling the method.

Alternatively, define the list in the base class then just use it in the inherited classes.

There are other ways of handling this, but without seeing how newBaseClass and the extendingClasses are going to define stuff I can't tell you which method I would prefer using.

On the FixedUpdate() question, I don't think it matters. Unity (and so KSP) only calls the FixedUpdate methods on instances of the class that exist. If there are no instances of the newBaseClass object, the FixedUpdate method in that class will never run even if it exists.

Hope that helps,

D.

I've done some reading and casting looks like it'll work well.

Now to figure out how to use git while my code still runs!

9 minutes ago, Diazo said:

Yes, that is how overiding works, the FixedUpdate in the sub-class runs in place of the FixedUpdate in the parent class.

You can make use of the BASE modifier however, if you stick "base.FixedUpdate()" on a line in the sub-class, it will run the FixedUpdate in the parent class at that point, then finish off running the FixedUpdate() in the sub-class.


public class CivilianSpawnGrowth: CivilianDockGrowth
  {
    public override void OnFixedUpdate ()
    {
      Debug.Log (debuggingClass.modName + "CivilianSpawnGrowth checking in!");
	  base.OnFixedUpdate(); //as so
    }
  }

D.

Good to know.  I'll test to see how base interacts, but that will be after I've had some time to start writing the new classes.  Again, thank you!

Link to comment
Share on other sites

17 hours ago, sarbian said:

If you open the KSP.log you should see if your mod is loaded. Look for the "Mod DLLs found" line near the start of the log.

I see that my mod is being found, but there is an exception that occurs:

AssemblyLoader: Exception loading 'TutorialMod': System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.

  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (bool)

  at System.Reflection.Assembly.GetTypes () [0x00000] in <filename unknown>:0 

  at AssemblyLoader.LoadAssemblies () [0x00000] in <filename unknown>:0 

Additional information about this exception:

 System.TypeLoadException: Could not load type 'System.Configuration.ApplicationSettingsBase' from assembly 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

This is the code for my mod:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace TutorialMod
{
	[KSPAddon(KSPAddon.Startup.EveryScene, false)]
	class TestMod : MonoBehaviour
	{
		void Awake()
		{
			Debug.Log("TestMod::Awake");
		}
	}
}

This the only file in my mod (called TestMod.cs) and I've created the folder KSP/GameData/TutorialMod wherein I've placed the resulting TutorialMod.dll.

I've added Assembly-CSharp, KSPUtil and UnityEngine as references, compiling a Class Library with .NET Framework 3.5 using Visual Studio 2015 Community edition.

Any idea what I'm doing wrong?

Link to comment
Share on other sites

Copy the game folder to somewhere else and try again. Windows or your anti virus may prevent le dll loading, it s a common issue. The game does not have any DRM so il will work from anywhere.

Link to comment
Share on other sites

58 minutes ago, michaelenger said:

I installed i via Steam so it rests here: C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program

In addition to what sarbian said, it's also generally not a good idea to mod your Steam install (because Steam installs updates automatically which might not be compatible with installed mods).  So yeah, copy KSP to another location and mod there.

Link to comment
Share on other sites

10 minutes ago, blowfish said:

In addition to what sarbian said, it's also generally not a good idea to mod your Steam install (because Steam installs updates automatically which might not be compatible with installed mods).  So yeah, copy KSP to another location and mod there.

I copied the game from the Steam folder to my Program Files folder and when I boot it up it gets stuck on the loading screen with this in the log:

(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 64)

InvalidOperationException: Steamworks is not initialized.
  at Steamworks.InteropHelp.TestIfAvailableClient () [0x00000] in <filename unknown>:0 

  at Steamworks.SteamController.Shutdown () [0x00000] in <filename unknown>:0 

  at SteamController.KSPSteamController.OnDestroy () [0x00000] in <filename unknown>:0 

  at SteamController.KSPSteamController.OnApplicationQuit () [0x00000] in <filename unknown>:0 
 
(Filename:  Line: -1)

[UIApp] OnDestroy: MessageSystem
 
(Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 64)

InvalidOperationException: Steamworks is not initialized.
  at Steamworks.InteropHelp.TestIfAvailableClient () [0x00000] in <filename unknown>:0 

  at Steamworks.SteamController.Shutdown () [0x00000] in <filename unknown>:0 

  at SteamController.KSPSteamController.OnDestroy () [0x00000] in <filename unknown>:0 
 
(Filename:  Line: -1)

 

Link to comment
Share on other sites

13 minutes ago, michaelenger said:

I copied the game from the Steam folder to my Program Files folder and when I boot it up it gets stuck on the loading screen with this in the log:

That's odd.  Did you copy the entire KSP folder?  Could you try installing Steam.

Also probably not the cause of this issue (although maybe), but it's probably best to put it somewhere other than Program Files, as Windows puts certain restrictions on what it will allow in there.

Link to comment
Share on other sites

8 minutes ago, blowfish said:

That's odd.  Did you copy the entire KSP folder?  Could you try installing Steam.

Also probably not the cause of this issue (although maybe), but it's probably best to put it somewhere other than Program Files, as Windows puts certain restrictions on what it will allow in there.

I copied it into my documents and now it works. Magic, I guess.

My mod still fails to load with the same error in the log. I'm running Windows 10 and I don't have any separate antivirus or anything, so how do I disable any blocks Windows may have placed on the mod?

Link to comment
Share on other sites

Hi friends!

I'm working to revive the ESLD Jump Beacons mod, and the only feature that still isn't working in 1.1 is the post-jump orbit predictions. The method used by TMarkos originally (https://www.reddit.com/r/KerbalAcademy/comments/2eolvd/things_i_learned_about_orbit_display/) doesn't seem to work anymore. Does anyone watching this thread have any experience with drawing hypothetical orbits or orbits that have no vessel assigned in the map view or ideas about how this could be done?

Thanks!

Link to comment
Share on other sites

  • 2 weeks later...
On 19/06/2016 at 7:34 PM, RoyalVengeance said:

@wasml Fixed it ! Thanks ! Now I need to learn how to set up a ladder  + EVA door + crew. I'm trying to do a simple capsule and I can't find a good tutorial anywhere. Especially for Unity. 

You may have more luck if you ask in the moddeling section instead of the thread about coding plugins :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...