Skip to content

Using the game

Obj is a game object, held by Oxidizer and released when the Obj is dropped. You reach members by name:

use oxidizer_api::Obj;

// Static members: the type name, assembly-qualified when it isn't found otherwise ("Namespace.Type, Assembly").
let v = Obj::static_get("KSA.Program, KSA", "ControlledVehicle");
let t = Obj::static_call("KSA.Universe, KSA", "GetElapsedSeconds", &[]).f64().unwrap_or(0.0);
Obj::static_call("KSA.Universe, KSA", "SetSimulationSpeed", &[&Obj::from(5.0), &Obj::from(true)]);
Obj::static_set("KSA.SimSpeed, KSA", "MaxSpeed", &Obj::from(100.0));

// Instance members.
if !v.is_null() {
    let id = v.get("Id").to_string();
    let speed = v.call("GetSurfaceSpeed", &[]).f64();
    v.set("ShowGroundTrack", &Obj::from(true));
    let radius = v.get("Parent").get("MeanRadius").f64();
}
Method Does
Obj::static_get(type, member) / Obj::static_set(type, member, &value) Static property or field.
Obj::static_call(type, method, &[args]) Static method.
obj.get(member) / obj.set(member, &value) Property or field of an object.
obj.call(method, &[args]) Method of an object.
obj.f64(), obj.i64() The number (also bools and enums), or None.
obj.to_string() The object's ToString() (also through {} in format!).
obj.is_null() Whether it is null.
obj.len(), obj.index(i) Arrays and collections.
Obj::from(x) A game value from f64, i64, bool or &str, for arguments and set.

Arguments are converted to the parameter types (a number to float, int or an enum, and so on). When a method has overloads, name the one you mean with its parameter types: "SetSimulationSpeed(double, bool)"; without them, Oxidizer picks the overload that fits the arguments, and if it can't tell, the error lists them.

By-name calls find members when they run, so a mod keeps working across game updates as long as the names exist. For names with autocomplete and compile-time checks, see typed bindings.

Wrapping it up

Mods usually put the calls they need behind small typed functions, so the rest of the code reads like Rust:

pub struct Vehicle(Obj);

impl Vehicle {
    pub fn controlled() -> Option<Vehicle> {
        let v = Obj::static_get("KSA.Program, KSA", "ControlledVehicle");
        (!v.is_null()).then_some(Vehicle(v))
    }
    pub fn altitude(&self) -> f64 {
        self.0.call("GetBarometricAltitude", &[]).f64().unwrap_or(f64::NAN)
    }
}

Flight Panel's game.rs does this for a whole flight data panel.

Finding names

  • A .NET decompiler such as ILSpy on the game folder's KSA.dll.
  • The typed bindings file, which lists every public member with its types.
  • Oxidizer's Rhai definitions, a searchable list with types.