Adding or extending builtin modules

Standard binding

A builtin module usually looks like this:

[KSModule("ksp::my", Description = "Description of the module"
)]
public class MyModule {
    [KSFunction(Description = "Description of the function")]
    public static double SomeCalculation(double param1, double param2) {
        return param1 + param2;
    }

    [KSFunction(Description = "Description of the function")]
    public static double CreateMyType(long param1, string param2) {
        return new MyType(param1, param2);
    }
    
    
    [KSClass("MyType", Description = "Description of the type")
    public class MyType {
        private readonly long param1;
        private readonly string param2;
        
        internal MyType(long param1, string param2) {
            this.param1 = param1;
            this.param2 = param2;
        }
        
        [KSField]
        public long FirstParam => param1;
        
        [KSField]
        public string SecondParam => param2;
        
        [KSMethod]
        public double AddSomething(long toAdd) {
            return param1 + toAdd;
        }
    }
}

Additionally it has to be added to the KontrolSystemKSPRegistry using

registry.RegisterModule(BindingGenerator.BindModule(typeof(MyModule)));

Then

  • The new module will have the name ksp::my

  • It will contain two functions

    • fn some_calculation(param1 : float, param2 : float) -> float

    • fn create_my_type(param1 : int, param2 : string) -> ksp::my::MyType

  • It will also contain a type MyType with

    • Property .first_param : float

    • Property .second_param : string

    • Method .add_something(to_add : string)

  • The module class MyModule can become very big quickly, that is wy in most cases a partial class is used.

Notable things:

  • Names will generally be converted from CamelCase to snake_case

  • TO2 int is a C# long (using a C# int will not work)

  • TO2 float is a C# double (using a C# float will not work)

  • TO2 has no new operator or statement. I.e. to create an instance of MyType one has to provide a function returning it.

Direct binding

Existing types can be bound directly, the Vector3Binding.cs is a good example covering all the cases.

Be aware that the type mapping has to be done manually here and might lead to runtime exception if done incorrectly (i.e. standard binding is much easier and safer).

Direct binding should only be used if performance if an issue (i.e. the type might be used a lot) or operator binding is desired.