Jump to content

Example plugin projects to help you get started


Recommended Posts

I have been working on a set of examples that I hope people will find useful for learning how to write plugins for KSP and as a starting point for their mods: https://github.com/taraniselsu/TacExamples. I also hope to have working examples of how to implement certain things in KSP/Unity.

So far I have:

  • 01: A simple part-less plugin.
  • 02: A simple PartModule plugin.
  • 03: A part with right-click events.
  • 04: A part with action group events.

In the works:

Coming soon:

You can download the source code from this link: https://github.com/taraniselsu/TacExamples/archive/master.zip.

I hope that helps. Feedback will be much appreciated.

Edited by TaranisElsu
Link to comment
Share on other sites

Thanks for this. As an experienced programmer but total newbie to KSP modding it's nice to see how people set things up. I particularly like that you included the build events to show how you might actually do it in anger.

Personally I'd like to see more examples of how to interact with the Kerbal world via API. That's kind of vague, but some starters for things like handling collisions, spawning new objects etc would be nice.

Link to comment
Share on other sites

A suggestion for another example project: Adding a sound to something. If you need some sample code, there's a module here.

From your signature, it looks like you would be a better person to do it than me. I have not done anything with sound yet. If you would, make a simple example and send me a pull request on Github, or send a link to a file by pm, and I will include it in the package. I can even edit it and polish it if you want to just make a rough example.

Other examples, from anyone, are also welcome.

Link to comment
Share on other sites

  • 2 weeks later...

I started having a fiddle with this today, but it seems that you did not carry over the window class from TACLib.

Do you have any plans for including UI into the examples? Specifically I would love to see an example of how to do a partless plugin with an icon that brings up a GUI.

Link to comment
Share on other sites

I started having a fiddle with this today, but it seems that you did not carry over the window class from TACLib.

Do you have any plans for including UI into the examples? Specifically I would love to see an example of how to do a partless plugin with an icon that brings up a GUI.

I was planning on having a few GUI examples. I feel that your project got a little complicated, so I think we should split it into multiple example projects. Each example showing how to do one new thing.

I am trying to finish an update to my Life Support mod, so I won't have much time to work on this for the next week but after that I should be able to add to it or help others add to it (hint hint).

Link to comment
Share on other sites

  • 2 weeks later...

is it just me or could the instructions be more...documented?

I downloaded the .cs files and modified them....

Okay now what..........?

Do i click on deploy, package, or test.bat??

Do i open the .csproj file in visual studio and build the .dll from there?

I like the idea of this it would just be..great to have a tutorial to go along with it..

Edited by KFS
Link to comment
Share on other sites

  • 2 weeks later...
is it just me or could the instructions be more...documented?

I downloaded the .cs files and modified them....

Okay now what..........?

Do i click on deploy, package, or test.bat??

Do i open the .csproj file in visual studio and build the .dll from there?

I like the idea of this it would just be..great to have a tutorial to go along with it..

This is not finished yet, I just have not had time to work on it much lately. I agree that the documentation needs to be filled in more, and I should probably link to a few tutorials on programming. This project assumes that you have experience working with Visual Studio and writing C# code.

To answer your question (sorry for the long delay): open TacExamples.sln in Visual Studio, then right click the project that you want to compile and select "Build". The batch files (deploy and test) were there to show how I automatically copy the files to my test install of KSP and to my regular play install. You will need to edit them or create the KSP_TEST and KSP_PLAY environment variables. You will also need to fix the paths for the KSP dll's in each project file.

This might just give the the push I needed to tackle plugins! Thank you! :D

You're welcome!

Link to comment
Share on other sites

  • 3 weeks later...

First off a big thanks for TacLib and the tutorials -- I started off wanting to make a partless mod with a GUI window and looking through several resources, these tutorials and the library were the most helpful to me. Also a thanks for the support in IRC. :)

Just to have Google hopefully show this sometime when someone is looking for it: I added TacLib to my mod in VisualStudio Express 2013 and everything compiled fine, but I would get the following error messages in the KSP.log:

[LOG 03:11:53.966] Load(Assembly): MyPlugin/Plugins/MyPlugin
[LOG 03:11:53.968] AssemblyLoader: Loading assembly at C:\Program Files (x86)\Steam\SteamApps\common\Kerbal Space Program\GameData\MyPlugin\Plugins\MyPlugin.dll
[LOG 03:11:54.033] AssemblyLoader: Loading assemblies
[ERR 03:11:54.057] AssemblyLoader: Exception loading 'MyPlugin': 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 'Tac.Icon`1[T]' from assembly 'MyPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type 'Tac.PartExtensions' from assembly 'MyPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type 'Tac.PopupWindow' from assembly 'MyPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type 'Tac.ToolbarButton' from assembly 'MyPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type 'Tac.ToolbarWrapper' from assembly 'MyPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type '<>c__DisplayClass6' from assembly 'MyPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type '<>c__DisplayClasse' from assembly 'MyPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type '<>c__DisplayClass2' from assembly 'MyPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Someone in the chat hinted me to how to solve this: The project target has to be changed to .NET 3.5, then everything works fine.

@TaranisElsu

Another thing I found is that TacLib (in parts) requires the Toolbar plugin. Maybe you could add that somewhere in the README or whatever. It's probably obvious to experienced mod developers, but mentioning dependencies is probably not a bad idea either way. :)

Link to comment
Share on other sites

Someone in the chat hinted me to how to solve this: The project target has to be changed to .NET 3.5, then everything works fine.

That is really important. KSP/Unity only uses 3.5 and does not work very well with later versions of .NET.

Another thing I found is that TacLib (in parts) requires the Toolbar plugin. Maybe you could add that somewhere in the README or whatever. It's probably obvious to experienced mod developers, but mentioning dependencies is probably not a bad idea either way. :)

I would not say the code "requires" the Toolbar plugin because it should compile without it. I tried hard to make it use the toolbar if it is there, but work fine if the toolbar is not there. I definitely need to improve the documentation in TacLib.

Link to comment
Share on other sites

  • 1 month later...

Hello all.

This is my first post :D

Wanted to say I've just started looking at making a plugin and hope you continue working on this helpful documentation. Even if things kinda dropped off, thanks for everything you've written so far, Taranis!

Link to comment
Share on other sites

[*] 05: How to use KSPField's -- not done yet, and not working as written -- not sure why I cannot get it to work for MyType. I have gone through http://forum.kerbalspaceprogram.com/threads/7529-Plugin-Posting-Rules-And-Official-Documentation?p=156430&viewfull=1#post156430, among other sources, and still cannot figure it out :(

Any more ideas on how to make this work?

It's really doing my head in too. It *should* work according to the unity documentation, but unity seems to stubbornly refuse to copy anything in Instantiate that is Serializable.

I'm about to give in and serialize the data to an array of strings, which I know does get copied on Instantiate.

Edit:

If you store a byte array in the class and mark it with [serializableField] then this will get cloned correctly. You can use this to copy complex stuff from the config file. I can commit a change to the example that shows how to do this if you like.

Edited by swamp_ig
Link to comment
Share on other sites

Any more ideas on how to make this work?

It's really doing my head in too. It *should* work according to the unity documentation, but unity seems to stubbornly refuse to copy anything in Instantiate that is Serializable.

I'm about to give in and serialize the data to an array of strings, which I know does get copied on Instantiate.

Edit:

If you store a byte array in the class and mark it with [serializableField] then this will get cloned correctly. You can use this to copy complex stuff from the config file. I can commit a change to the example that shows how to do this if you like.

Yes, please send me a pull request showing how to do that. I appreciate it :)

Link to comment
Share on other sites

It's really doing my head in too. It *should* work according to the unity documentation, but unity seems to stubbornly refuse to copy anything in Instantiate that is Serializable.

That's because it plainly ignores Serializable unless it's on a class in one of the original dlls, like Assembly-CSharp.

Link to comment
Share on other sites

Is that what it is? Weird really since the original DLLs have nothing to do with unity really.

I guess the thing is there's three different persistence mechanisms going on here:

1. Unity serialization. This uses Serializable and SerializableField attributes. This is needed to clone objects (ie: Object.Instantiate). There's a good blog post about it here: http://blogs.unity3d.com/2012/10/25/unity-serialization/ but suffice to say it doesn't seem to work for classes compiled into a DLL. Maybe there's some way of getting unity to produce

some kind of asset or something to make it work, I got narked with the whole thing in the end.

2. ConfigNode stuff. This is actually pretty well developed and seems to cover most cases. This uses the Persistent and PersistentLinkable attributes. I haven't actually investigated PersistentLinkable much, but it looks like you can persist references with that.

3. KSPField attributes. These do actually work for classes, but not for arrays or lists of things which is an annoyance. You can write your own deserializer for lists of things in the OnLoad function. I don't think it works with references either. Not sure why they didn't just use the config node code as a basis for this, but *shrug*

So everything loads and saves to config files fine, but anything you set up there into your own classes won't persist across Object.Instantiate, which pretty much defeats the whole purpose.

I imagine if you bashed your head against unity serialization for long enough you might figure it out, but I've given up on that approach. Fortunately if you somehow store anything loaded from the part config file at the end of the OnLoad as a member, and then reinitialize it in OnAwake, then you get around the issue of Object.Instantiate not copying stuff properly.

You could probably get away with storing the ConfigNode as a member marked with SerializeField actually, but I figured why not just add yet another serialization mechanism and used the standard c# way.

Will do a git merge request shortly...

Link to comment
Share on other sites

Ok the merge request is done.

Some things that might be worth mentioning in the SimplePartModule docs for life cycle:

1. All the OnXXX messages are sent from the corresponding unity message to the parent Part. The exception to this is OnActive for which I haven't traced fully where it comes from. These get called in the same order as the modules are defined in the config file.

2. When you're attaching a part with symmetry, the part *in its current state* is run through Object.Instantiate. If you modify any data in a custom class field then unless you have reserialized it for reloading in OnAwake any tweaks will be lost. Then OnActivate->OnStart (don't know if OnSave is called, probably).

3. If you want to do anything dynamic in the VAB, you need to implement Update directly, rather than getting it through the part. This is called in no particular order.

Edited by swamp_ig
Link to comment
Share on other sites

  • 2 weeks later...
This thread is quite old. Please consider starting a new thread rather than reviving this one.

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...