Difference between revisions of "Tutorial:Creating your first module"
(Created page with "So you've got your IDE all set up. Now what? The next step involves coding your first part module. Quit shaking, it's actually very simple to add things to KSP, and won't t...") |
m (New version of KSP there are two RCSBlock types for the small and standard size. The new block has had its name changed to RCSBlock_v2.) |
||
(40 intermediate revisions by 26 users not shown) | |||
Line 1: | Line 1: | ||
So you've got your IDE all set up. Now what? | So you've got your IDE all set up. Now what? | ||
− | The next step involves coding your first | + | The next step involves coding your first PartModule class. Quit shaking, it's actually very simple to add things to KSP, and won't take you very long to complete. |
'''This tutorial assumes you're using Visual Studio 2010, but any IDE will do; Adapt accordingly!''' | '''This tutorial assumes you're using Visual Studio 2010, but any IDE will do; Adapt accordingly!''' | ||
Line 7: | Line 7: | ||
== First Things First == | == First Things First == | ||
− | You've managed to slog through | + | You've managed to slog through [[Setting up Visual Studio]] (for Windows) or [[Setting up MonoDevelop]] (for Windows/Linux/Mac), and you've got an empty class open in front of you with a pretty uncreative name. |
− | < | + | <syntaxhighlight> |
− | |||
using System; | using System; | ||
using System.Collections.Generic; | using System.Collections.Generic; | ||
Line 22: | Line 21: | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
− | + | We're going to rename the class to something nice and creative, like '''HelloKerbinMod'''. As a matter of good practices, remember to rename the file the class is in! (In VS2010, right-click the file and choose Rename.) | |
− | |||
− | We're | ||
After compulsively re-indenting (VS2010: CTRL+E, D) it looks like this: | After compulsively re-indenting (VS2010: CTRL+E, D) it looks like this: | ||
− | < | + | <syntaxhighlight> |
using System; | using System; | ||
using System.Collections.Generic; | using System.Collections.Generic; | ||
Line 36: | Line 33: | ||
using System.Text; | using System.Text; | ||
− | + | namespace MyKSPProject | |
{ | { | ||
+ | public class HelloKerbinMod | ||
+ | { | ||
+ | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
Awesome, now we can move on to the good stuff. | Awesome, now we can move on to the good stuff. | ||
Line 45: | Line 45: | ||
== The Good Stuff == | == The Good Stuff == | ||
− | === Extending | + | === Extending PartModule === |
− | Part Modules all have one thing in common: They extend the | + | Part Modules all have one thing in common: They extend the PartModule class. The PartModule class defines a bunch of easy to use and intuitive methods and properties which you must override to do things with your module. |
− | So, let's go ahead and extend | + | So, let's go ahead and extend PartModule. You don't need to add any ''using'' directives; It's in the global namespace as long as you have your KSP DLLs referenced correctly. However, you will need to add a ''using'' directive for the <code>UnityEngine</code> namespace in order to access debug functionality. Note that, again, compulsive cleanup was done. |
− | '''DO NOT ADD A CONSTRUCTOR, KSP DOESN'T LIKE CONSTRUCTORS!''' | + | '''DO NOT ADD A CONSTRUCTOR, Unity (and, by extension, KSP) DOESN'T LIKE CONSTRUCTORS!''' |
− | < | + | <syntaxhighlight> |
using System; | using System; | ||
using System.Collections.Generic; | using System.Collections.Generic; | ||
using System.Linq; | using System.Linq; | ||
using System.Text; | using System.Text; | ||
+ | using UnityEngine; | ||
− | + | namespace MyKSPProject | |
{ | { | ||
+ | public class HelloKerbinMod : PartModule | ||
+ | { | ||
+ | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
=== Showing Up to Class === | === Showing Up to Class === | ||
− | When a part module is first loaded, | + | When a part module is first loaded, PartModule.OnStart(StartState state) is called. Here, we can set up low-level things like icons. |
− | So, let's go ahead and override | + | So, let's go ahead and override <code>OnStart</code>. You don't need the <code>base.OnStart()</code> stuff, so let's toss that and add some documentation like good programmers do. The <code>override</code> modifier isn't necessary, but it's good practice and will throw compile errors in case HarvesteR moves things around. |
− | < | + | <syntaxhighlight> |
using System; | using System; | ||
using System.Collections.Generic; | using System.Collections.Generic; | ||
using System.Linq; | using System.Linq; | ||
using System.Text; | using System.Text; | ||
+ | using UnityEngine; | ||
− | + | namespace MyKSPProject | |
− | |||
− | |||
− | |||
{ | { | ||
/// <summary> | /// <summary> | ||
− | /// | + | /// My first part! |
/// </summary> | /// </summary> | ||
− | + | public class HelloKerbinMod : PartModule | |
{ | { | ||
+ | /// <summary> | ||
+ | /// Called when the part is started by Unity. | ||
+ | /// </summary> | ||
+ | public override void OnStart(StartState state) | ||
+ | { | ||
+ | } | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | For what OnStart etc does, see the part module lifecycle (https://forum.kerbalspaceprogram.com/index.php?/topic/145340-the-lifecycle-of-a-part-module-a-primer/). | ||
So we've got a method now, but it doesn't really do anything. So, let's just print something silly to the log. | So we've got a method now, but it doesn't really do anything. So, let's just print something silly to the log. | ||
− | < | + | <syntaxhighlight> |
using System; | using System; | ||
using System.Collections.Generic; | using System.Collections.Generic; | ||
Line 96: | Line 106: | ||
using System.Text; | using System.Text; | ||
− | + | using UnityEngine; | |
− | + | ||
− | + | namespace MyKSPProject | |
− | |||
{ | { | ||
/// <summary> | /// <summary> | ||
− | /// | + | /// My first part! |
/// </summary> | /// </summary> | ||
− | + | public class HelloKerbinMod : PartModule | |
{ | { | ||
− | // Add stuff to the log | + | /// <summary> |
− | + | /// Called when the part is started by Unity. | |
+ | /// </summary> | ||
+ | public override void OnStart(StartState state) | ||
+ | { | ||
+ | // Add stuff to the log | ||
+ | print("Hello, Kerbin!"); | ||
+ | } | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | Cool! Now compile the DLL and find it - it should be YourSolution/YourProject/bin/Debug/MyKSPProject.dll. To install it, create GameData/MyKSPProject/Plugins/ inside KSP's GameData/ directory, and drop the DLL in your new Plugins/ directory. | ||
+ | |||
+ | == Adding to a Part == | ||
+ | |||
+ | === By copying a part === | ||
+ | |||
+ | * Because we're just making a simple test part, make a copy of the "RCS block" directory and edit part.cfg. (As of 1.4.3, located in GameData\Squad\Parts\Utility and named rcsBlockRV-105) | ||
+ | * Now, change part.cfg so that <code>MODULE { name = ModuleRCS</code> becomes <code>MODULE { name = HelloKerbinMod</code>. | ||
+ | * Our part needs a name. Change the <code>name =</code> at the top of the file from ''RCSBlock'' to something like ''MyUselessPart''. | ||
+ | |||
+ | Save the .cfg file. When you load the game, you'll discover that the RCS block is indeed there. And it doesn't do anything. | ||
+ | |||
+ | === Or using ModuleManager === | ||
+ | |||
+ | Alternately, you could begin as you should continue and use ModuleManager - a separate download - to patch the module into an existing part. Install ModuleManager.dll to GameData/ if you don't already have it. | ||
+ | |||
+ | Now create a new GameData/MyKSPProject/HelloKerbinMod_rcs.cfg file with Notepad++ or a similar text editor. Its contents should be: | ||
+ | |||
+ | <syntaxhighlight> | ||
+ | // Modify the stock part "RCSBlock" from GameData/Squad/Parts/Utility/rcsBlockRV-105/rcsBlockRV-105.cfg | ||
+ | @PART[RCSBlock_v2] | ||
+ | { | ||
+ | // Add a new module | ||
+ | MODULE | ||
+ | { | ||
+ | // using the HelloKerbinMod PartModule subclass | ||
+ | name = HelloKerbinMod | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | When you start KSP, existing RCS thrusters will now have your new module too! | ||
+ | |||
+ | == Build and Test == | ||
+ | |||
+ | Load the game, create a new vessel and add your new part to it. Now we can see something silly in our KSP.log and/or our output_log. (See https://forum.kerbalspaceprogram.com/index.php?/topic/83212-how-to-get-support-read-first/ for details on where to find the game logs). | ||
+ | |||
+ | Alternatively, press ALT+F12 to bring up the ingame debug console. It might've scrolled off though. | ||
+ | |||
+ | == Common Problems == | ||
+ | |||
+ | Verify your project targets .NET 3.5 - many newer compilers and IDEs target 4.0. (Not relevant for newer KSP; 1.4.x uses Unity 2017 with .NET 4.5). | ||
+ | |||
+ | Linux systems may be missing the PCL assembly libraries, which will cause compilation to fail due to their absence. Check the [[Setting_up_MonoDevelop#PCL_assemblies_for_Linux_systems|Setting up MonoDevelop]] page for more information. (No longer an issue in newer Mono, so only try to fix it if you have a problem). | ||
+ | |||
+ | == Continuing the Legacy == | ||
+ | |||
+ | Now it's your turn. Try overriding various methods in PartUpdate, like onUpdate. Over the coming weeks, more information can be found at [[Plugins]]. | ||
− | + | [[Category:Tutorials|Creating your first module]] | |
+ | [[Category:Plugin SDK Tutorials|Creating your first module]] | ||
+ | [[Category:Modding Tutorials|Creating your first module]] |
Latest revision as of 23:25, 17 March 2022
So you've got your IDE all set up. Now what?
The next step involves coding your first PartModule class. Quit shaking, it's actually very simple to add things to KSP, and won't take you very long to complete.
This tutorial assumes you're using Visual Studio 2010, but any IDE will do; Adapt accordingly!
Contents
First Things First
You've managed to slog through Setting up Visual Studio (for Windows) or Setting up MonoDevelop (for Windows/Linux/Mac), and you've got an empty class open in front of you with a pretty uncreative name.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyKSPProject { public class Class1 { } }
We're going to rename the class to something nice and creative, like HelloKerbinMod. As a matter of good practices, remember to rename the file the class is in! (In VS2010, right-click the file and choose Rename.)
After compulsively re-indenting (VS2010: CTRL+E, D) it looks like this:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyKSPProject { public class HelloKerbinMod { } }
Awesome, now we can move on to the good stuff.
The Good Stuff
Extending PartModule
Part Modules all have one thing in common: They extend the PartModule class. The PartModule class defines a bunch of easy to use and intuitive methods and properties which you must override to do things with your module.
So, let's go ahead and extend PartModule. You don't need to add any using directives; It's in the global namespace as long as you have your KSP DLLs referenced correctly. However, you will need to add a using directive for the UnityEngine
namespace in order to access debug functionality. Note that, again, compulsive cleanup was done.
DO NOT ADD A CONSTRUCTOR, Unity (and, by extension, KSP) DOESN'T LIKE CONSTRUCTORS!
using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace MyKSPProject { public class HelloKerbinMod : PartModule { } }
Showing Up to Class
When a part module is first loaded, PartModule.OnStart(StartState state) is called. Here, we can set up low-level things like icons.
So, let's go ahead and override OnStart
. You don't need the base.OnStart()
stuff, so let's toss that and add some documentation like good programmers do. The override
modifier isn't necessary, but it's good practice and will throw compile errors in case HarvesteR moves things around.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace MyKSPProject { /// <summary> /// My first part! /// </summary> public class HelloKerbinMod : PartModule { /// <summary> /// Called when the part is started by Unity. /// </summary> public override void OnStart(StartState state) { } } }
For what OnStart etc does, see the part module lifecycle (https://forum.kerbalspaceprogram.com/index.php?/topic/145340-the-lifecycle-of-a-part-module-a-primer/).
So we've got a method now, but it doesn't really do anything. So, let's just print something silly to the log.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace MyKSPProject { /// <summary> /// My first part! /// </summary> public class HelloKerbinMod : PartModule { /// <summary> /// Called when the part is started by Unity. /// </summary> public override void OnStart(StartState state) { // Add stuff to the log print("Hello, Kerbin!"); } } }
Cool! Now compile the DLL and find it - it should be YourSolution/YourProject/bin/Debug/MyKSPProject.dll. To install it, create GameData/MyKSPProject/Plugins/ inside KSP's GameData/ directory, and drop the DLL in your new Plugins/ directory.
Adding to a Part
By copying a part
- Because we're just making a simple test part, make a copy of the "RCS block" directory and edit part.cfg. (As of 1.4.3, located in GameData\Squad\Parts\Utility and named rcsBlockRV-105)
- Now, change part.cfg so that
MODULE { name = ModuleRCS
becomesMODULE { name = HelloKerbinMod
. - Our part needs a name. Change the
name =
at the top of the file from RCSBlock to something like MyUselessPart.
Save the .cfg file. When you load the game, you'll discover that the RCS block is indeed there. And it doesn't do anything.
Or using ModuleManager
Alternately, you could begin as you should continue and use ModuleManager - a separate download - to patch the module into an existing part. Install ModuleManager.dll to GameData/ if you don't already have it.
Now create a new GameData/MyKSPProject/HelloKerbinMod_rcs.cfg file with Notepad++ or a similar text editor. Its contents should be:
// Modify the stock part "RCSBlock" from GameData/Squad/Parts/Utility/rcsBlockRV-105/rcsBlockRV-105.cfg @PART[RCSBlock_v2] { // Add a new module MODULE { // using the HelloKerbinMod PartModule subclass name = HelloKerbinMod } }
When you start KSP, existing RCS thrusters will now have your new module too!
Build and Test
Load the game, create a new vessel and add your new part to it. Now we can see something silly in our KSP.log and/or our output_log. (See https://forum.kerbalspaceprogram.com/index.php?/topic/83212-how-to-get-support-read-first/ for details on where to find the game logs).
Alternatively, press ALT+F12 to bring up the ingame debug console. It might've scrolled off though.
Common Problems
Verify your project targets .NET 3.5 - many newer compilers and IDEs target 4.0. (Not relevant for newer KSP; 1.4.x uses Unity 2017 with .NET 4.5).
Linux systems may be missing the PCL assembly libraries, which will cause compilation to fail due to their absence. Check the Setting up MonoDevelop page for more information. (No longer an issue in newer Mono, so only try to fix it if you have a problem).
Continuing the Legacy
Now it's your turn. Try overriding various methods in PartUpdate, like onUpdate. Over the coming weeks, more information can be found at Plugins.