Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

Is there a way to get notified when the game is saved/the persistence file is written?..

That depends a lot on which class you derive from; MonoBehaviour, Part and PartModule would be the big three. For MonoBehaviour there might be some delegates in GameEvents you'll be able work with. For PartModule, it's as simple as overriding the OnLoad and OnSave methods.

Link to comment
Share on other sites

Is there an easy way to track down Null Reference Exceptions or do I need to load up on Debug.Log() lines and just try to figure it out?

if you set


VERBOSE_DEBUG_LOG = True

in settings.cfg you get a more detailed output to the dev console, displaying which method ultimately threw the exception.

Link to comment
Share on other sites

if you set


VERBOSE_DEBUG_LOG = True

in settings.cfg you get a more detailed output to the dev console, displaying which method ultimately threw the exception.

Thanks. How do I get to the dev console, is that alt + f2?

Link to comment
Share on other sites

How can I force KSPEvent buttons to always be available when right-clicking on a part? It seems they're automatically hidden if a part has no ElectricCharge available.

I doubt they check resources on general UI stuff. Have you checked the vessel.IsControllable? I'm not sure about those Events, but there are some ControlLocks set via InputLockManager, once the vessel becomes uncontrollable. In that case, you could try to alter the ControlLock with id "vessel_noControl_"+vesselId. Or add an ControlSource (a part with isControlSource = true), though that obviously would have side effects.

Link to comment
Share on other sites

I doubt they check resources on general UI stuff. Have you checked the vessel.IsControllable? I'm not sure about those Events, but there are some ControlLocks set via InputLockManager, once the vessel becomes uncontrollable. In that case, you could try to alter the ControlLock with id "vessel_noControl_"+vesselId. Or add an ControlSource (a part with isControlSource = true), though that obviously would have side effects.

Thanks, looks like there isn't an elegant way to do what I want, will probably try a different approach.

Link to comment
Share on other sites

  • 2 weeks later...

Anyone got a suggestion on how to track down stackoverflow errors? Sometimes, i am getting this message in the output log, and shortly after that the game becomes unresponsive and crashes


StackOverflowException: The requested operation caused a stack overflow.
at (wrapper delegate-invoke) PQS/OnDefaultDelegate:invoke_void__this__ ()

at (wrapper delegate-invoke) PQS/OnDefaultDelegate:invoke_void__this__ ()

My code has a behavior with a repeating function that is called once every few seconds via InvokeRepeating(), but i am fairly sure that i have no infinite recursion in my program. If someone recognizes this message and has an idea on how to hunt this down or cure it, all help would be greatly appreciated

Also, i cannot reliably reproduce the error. It just happens occasionally. Here is the code that gets called repeatedly:



Vector3 currentPos = this.referenceBody.GetWorldSurfacePosition(sourceVessel.latitude, sourceVessel.longitude, sourceVessel.altitude);

if (waypoints.Count > 0) //waypoints is a list<Waypoint>, Waypoint is a container for 3 doubles called latidute, longitude and altitude
{
Vector3 lastPos = this.referenceBody.GetWorldSurfacePosition(waypoints.Last().latitude, waypoints.Last().longitude, waypoints.Last().altitude);
if ((lastPos - currentPos).sqrMagnitude < 1) //Minimum distance between nodes > 1m
return;
}

waypoints.Add(new Waypoint(this.sourceVessel));
Modified = true;

//add new point to renderer
if (Visible){
int vertexCount = waypoints.Count;
lineRenderer.SetVertexCount(vertexCount); //increase by one
lineRenderer.SetPosition(vertexCount - 1, currentPos);

}

Edited by SirJodelstein
Link to comment
Share on other sites

Hopefully this is a right place for this. I get lost 'round here.

I've been trying to learn C# and KSP scripting at the same time, and it's been a pain in the Kerbal, to borrow a phrase from Devo.

However, I got a basic plugin functioning that builds a list of all the Kerbals that have died ("missing") when you enter the space center scene. For now it just prints to the debug log, but I've got more interesting plans down the road. Mainly I just wanted to see if anyone had some advice on the code's structure. I have a LOT of habits from procedural programming that are difficult to break out of. (For instance, I was trying to figure out how to create a list that would contain a kerbal's name, as well as their other relevant data. Then I realized that was exactly what I was pulling that data from- an object.)

So yeah, anything stand out as being particularly inefficient/prone to breaking?

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

namespace Tor
{
[KSPAddon(KSPAddon.Startup.SpaceCentre, false)]
public class Kerborial : MonoBehaviour
{
public void Awake(){}
public void Start()
{
List<ProtoCrewMember> kerbolist = new List<ProtoCrewMember>();
foreach (ProtoCrewMember kerbal in HighLogic.CurrentGame.CrewRoster)
{
if (kerbal.rosterStatus == ProtoCrewMember.RosterStatus.MISSING)
{
print(kerbal.name);
print("Is no more!");
kerbolist.Add(kerbal);
}
}
print(kerbolist.Count);
print(" kerbals deaded");


}
}
}

Link to comment
Share on other sites

@Tor

Those are exactly 12 lines of code, 1/3rd of them printf's... sure, in the current version is no need for a list since an int would work just fine, but it isn't a performance critical location and depends on what else you want to do with this data. I don't think there is much you could do wrong in just those few lines^^


StackOverflowException: The requested operation caused a stack overflow.
at (wrapper delegate-invoke) PQS/OnDefaultDelegate:invoke_void__this__ ()

at (wrapper delegate-invoke) PQS/OnDefaultDelegate:invoke_void__this__ ()

Is that the entire stack trace? Have you checked the verbose log. It does show the entire stack of my exceptions, when i check the box on the right.

Link to comment
Share on other sites

Is that the entire stack trace? Have you checked the verbose log. It does show the entire stack of my exceptions, when i check the box on the right.

Well, i have activated the verbose logging, but i get no chance to click on the check box, the GUI becomes unresponsive at the first occurence. The stack trace comes from the KSP_Data/output.log.

And it is not the entire stack trace, the last line ( at (wrapper delegate-invoke) PQS/OnDefaultDelegate:invoke_void__this__ ()) is repeated about 21.000 times. The exceptions seems to happen in unity/KSP itself. The last debug output from my code im my output polluted function (one debug after each line of code) is different everytime i repeat that process. I have no clue....

Link to comment
Share on other sites

I am going to have many, many questions throughout this process. Is it acceptable to put them here? Should I make a (single) thread in the plugin sub-forum? Should I just go sit in my corner?

anyway, before my welcome is completely worn out,

I want to be able to save this list, in some way, and then be able to use this list to construct a sort of memorial. I /think/ the way to do this involves the OnSave and OnLoad methods, but I'm not quite sure what to do from there. There's also the option of serializing the object and using the IO functions to save the binary, but I suspect this is my procedural habits talking, and it seems unnecessarily complex.

Just to make sure I've got this right- if I write a method tagged with "override" called OnSave(), whatever I enclose in the braces will be executed whenever the game autosaves, correct? Or does this only work with part modules?

Link to comment
Share on other sites

I know I'm a little late to this, but I just bought KSP and started programming the other day. Forgive me for any newbishness and all such.

@Tor, while I'm no expert programmer or anything the code you posted earlier looks pretty good. The only thing I notice is that you have multiple print statements that you could combine together. The + operator concatenates strings together, like such:


if (kerbal.rosterStatus == ProtoCrewMember.RosterStatus.MISSING)
{
print(kerbal.name + " is no more!");
kerbolist.Add(kerbal);
}

As far as OnSave and OnLoad methods, I've got a question about that as well. I wrote my first part mod yesterday and the basic idea is that this part takes a resource as input and spits out another resource (or two) as output; it's basically a sort of matter converter. Right now I have it hardcoded to use ElectricCharge to generate LiquidFuel and Oxidizer at a rate of 3 Electric per .5 LiquidFuel/Oxidizer. I thought, though, that it'd make more sense for the part to specify the rates at which it uses resources and attempted to implement an OnLoad() function to read the information from part.cfg and use those values.

And that's where I ran into an issue. I followed the example in the Official Documentation thread but this is my first time programming for KSP and my first time using C#, so I'm not sure where the issue I'm having is originating from. Basically when I use node.GetValue() whatever I read in gets the default value for that variable type.


class ElectricToFuelConverter : PartModule
{
[KSPField]
public string resourceIn = "ElectricCharge";
public string resourceOut1 = "LiquidFuel";
public string resourceOut2 = "Oxidizer";

[KSPField(isPersistant=true)]
public double resourceInAmount = 3;
[KSPField(isPersistant = true)]
public double resourceOutAmount = .5;

[KSPField(isPersistant=true)]
public bool generatorEnabled;

//Do stuff in the middle to make it actually resource
//Do more stuff in the middle

public override void OnLoad(ConfigNode node)
{
string temp = node.GetValue("generatorEnabled");
print(temp);

if (temp.Equals("true") == true)
{
Activate();
print("Loaded. Activating.");
}
else
{
Deactivate();
print("Loaded. Deactivating.");
}


print(node.GetValue("resourceInAmount"));
print(node.GetValue("resourceOutAmount"));
resourceInAmount = Convert.ToDouble(node.GetValue("resourceInAmount"));
print("My resource in amount is " + resourceInAmount);
resourceOutAmount = Convert.ToDouble(node.GetValue("resourceOutAmount"));
print("My resource out amount is " + resourceOutAmount);


}
}

Does anyone have any suggestions?

Link to comment
Share on other sites

Hi fellow KSP programmers

For some time, I have wanted to add a "solar sail" to the game, but I have ran into a deadlock.

I have extended the ModuleDeployableSolarPanel class, and then added some code in the OnUpdate function, that changes the crafts velocity based on the flowrate of the solar panel. It works fine, but I am unable to warp. I know you can't warp while the ship is throttled up, but I do not use throttle. At first I did it with rigidbody.AddForce. This worked just as fine, but I still couldn't warp.

Does anyone have a clue about how to bypass the warp limitation? Any way of modifying the velocity/trajectory while warped?

How do I even detect if time is warped?

Any ideas are would be helpfull :)

Best regards

RCSub

Link to comment
Share on other sites

I do not know how to get around the issue with time warp being disabled you are having, but to detect if Time Warp is enabled uses the TimeWarp class.

Looks like TimeWarp.Modes WarpMode and TimeWarp CurrentRate are what you need to look at.

Looking at the class, I see Gets all over the place, but no Sets, so it is looking like TimeWarp is pretty locked down in terms of controlling it.

disclaimer: I have not worked with TimeWarp at all, this is from a 2 second look through the documentation so YMMV.

D.

Link to comment
Share on other sites

Hi.

Where can i find good c# tutorials? Im trying to translate some Python code to C# terminal app, so MarkusA380 can integrate it to a plugin. And i want to learn C# so i can help with the plugin itself.

The plugin i talking about is http://forum.kerbalspaceprogram.com/showthread.php/35310-The-L-O-G-Multiplayer-Project

P.S: dont say anything about google, it gives me tutorials from 2002

Link to comment
Share on other sites

Hi guys,

I'm rather new when it comes to building plugins for KSP but I have programmed quite much in C# earlier. Right now I want to create a GUI window which will be visible in the construction scene which will show you a list of all parts you've placed on your ship (I need it for a bigger project). So what I'm looking for is a rough description of how to access the parts of the ship while in the construction stage?

I'll be really greatful for all help I can get.

Edited by jimutt
Link to comment
Share on other sites

For this, take a look at the TAC Part Lister which does exactly that.

http://kerbalspaceprogram.com/tac-part-lister-0-2025may/

(Note I am not associated with TAC or that mod at all.)

Also, I'm looking to interface with the navball at the bottom of the screen to display an additional throttle setpoint. However, I'm totally lost on where to even start on this. It looks like I need to refer to the Navball object on screen, which is from the Navball class, but it is called something else in the flight scene?

Another thread on here talked about KSP using a GUI plugin for Unity of some sort, but my search skills fail me and I cant' find that thread.

Anyone have any ideas?

D.

Edited by Diazo
Link to comment
Share on other sites

Does anyone know, or have a good write up, of the numbers FlightInputState expects?

The API documentation only says throttle is from 0 to 1 and I got that to work.

However, trying to get pitch to work is stumping me. I've tried setting pitch to both 1 and 100 and neither setting does anything I can see.

Those were persistent values in fixed update so:


<snip preliminary stuff>
public void FixedUpdate()
{
FlightInputHandler.state.throttle = 0.5f; //sets throttle to half and this works.
FlightInputHandler.state.pitch = 45f; //does nothing, tried 0, 1, 90, 100 and the 45 I just copied pasted in.
}
<snip code in remainder of mod>

Anyone have any ideas?

D.

edit: It never fails, 10 minutes later I find the answer.

It looks like the non-throttle inputs are all axis as opposed to boolean (button) inputs so they always have inputs, where the throttle only has input when the throttle changes.

IE: pitch is from -1 to 1, so when no keys are being pressed, there is still a pitch input of 0. However, throttle is on/off, so when throttle keys are not being pressed (off), there is no throttle input happening.

Therefore I could directly call FlightCtrlState.throttle to set the throttle because there was no input present. However, pitch always has an input of 0 present that overwrites what my code sends.

To get around this, you have to create a FlightCtrlState function that you add your values to, then call "vessel.OnFlyByWire = MyFlightCtrlState" to explicitly tell KSP to overwrite what is already in there (the no-input pitch value of 0) with the input from code.

Bleh, fun times. More details can be found in the 'Vessel.cs' part of the documentation, I was looking in the Flight parts earlier and missed it.

Edited by Diazo
Link to comment
Share on other sites

Is there a "hello world" style tutorial example of a mod out there somewhere that walks a new person through the steps?

I picture something where a new programmer doesn't work with artwork, or mesh modeling or any of that, but just wants to learn how to make a trivial alteration of game behavior - like maybe a window that says "hello world" when you launch a craft - just something really tiny who's only purpose is to prove "yes you have all the pieces you need for mod development installed right, configured correctly, and you did get it to compile and do a thing."

There doesn't seem to be a lot of information at that getting started level. The closest I could find was this thread:

http://forum.kerbalspaceprogram.com/threads/25013-Compilation-of-modding-information-links-for-0-19-20-21-Last-updated-24th-September

But it seems to be spending all its time talking about making parts, which is a bit farther along than I am. I don't even know where the KSP API is downloaded from, or what development environment I'll need installed first.

I have a lot of experience with other languages, but none with C#. I know Java and C++ so it should be simple to pick up. Finding information on C# isn't the problem. Finding information on KSP's modder API and how to get off the ground with it is the problem.

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