Jump to content

Adding a Slope Option to KerbNet


Recommended Posts

I'd like to add a Slope mode to KerbNet, so that a vessel can see Ore, Altitude, Biomes, and Slope.

This is my first mod, but I think what I want to do is pretty simple. It'd just be the altitude mode, but with slope instead.

It looks like I want a PartModule, and I need to subclass KerbNetMode (https://kerbalspaceprogram.com/api/class_kerb_net_1_1_kerb_net_mode.html).

Looks like I want to attach this to existing parts, so looks like I need to use ModuleManager.

I've read through the basic start guide. Any advice on what to research next?

Link to comment
Share on other sites

KerbNetMode is not a PartModule, it's just a class that serves as the base for each different mode to determine how the map is actually drawn.

What you would need is to use MM to add your new slope mode to whichever KerbNet part you want to have it.

So, for example, in the probeCoreHex part config you would need to use MM to add to the DISPLAY_MODES node:


	MODULE
	{
		name = ModuleKerbNetAccess
		MinimumFoV = 17
		MaximumFoV = 63
		AnomalyDetection = 0.12
		DISPLAY_MODES
		{
			Mode = Terrain,#autoLOC_438839 //#autoLOC_438839 = Terrain
			Mode = Slope,Slope //the second word is the translated term used for the actual display
		}
	}

 

To generate a slope map you would need to make a new class that inherits KerbNetMode and overrides the relevant methods:

CustomPass - this looks like where you would take the terrain data and convert it slope (I'm pretty sure that all KerbNet modes generate terrain data); you would have to convert pixel color to an altitude value, then calculate slope from there, or something along those lines.

LocalCoordinateInfo - this is where you would get slope info for the center or cursor point to print in the KerbNet window.

 

The problem here is that the terrain altitude data is interpolated, only every x pixel on every y row (2 or 4 pixels probably) is actually calculated, so the default terrain map is not very accurate. I'm also not sure of how you would figure out what the min and max altitude is for a given map (you would need this to convert pixel color back to altitude).

I think you can disable the stock terrain data generation by setting the "doTerrainContourPass" field for you KerbNetMode class to false. Then you would have to calculate the terrain altitude data yourself in the CustomPass method, convert terrain data to slope, convert slope data to color and apply that to the map texture. :D

 

Getting terrain data is pretty slow, even for the relatively small KerbNet map (that's why the stock modes interpolate the data). So you would have to balance the trade off of slow map generation with the accuracy of the slope calculation.

The slope calculation itself can also be a bit math heavy, so you have to decide how accurate you want that part to be, too.

 

SCANsat uses two methods for calculating slope, one for drawing the map, which isn't very accurate, but produces decent results: https://github.com/S-C-A-N/SCANsat/blob/release/SCANsat/SCAN_Map/SCANmap.cs#L908-L939 (this one is probably indecipherable without knowing how the map code works overall :kiss:).

And the other for finding the slope at a highly localized locations, like the current vessel location or when the mouse is over a pixel on the map: https://github.com/S-C-A-N/SCANsat/blob/release/SCANsat/SCANutil.cs#L699-L753 (this one calculates the slope by comparing the altitude at the 8 points surrounding the location).

 

Link to comment
Share on other sites

7 hours ago, Wcmille said:

How does the game know that the word "Slope" is associated with this new slope class? Does it use reflection to do that?

Any class that implements KerbNetMode is loaded by the game. The "name" member of the class is the one that is used for the mode name.

Link to comment
Share on other sites

@sarbian and @DMagic -- thanks for your help!

Here's what I have so far. I'm trying just to see if I can get the code to register inside the game before I go farther. Trying to make my slope KerbNet so that it just displays a red screen. Once I've got it installed correctly, I'll get to work on making the display correct.

So far, this doesn't seem to work.

Here's my module manager file (all of it):

@PART[probeStackSmall]
{
	@MODULE[ModuleKerbNetAccess]
	{
		MinimumFoV = 9
		MaximumFoV = 81
		AnomalyDetection = 0.24
		DISPLAY_MODES
		{
			Mode = Biome,#autoLOC_438890 //#autoLOC_438890 = Biome
			Mode = Terrain,#autoLOC_438839 //#autoLOC_438839 = Terrain
			Mode = Slope, Slope
		}
	}
}

Here's my code file (there's only this file in the assembly):

using KerbNet;
using UnityEngine;

namespace wcmille
{
    public class Slope : KerbNetMode
    {
        public override void OnInit()
        {
            name = "Slope";
            displayName = "Slope";
        }

        public override void CustomPass(Texture2D tex)
        {
            base.CustomPass(tex);
            var pixels = tex.GetPixels();
            for(int i = 0; i < pixels.Length; ++i)
            { 
                pixels[i] = new Color(255,0,0);
            }
            tex.SetPixels(pixels);
        }
    }
}

 

Link to comment
Share on other sites

Thanks for that, @sarbian . When I install the mod, log messages in the Init get called, but the log get's continuously spammed with this message:

"[EXC 14:26:09.295] MissingMethodException: Method not found: 'KeyBinding.GetKey'."

If I remove my mod or I replace the code with the tutorial code, I don't get this message.

I'm wondering if I didn't override the class enough or if I have some missing references?

Link to comment
Share on other sites

14 minutes ago, Wcmille said:

Thanks for that, @sarbian . When I install the mod, log messages in the Init get called, but the log get's continuously spammed with this message:

"[EXC 14:26:09.295] MissingMethodException: Method not found: 'KeyBinding.GetKey'."

If I remove my mod or I replace the code with the tutorial code, I don't get this message.

I'm wondering if I didn't override the class enough or if I have some missing references?

Are you sure you compiled your DLL with the same KSP version that you run it with ?

Link to comment
Share on other sites

4 minutes ago, sarbian said:

Are you sure you compiled your DLL with the same KSP version that you run it with ?

From an internet search, it sounds like I must not be. That puzzles me. I have only one instance of KSP on my machine. I am referencing these 4 assemblies:

  • Assembly-CSharp
  • Assembly-CSharp-firstpass
  • UnityEngine
  • UnityEngine.UI

These come from: <PATH>\Kerbal Space Program\KSP_x64_Data\Managed\<Assembly>

I am running in 64-bit mode.

I think mscorlib is getting implicitly referenced by the compiler (VS Community 2017), but that could be different.

I wonder how else I might try to troubleshoot this?

Link to comment
Share on other sites

Stupid question, but I don't see it elsewhere in the thread. 

The MS C# API defaults to the current version of C#, which is 4.7.1 (iirc). You have to make sure that whatever functions you're using still existed back in the days of C# 3.5, which KSP is written in. 

Same thing with the KSP API, which is updated to the latest version. If you're working with an older version of KSP, things might have changed in the API. 

The compiler must be set to compile for C# v.3.5, as it defaults to the latest one. 

The last thing is to check your using statements. 

Good luck!

Link to comment
Share on other sites

I think those are all correct. The target framework for the assembly is .NET 3..5. Can't see why using statements would create a run-time problem if it resolves unambiguously.

If anyone is so inclined, I'd be very thankful to see if this works/runs for anyone else. here's the dropbox link:
https://www.dropbox.com/s/e8ba6mhf52f7lzp/wcmille.zip?dl=0

The test is to make a sandbox game, put a probe core on the launch pad, and open up KerbNet. You'll need to hand-deploy the ModuleManager file to your mods folder, and your game path won't be the same as the one I deploy to in my post-build step.

Link to comment
Share on other sites

I deleted the bin and obj folders to isolate that out.

Here are some other things I have tried; this did not seem to help:

  • I have run in 32 and 64 bit mode.
  • I have removed all my mods, except ModuleManager
  • I tried adding the System namespace

Would anyone be willing to try compiling my project on their machine to see if the error reproduces?

Link to comment
Share on other sites

There : https://www.dropbox.com/s/7wim9oncen0d56b/wcmille.zip?dl=0

I added the system references to make sure it uses the one from KSP, changes the references to remove the hint path and switch to a user path (wcmille.csproj.user , I prefer this way of setting reference path), added some more code so the displayed strings are the right one and fixed the MM patch since a @ was missing.

Link to comment
Share on other sites

4 hours ago, sarbian said:

There : https://www.dropbox.com/s/7wim9oncen0d56b/wcmille.zip?dl=0

I added the system references to make sure it uses the one from KSP, changes the references to remove the hint path and switch to a user path (wcmille.csproj.user , I prefer this way of setting reference path), added some more code so the displayed strings are the right one and fixed the MM patch since a @ was missing.

Not seeing the change in the .cfg file in the drop box. Is that what you meant by the MM patch?

Link to comment
Share on other sites

20 minutes ago, Wcmille said:

Not seeing the change in the .cfg file in the drop box. Is that what you meant by the MM patch?

Err sorry, I edited the file in my ksp install and did not zip the right one

@PART[probeStackSmall]
{
	@MODULE[ModuleKerbNetAccess]
	{
		MinimumFoV = 9
		MaximumFoV = 81
		AnomalyDetection = 0.24
		@DISPLAY_MODES
		{
			Mode = Biome,#autoLOC_438890 //#autoLOC_438890 = Biome
			Mode = Terrain,#autoLOC_438839 //#autoLOC_438839 = Terrain
			Mode = Slope,Slope
		}

	}
}

 

Link to comment
Share on other sites

6 minutes ago, sarbian said:

Err sorry, I edited the file in my ksp install and did not zip the right one


@PART[probeStackSmall]
{
	@MODULE[ModuleKerbNetAccess]
	{
		MinimumFoV = 9
		MaximumFoV = 81
		AnomalyDetection = 0.24
		@DISPLAY_MODES
		{
			Mode = Biome,#autoLOC_438890 //#autoLOC_438890 = Biome
			Mode = Terrain,#autoLOC_438839 //#autoLOC_438839 = Terrain
			Mode = Slope,Slope
		}

	}
}

 

Thanks for that. Looks like that did it.

Link to comment
Share on other sites

Here's an image of the mod. At present, its showing contours of the surface. I find something like this to be much more helpful than altitude, because I'm looking for areas on the ground that are going to be really flat.

89E05172EDD1D0D8F2F3FEE96D810E19433FBBA1

Link to comment
Share on other sites

@sarbian -- I never bothered to look at the log once I got the mod to work. The mod works, but its spamming the log. I just tried running your code from DropBox, and that's spamming the log with the same MissingMethodException. Does your dropbox version spam the log on your machine? What version of Visual Studio are you building with?

Link to comment
Share on other sites

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