Jump to content

Info on how to convert your Plugin to KSP 1.1


Recommended Posts

This post is the product of the findings that modders in the experimental team shared with each others. I won't list them since they may not want to make their involvement in Exp public but I thank each of them. 

First the short version : no pre 1.1 plugin (dll) will work without some change. Most of those change are easy, even trivial. But some are complex, especially if your plugin interacts with KSP user interface. This does not list everything but should help your getting started. Please share your own findings.

Warning

The game has many classes that are not used anymore in 1.1. Your mod could compile fine and generate many errors at runtime (RenderingManager) or worse do nothing since it relies on value that are no updated anymore (Staging). I will list some of those trap in that post but it is likely that there are others. If you find some please share them so I can update the post.

References and Unity 5 changes

The first thing you will have to do is add some references to the new dll in KSP. Most mods will have to include KSPUtil.dll (ConfigNode are now here and a lot of useful extension) & UnityEngine.UI. Some project may also have to add  Assembly-CSharp-firstpass.dll (all the PQS class are now here), Vectrosity.dll (if you used VectorLine. Be aware that the API changed) or you may want KSPAssets.dll if you want to use the new AssetBundles calls (more on that later).

Then Unity 5 also changed some of its API. Mainly some of the Components shortcut are gone. So :
Screen.showCursor => Cursor.visible 
x.rigidbody => x.GetComponent<Rigidbody>()  (for Part you can use part.rb)
x.light => x.GetComponent<Light>()
x.collider => x.GetComponent<Collider>() 

Take note that those call are not free at all (and they ware not before, they just looked simpler) and you should cache them if you can. Arsonide added some methods to help with that :

On 3/5/2016 at 10:21 AM, Arsonide said:

I added some extension methods to KSPUtil for Objects and Components called GetComponentCached that should help you guys improve performance without repeatedly writing component caching properties. It works like this...


private Rigidbody _rigidbody;

// It can infer the type for brevity...if you use it this way, I recommend very explicit names like _rigidbody.
part.GetComponentCached(ref _rigidbody).velocity = Vector3.zero;

// Or you can be more explicit...
part.GetComponentCached<Rigidbody>(ref _rigidbody).velocity = Vector3.zero;

Basically all they do is check if the reference is null, and if it is they run a single GetComponent, and cache the result in the reference. I could have made it not require a reference, but that would have required overriding Monobehaviour, which would have been quite invasive. This way the caches are more obvious as well.

You can use these basically anywhere you'd use GetComponent, and use them as much as you like without feeling as guilty about how much you are destroying performance.

You can find the list of change that are Unity specific in they manual upgrade section: 5.0 and 5.2 

 

KSP API changes

  • The use of the ApplicationLauncher require adding a "using KSP.UI.Screens;"
  • Reference to Staging should be replaced with StageManager (and .lastStage => .LastStage) and will require adding a "using KSP.UI.Screens" 
  • Reference to CMAssignmentDialog should be replaced with KSP.UI.CrewAssignmentDialog
  • The  PopupDialog.SpawnPopupDialog  cal lchanged. Replace 

PopupDialog.SpawnPopupDialog("Title", "Text", "OK", false, HighLogic.Skin); 
with :

PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "Title", "Text", "OK", false, HighLogic.UISkin);

  • SoftJointLim as had its functionality split into SoftJointLim for the actual limit and bounce at the limit and SoftJointLimitSpring for the spring/damper beyond that limit.
  • MapObject.MapObjectType.CELESTIALBODY => MapObject.ObjectType.CelestialBody

 

RenderingManager

That class is still here but should not be used anymore. The object is not present anymore and even adding it manually create problems (corruption of RenderingTexture). So you will have to replace your code. Unfortunately it means that many tutorial are now obsolete.

void Start() // or an other similar mtehod
{
	RenderingManager.AddToPostDrawQueue(3, new Callback(drawGUI));
	RenderingManager.AddToPreDrawQueue(3, new Callback(myPreDrawQueue));
}

void myPreDrawQueue()
{
  // my preDrawQueue code
}

void drawGUI()
{
  // my GUI code
}

Need to be replaced with 

private void OnGUI()
{
    if (Event.current.type == EventType.Repaint || Event.current.isMouse)
    {
        myPreDrawQueue(); // Your current on preDrawQueue code
    }
    drawGUI(); // Your current on postDrawQueue code
}

void myPreDrawQueue()
{
  // my preDrawQueue code
}

void drawGUI()
{
  // my GUI code
}

 

So for most mods it will mean adding OnGUI and calling your current UI code from it.

 

Assetbundles

The new PartTool allow you to build AssetBundle in the Unity editor to load easily in KSP any prefab you created. This let you do some thing that were previously hard or impossible to do. It can be used to create UI with the new UI system more easily (I will do a post on that later), loads Shiruken Particles system and all kind of fun stuff. 

The PartTool will handle al of the packaging work. You only have to create prefabs and affect them to a new bundle. The tool will then generate the XML file that KSP need and package it and your prefab in the AssetBundle file. 

Here is a simple exemple. The AssetLoader has many other static methods to load a lot of prefab at the same time. You will need a reference to KSPAssets.dll

bool myPrefabIsLoaded = false;
Shader myShader;

void Start()
{
      // We load the MyPrefabName prefab in the AssetBundle file <KSP>/GameData/MyMod/MyAssetBundle.ksp
      AssetLoader.LoadAssets(AssetLoaded, AssetLoader.GetAssetDefinitionWithName("MyMod/MyAssetBundle", "MyPrefabName"));
      // WARNING. This is Asynchorous. The prefab is actually loaded in a cooroutine
      // Don't use it before myPrefabIsLoaded is true !
}

// this gets called when the assetisLoaded and is where you need to affect the object to variables.
Void AssetLoaded(AssetLoader.Loader loader)
{
  // You get a object that contains all the object that match your laoding request
	for (int i = 0; i < loader.definitions.Length; i++ )
    {
		UnityEngine.Object o = loader.objects[i];
		if (o == null)
			continue;
	
		if (o.GetType() == typeof(Shader))
			myShader = o as Shader;
    }
    myPrefabIsLoaded = true;
}

 

KSP Module change/improvement

  • ModuleEngine has a new thrustTransformMultipliers array. Before each thrustTransforms of the engine had a thrust of the total engine trust divided by thrustTransforms.count. Now each thrustTransforms has a thrust of total engine * thrustTransformMultipliers.
  • If you deleted maneuver nodes with something like "vessel.patchedConicSolver.RemoveManeuverNode(node);" you should now replace it with "node.RemoveSelf();" instead to avoid some graphic glitch on the map.

 

Link to comment
Share on other sites

and pray tell where's this new fangled parttools?

Quote

ModuleEngine has a new thrustTransformMultipliers array. Before each thrustTransforms of the engine had a thrust of the total engine trust divided by thrustTransforms.count. Now each thrustTransforms has a thrust of total engine * thrustTransformMultipliers.

thrustTransformMultiplier is public variable set in the module config or is it automatically set based on the # of thrustTransforms in the part model?
and each thrustTransform has total engine * multiplier... meaning 3 thrustTransforms * 3 engine thrust * thrustTransformMultiplier[3] = 27 actual thrust??

Edited by nli2work
Link to comment
Share on other sites

Has anyone figured out how to use the new PartTools to build an AssetBundle?  I have it loaded and working Unity but I can't figure out how to take a prefab i've made and make a bundle out of it.

Link to comment
Share on other sites

9 minutes ago, stupid_chris said:

Yes, thats mentioned in the OP.

Aha, I see that part now. I had scanned the post, then searched for "vector3d" and didn't see it before... I should read more carefully.

Link to comment
Share on other sites

52 minutes ago, Agathorn said:

Has anyone figured out how to use the new PartTools to build an AssetBundle?  I have it loaded and working Unity but I can't figure out how to take a prefab i've made and make a bundle out of it.

Ok still working on this but after blindly groping around i finally found something.

1. Select a prefab.

2. Look in the properties panel, and look at the very bottom.  You will see a section named "Asset Labels" and you will see a property AssetBundle.

3. It will say None.  Click that and you can create a new bundle.

4. In the AssetCompiler, click Update All and your new bundle will show up.

 

One thing I can't find is a way to delete one though.

Edited by Agathorn
Link to comment
Share on other sites

For people using RenderManager we will presumably have to manually handle hiding the UI.

There are GameEvents for every circumstance that I know of where the UI should be hidden:

OnShowUI and OnHideUI for Alt+F2

OnGUI*Spawn OnGUI*Despawn for the Space Center complexes, like mission control, R&D, etc... Using these will prevent your window from being drawn above those screens (as far as I know OnGUI elements will be drawn on top of any other type of UI object, using the new or old system).

Link to comment
Share on other sites

Does the change from Unity 4 -> 5 affect the UI code for mods beyond what is mentioned in the OP? I've heard there is quite a difference between 4 and 5 from a UI perspective, is that only for the actual game developers or will I/we need to rewrite the all the code that creates / draws the UI?

Link to comment
Share on other sites

Immediate Mode GUI still exists in Unity 5, so beyond those changes and maybe some minor changes your GUI should still work.  I can't confirm that but that should be the case.

That said IMGUI is slow, and hard to work with, therefore there is definite benefit in diving into the new Unity 5 GUI stuff if you have the desire.  It will let you produce much better UIs with less work.

Link to comment
Share on other sites

34 minutes ago, Agathorn said:

One thing I can't find is a way to delete one though.

You have to set the asset to None in asset bundle down under the preview window. and delete any existing XML of the bundle you want to delete.  then Clear Unused names.

seems like AssetBundles will be a mixed blessing. 

Edited by nli2work
Link to comment
Share on other sites

Just now, nli2work said:

You have to set the asset to None in asset bundle, then Clear Unused names. and delete any existing XML of the bundle you want to delete.

seems like AssetBundles will be a mixed blessing. 

Did that work for you? Because that is what I tried to do but it wouldn't actually go away.

Link to comment
Share on other sites

So does the ability to make an asset bundle mean we'll be able to include our own additional fonts that the stock game doesn't come with?  We couldn't do that before, and it's the reason kOS has to use the wonky system of cutting and pasting character cells from a texture2d into the screen.  If we could just include our own TrueType font file and use that instead, it may clean up a lot of ugly code.  (The reason we didn't draw characters using a proper font before was that we were limited to the fonts that SQUAD bundled, and none of them were monospaced.)

 

Link to comment
Share on other sites

Where does true anomaly appear in the user interface?

I noticed this comment in the change notes:

> * True anomaly is now always in radians.

was listed under the "User Interface" section.  But I am unaware of where within the user interface in the stock game a player is ever shown the true anomaly value.

This matters because in kOS we tend to show the user everything in Degrees if possible, as it's more newbie-friendly even though it's less good from a scientist's point of view, and so we've always returned an orbit's trueanomaly in degrees to scripts.  We noticed that it's in radians now in the KSP API, but to preserve backward compatibility we were just going to convert it to degrees before showing it to the kOS scripts.  But if there's an actual user interface somewhere that shows it to people in radians, and that's the official way the stock game works, then maybe the right thing to do is break backward compatibility with scripts and switch to radians to match what the user sees in the stock game.

 

Link to comment
Share on other sites

40 minutes ago, Agathorn said:

Immediate Mode GUI still exists in Unity 5, so beyond those changes and maybe some minor changes your GUI should still work.  I can't confirm that but that should be the case.

That said IMGUI is slow, and hard to work with, therefore there is definite benefit in diving into the new Unity 5 GUI stuff if you have the desire.  It will let you produce much better UIs with less work.

As much as I hate OnGUI and unity gui scripting.... it's still ages easier than using the new WYSIWYG editor for modders. The problem is that you can make it happen and load your on UI with AssetBundles, but making it interact with your code is a *nightmare*. I believe Sarbian figured a way to do this, but it's not easy. OnGUI remains much easier to work with unfortunately.

12 minutes ago, lextacy said:

What about part mods? Will there need to be code changes for parts?

Parts don't use code :/

Edited by stupid_chris
Link to comment
Share on other sites

17 minutes ago, Steven Mading said:

So does the ability to make an asset bundle mean we'll be able to include our own additional fonts that the stock game doesn't come with?  We couldn't do that before, and it's the reason kOS has to use the wonky system of cutting and pasting character cells from a texture2d into the screen.  If we could just include our own TrueType font file and use that instead, it may clean up a lot of ugly code.  (The reason we didn't draw characters using a proper font before was that we were limited to the fonts that SQUAD bundled, and none of them were monospaced.)

 

If you can make it a Prefab then yes should be doable.  Really it opens up some amazing doors.

 

I"ve got an AssetBundle exported, but can't seem to get it loaded into KSP.  It just keeps erroring saying it can't be found:

AssetLoader: Cannot find bundle definition with name 'TestFlight/AssetBundles/testflight'

 

I notice in Sarbian's original post he mentions the AssetBundle should have an extension of .ksp, but the one created by PartTools has no extension.  Not sure which is correct.  The error doesn't have an extension either so I assume the no extension is correct.

I've copied over both the AssetDatabase and the xml but no joy so far.

1 minute ago, stupid_chris said:

As much as I hate OnGUI and unity gui scripting.... it's still ages easier than using the new WYSIWYG editor for modders. The problem is that you can make it happen and load your on UI with AssetBundles, but making it interact with your code is a *nightmare*. I believe Sarbian figured a way to do this, but it's not easy. OnGUI remains much easier to work with unfortunately.

Parts don't use code :/

That doesn't make any sense.  I mean after all modders in KSP are only one step removed from just a normal Unity developer unless KSP itself is mucking around with things.

Even if it is harder from a code perspective, for me it is most likely worth it to be able to design NICE looking UIs using a proper editor.

Link to comment
Share on other sites

7 minutes ago, Agathorn said:

hat doesn't make any sense.  I mean after all modders in KSP are only one step removed from just a normal Unity developer unless KSP itself is mucking around with things.

Even if it is harder from a code perspective, for me it is most likely worth it to be able to design NICE looking UIs using a proper editor.

Don't think you understood what I meant. Creating UI is easy. Importing it in the game is easy. Interacting through code with this UI is on the verge of the not really possible. From what I got it only works in simple and specific cases, and is still a hell to set up.

Link to comment
Share on other sites

6 minutes ago, stupid_chris said:

Don't think you understood what I meant. Creating UI is easy. Importing it in the game is easy. Interacting through code with this UI is on the verge of the not really possible. From what I got it only works in simple and specific cases, and is still a hell to set up.

Import it into the game is where i'm hung up right now :)

But my point was that i've worked with these same UIs in my own Unity project without difficulty so i'm confused as to why it would be such an issue in KSP unless it has something to do with the KSP side?  Anxious to hear what Sarbian has to say since you said he worked it out.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...