Server Side Functions#
A server side function is code that runs inside the game, on the server. The Python client compiles a lambda or function into one. It has three main uses:
Custom events wait for a condition to become true. The server checks the condition on every update, and sends your script a message when it fires. Polling from your script adds a round trip to every check, and can miss a condition that holds for only a few frames.
Function streams stream the result of a computation over several values. The server reads every value in the same frame, so the values are consistent.
Run-once functions run a sequence of calls in a single frame, from a single call. The same calls made from your script take a round trip each, and the game advances between them.
This event fires when the vehicle’s apoapsis passes 100 km:
event = conn.add_event(lambda: orbit.apoapsis_altitude > 100_000)
with event.condition:
event.wait()
print("Apoapsis passed 100 km")
The server runs once per frame, so it checks the event once per frame. See Timing.
Captured Values#
The client splits a function by what each part depends on. A property or method of a remote object becomes part of the function, and the server reads it on every evaluation. A part that uses only values from your script, such as a captured variable, is evaluated once, when the function is compiled:
threshold = 50_000
event = conn.add_event(lambda: vehicle.orbit.apoapsis_altitude > threshold * 2)
The client computes threshold * 2 when it creates the event, so the server compares the
apoapsis with the constant 100000. The chain vehicle.orbit.apoapsis_altitude is part of the
function, so it follows the vehicle’s current orbit.
Computed Streams#
A stream of a function streams its computed value. This streams the vehicle’s thrust to weight ratio, from its thrust and mass read in the same frame:
gravity = vehicle.orbit.body.surface_gravity
ratio = conn.add_stream(lambda: vehicle.thrust / (vehicle.mass * gravity))
print(f"Thrust to weight ratio {ratio():.2f}")
A function can produce a collection. This streams the thrust of each of the vehicle’s engines:
engines = [part.engine for part in vehicle.parts if part.engine is not None]
thrusts = conn.add_stream(lambda: [engine.thrust for engine in engines])
print(f"Engine thrusts {thrusts()}")
Here engines is a captured variable, so the list of engines is fixed when the function is
compiled. The server reads only their thrusts.
Collections and Statements#
Python’s collection operations, such as any, all, sum and comprehensions, compile to
the server’s collection operations. This event fires when an active engine runs out of
propellant, such as the Rocket’s sea level engine about a minute after it lifts off:
event = conn.add_event(
lambda: any(engine.active and not engine.has_propellant for engine in engines)
)
with event.condition:
event.wait()
print("An engine has run out of propellant")
A function can contain statements, loops and local variables before its return. This streams the fraction of the vehicle’s propellant that is left:
def propellant_fraction():
amount = 0.0
capacity = 0.0
for resource in vehicle.resources:
amount += resource.amount
capacity += resource.max
return amount / capacity
fraction = conn.add_stream(propellant_fraction)
print(f"{fraction():.1%} of the propellant is left")
Run-Once Functions#
A function can also change the game, by setting properties and calling methods. conn.run
runs it once, with every step in the same frame. This points a vehicle on the launch pad
straight up and lights its engines:
def lift_off():
vehicle.auto_pilot.target_pitch_and_heading(90, 90)
vehicle.auto_pilot.engage()
vehicle.control.throttle = 1
vehicle.control.engine_on = True
conn.run(lift_off)
Note
An event or stream runs its function on every update, side effects included. Keep event and stream functions free of side effects.
Procedures That Wait#
A function runs within a single frame, so it cannot call a procedure that waits for a later frame. The call raises an error, and the effects the procedure made before it waited still happen. These procedures wait:
KSA.WarpToandKSA.LaunchVehicle.Vehicle.AddBurnandAutoPilot.Wait.Control.ActivateNextSequence.The part module setters and actions, such as
Engine.Active,Decoupler.DecoupleandParachute.Deploy.
Call these from your script, between functions.
More#
The kRPC server side functions guide covers the rest of what a function can do: arguments, state kept between updates, strings, exceptions, printing, and the expression API that clients without a compiler use.