Jump to content

Protip for new modders - C# isn't the only language you can use!


longbyte1

Recommended Posts

I'd just like to tell any new modders that C# isn't your only choice. Although it is indeed a powerful language that is familiar to Java veterans, you may have had a background with another family or group of languages. Some may look simpler or prettier for you. Basically any language that conforms to CLI specifications can be used to make KSP mods, as long as a toolchain exists that can be configured correctly to work with Unity's .NET/Mono environment. To show what each language looks like, I've posted a translated version of my very simple mod, [thread=81957]FloorIt[/thread]. I cannot guarantee that the examples will work.

Here is a list of commonly used CLI languages that may be of interest to you:

  • Boo - Very similar to Python in syntax, but it's more focused towards .NET and C#-like typing. If you're familiar with Python, I recommend you use this language. SharpDevelop supports this language.


[COLOR=#008000][B]namespace[/B][/COLOR] FloorIt


[COLOR=#008000][B]import[/B][/COLOR] System
[COLOR=#008000][B]import[/B][/COLOR] UnityEngine
[COLOR=#008000][B]import[/B][/COLOR] KSP

[[COLOR=#191970]KSPAddon[/COLOR](KSPAddon.Startup.Flight, [COLOR=#000000][B]false[/B][/COLOR])]
[COLOR=#0000ff][B]public[/B][/COLOR] [COLOR=#0000ff][B]class[/B][/COLOR] [COLOR=#191970]FloorIt[/COLOR](MonoBehaviour):

[COLOR=#0000ff][B]public[/B][/COLOR] [COLOR=#0000ff][B]def[/B][/COLOR] [COLOR=#191970]Start[/COLOR]():
[COLOR=#800080]print[/COLOR]([COLOR=#0000ff]'FloorIt enabled.\nPress Z to turn the throttle up to 100%.'[/COLOR])


[COLOR=#0000ff][B]private[/B][/COLOR] [COLOR=#0000ff][B]def[/B][/COLOR] [COLOR=#191970]Update[/COLOR]():
[COLOR=#0000ff][B]if[/B][/COLOR] Input.[COLOR=#191970]GetKeyDown[/COLOR](KeyCode.Z):
FlightInputHandler.state.mainThrottle = [COLOR=#00008b]1[/COLOR]

  • Visual Basic - Supported by Microsoft, this language has a very strong/mature community. Very few special characters are used. This was actually the first programming language that I used. If you aren't really that into programming, I suggest you play around with VB before you delve into a more complex language like C#.


[COLOR=#0000ff]Imports[/COLOR] UnityEngine
[COLOR=#0000ff]Imports[/COLOR] KSP

[COLOR=#0000ff]Namespace[/COLOR] FloorIt

<KSPAddon(KSPAddon.Startup.Flight, [COLOR=#0000ff]False[/COLOR])> _
[COLOR=#0000ff]Public[/COLOR] [COLOR=#0000ff]Class[/COLOR] FloorIt
[COLOR=#0000ff]Inherits[/COLOR] MonoBehaviour
[COLOR=#0000ff]Public[/COLOR] [COLOR=#0000ff]Sub[/COLOR] Start()
print("FloorIt enabled." & vbLf & "Press Z to turn the throttle up to 100%.")
[COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Sub[/COLOR]

[COLOR=#0000ff]Private[/COLOR] [COLOR=#0000ff]Sub[/COLOR] Update()
[COLOR=#0000ff]If[/COLOR] Input.GetKeyDown(KeyCode.Z) [COLOR=#0000ff]Then[/COLOR]
FlightInputHandler.state.mainThrottle = 1
[COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]If[/COLOR]
[COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Sub[/COLOR]

[COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Class[/COLOR]
[COLOR=#0000ff]End[/COLOR] [COLOR=#0000ff]Namespace[/COLOR]
[COLOR=#0000ff]Imports[/COLOR] System

  • IronPython - Unlike Boo, IronPython is more faithful to Python in its weak typing. Unless you really really really want to keep Python's good old syntax and compatibility with your existing Python code, just use Boo.
  • C++/CLI - This is the most powerful language and perhaps fastest of all CLI languages. This is not for the faint of heart. C++ veterans may find the syntax familiar, but additional reading is mandatory. I have never used C++/CLI, and I don't know if anyone's successfully made a Unity plugin with it. But if you manage to, you could get some performance boosts.
  • C# - As said before, it's like Java and C++ combined.
  • Native - You can create a native DLL file and interface it with C# using P/Invoke. This will only work with a single platform, but it will give you a significant performance boost if made correctly. I have never done this before, nor have I seen anyone do it apart from documentation and tutorials. Maybe the next FAR will do this, who knows?
  • UnityScript - Similar syntax to JavaScript, but it is more object-oriented. Use MonoDevelop as an IDE if you want to compile to a DLL. C# is slightly faster than UnityScript, though.

I'm surprised that these really are the only popular languages, I thought there were more. But anyway, that is the end of my PSA.

Edited by longbyte1
Link to comment
Share on other sites

I could only find lua interpreters that are embedded in .net; Not good for performance :(

I could also find no compiler to any language that isn't statically typed, so I don't think vanilla lua (or anything) can be found.

IronPython requires DLR, that I think isn't supported with Unity.

Link to comment
Share on other sites

Is it possible to use straight up Java (without using J#)? IKVM.NET would probably work but I wonder what the performance cost is? I think IKVM basically has a java runtime inside the .net runtime.

Link to comment
Share on other sites

Writes a list of Languages to code Unity mods with but doesn't mention UnityScript.

But yes, C# is the popular language for KSP modding and rightfully so, imho.

C++/CLI - This is the most powerful language and perhaps fastest of all CLI languages.

What makes you think it is so much faster? It makes interop with native code very easy and "direct", but otherwise the generated IL is pretty much the same as C# (At least telling from the disassembly of my mod). But using native stuff seems to also give you the same platform dependency drawback as using pure native code.

Also why those focus on performance? 90% of all mods don't care about perf anyway (kinda the opposite. Had quite a few cases of infinite exception spams, what regularly freezes the game for a few ms to write the log to the disk). And even if they do, they usually should identify that bottleneck and replace it with better scaling code. If someone wants to start a new mod, choose a language you are familiar with and can get help. That's usually C#.

Link to comment
Share on other sites

Oh boy, where to start.

Caveat #1. If you are not using C#, Boo, or unityscript (and compiling using unity/mono), you will have to use visual studio or whatever other compiler you use. As far as I am aware, cross compatibility can and probably will be an issue as most of those dlls won't be using the mono CLR.

Caveat #2. Only scripts compiled by unity can be monobehaviors, so no attaching a script to a gameobject without it being either C#, Boo, or US (this may only be in editor, but I'm pretty sure it can't be done period).

Link to comment
Share on other sites

Oh boy, where to start.

Caveat #1. If you are not using C#, Boo, or unityscript (and compiling using unity/mono), you will have to use visual studio or whatever other compiler you use. As far as I am aware, cross compatibility can and probably will be an issue as most of those dlls won't be using the mono CLR.

Caveat #2. Only scripts compiled by unity can be monobehaviors, so no attaching a script to a gameobject without it being either C#, Boo, or US (this may only be in editor, but I'm pretty sure it can't be done period).

Both isn't correct. Mono is mostly compatible with .NET bytecode (since thats what it was supposed to be). The problem is that Unity uses a very outdated cut down version of the .NET class library. Yes you have to use .net 3.5, can't use a few types and should probably use an external tool to target a unity framework.

Same for #2... you only need the correct references. And any reasonable KSP mod will include references to unityengine and ksp's Assembly-CSharp, so not a problem at all.

@philotical: That's not real JS but their UnityScript.

Link to comment
Share on other sites

What makes you think it is so much faster? It makes interop with native code very easy and "direct", but otherwise the generated IL is pretty much the same as C# (At least telling from the disassembly of my mod). But using native stuff seems to also give you the same platform dependency drawback as using pure native code.

Also why those focus on performance? 90% of all mods don't care about perf anyway (kinda the opposite. Had quite a few cases of infinite exception spams, what regularly freezes the game for a few ms to write the log to the disk). And even if they do, they usually should identify that bottleneck and replace it with better scaling code. If someone wants to start a new mod, choose a language you are familiar with and can get help. That's usually C#.

Hypothetically speaking, C++/CLI, if used correctly, is more flexible in memory management. Sure, you can use the garbage collector, but you don't have to. But you are correct; usually, performance doesn't matter. Still, mods like FAR need as much performance as possible to keep framerates up.

Link to comment
Share on other sites

Hypothetically speaking, C++/CLI, if used correctly, is more flexible in memory management. Sure, you can use the garbage collector, but you don't have to.

It isn't, since its just cil byte code. All objects have to go on the heap and thus have to be garbage collected. And this is what my mods disassembly looks like. It could only use the stack for objects that are created and only used within the current method at all, but i would hope the .net JIT would make such an optimization anyway. The only advantage that C++/CLI seems to have in terms of memory management is its deterministic object destruction, but that is nothing but wrapper around .Net commonly used IDisposable. GC has to do the cleanup nonetheless.

Link to comment
Share on other sites

C# generally outperforms C++/CLI. I'm also not convinced P/Invoke is going to be faster. Remember, the CLR revolves around C#, even if it is built to be widely compatible.

There's a big reason to use C# that has nothing to do with language features: It's what KSP uses. It's what the vast majority of mods use. Everything you're going to interface with was designed with C# in mind (even if Unity is bad at it). All the snippets of useful code you'll find are in C#. If you're interested in skilled modders peeking at your code and giving you advice or pull requests, you'll want C#. I do think C# has some advantages from a technical standpoint, but my point here is that you should not use a different language unless you have a substantial overriding reason to. "I don't know C#" isn't a strong enough reason, in my opinion; it's not an unusual or difficult language. There might be a particular language feature you need, but those situations are very rare.

Link to comment
Share on other sites

Both isn't correct. Mono is mostly compatible with .NET bytecode (since thats what it was supposed to be). The problem is that Unity uses a very outdated cut down version of the .NET class library. Yes you have to use .net 3.5, can't use a few types and should probably use an external tool to target a unity framework.

A task not for the faint of heart and mostly for people who either are too pigheaded to pick up a new language or those doing it for the ****s and giggles.

Same for #2... you only need the correct references. And any reasonable KSP mod will include references to unityengine and ksp's Assembly-CSharp, so not a problem at all.

Referencing unityengine is one thing, but you can actually get update functions to work without black magic?

Link to comment
Share on other sites

  • 3 weeks later...

I've been messing around and trying to use Visual Basic to make a mod. (I know, I know -- I should use C# but I've been using VB for many years and I'm too lazy to switch). It took some fiddling and there was almost no discussion on the forums about how to do it, so I thought I would share my experience.

I started by trying to make a standard VB.NET class library using this mod tutorial which was designed for C# and using a code converter to change the sample code from C# to VB.

http://wiki.kerbalspaceprogram.com/wiki/Creating_your_first_module

When I loaded KSP, I found the following in the output.log. ("Thingamajig" is the name of my class)

AssemblyLoader: Exception loading 'Thingamajig': 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 :0

at AssemblyLoader.LoadAssemblies () [0x00000] in :0

Additional information about this exception:

System.TypeLoadException: Could not load type 'Thingamajig.My.MyProject' from assembly 'Thingamajig, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

System.TypeLoadException: Could not load type 'Thingamajig.My.MyProject+ThreadSafeObjectProvider`1[T]' from assembly 'Thingamajig, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

System.TypeLoadException: Could not load type 'MyWebServices' from assembly 'Thingamajig, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

System.TypeLoadException: Could not load type 'System.Configuration.ApplicationSettingsBase' from assembly 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.

File name: 'Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

I did some research and then asked for help on StackExchange

http://stackoverflow.com/questions/24412765/c-sharp-app-cant-find-types-from-a-vb-class-library/24413019#24413019

Basically what is happening is KSP, being written in C#, does not include the classes that Visual Studio was automatically putting references to in my library. I may not be describing that completely accurately, but this is the gist of it. These include (there may be more, depending on the mod you write):

My.MyProject

MyWebServices

System.Configuration.ApplicationSettingsBase

Microsoft.VisualBasic

So the solution is to write the mod in VB using Visual Studio, but compile it manually. The command line options prevent the inclusion of the VB classes that KSP (and/or the Unity engine) do not understand. Here is the command line that worked for me:

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Vbc.exe /sdkpath:C:\KSP-Dev\KSP_Data\Managed /noconfig /verbose /novbruntimeref /imports:System,System.Reflection,System.Collections,System.Collections.Generic /nowarn:42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 /optionstrict+ /rootnamespace:Thingamajig /define:"_MyType=\"Empty\"" /reference:C:\KSP-Dev\KSP_Data\Managed\UnityEngine.dll,C:\KSP-Dev\KSP_Data\Managed\Assembly-CSharp.dll /target:library /out:"C:\KSP-Dev\GameData\Timbo\Thingamajig\Thingamajig.dll" "C:\Users\Tim\Documents\Visual Studio 2012\Projects\Thingamajig\Thingamajig\*.vb"

To make it easier, I converted this to a batch file (ahhhh, good old batch files. I'm pleased to find a use for you after all these years...). Then I can copy the batch file and change the variables at the top for the particular mod I am working on. If the mod includes parts, the batch file can be configured to copy them to the appropriate directory too, or just do it manually.

@echo off

set SOURCE="C:\Users\Tim\Documents\Visual Studio 2012\Projects\Thingamajig\Thingamajig\*.vb"

set DEST="C:\KSP-Dev\GameData\Timbo\Thingamajig\Thingamajig.dll"

set LIBS=C:\KSP-Dev\KSP_Data\Managed\UnityEngine.dll,C:\KSP-Dev\KSP_Data\Managed\Assembly-CSharp.dll

set SDK="C:\KSP-Dev\KSP_Data\Managed"

set NAMESPACE="Thingamajig"

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Vbc.exe /sdkpath:%SDK% /noconfig /verbose /novbruntimeref /imports:System,System.Reflection,System.Collections,System.Collections.Generic /nowarn:42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 /optionstrict+ /rootnamespace:%NAMESPACE% /define:"_MyType=\"Empty\"" /reference:%LIBS% /target:library /out:%DEST% %SOURCE%

pause

I hope this helps anyone wanting to write mods in VB.NET. But.... you (and I) really ought to just switch to C#

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