-
Notifications
You must be signed in to change notification settings - Fork 32
TestFlight API Reference Documentation
This page documents the various pieces of the TestFlight API and Reflection Interface. Due to the fact that the Reflection Interface is simply a wrapper around the core API, both are documented here at once, with the minor differences between the two being called out where appropriate.
The ITestFlightCore Interface is the heart of the system. The Core PartModule on the Part is the module which coordinates and manages all the rest of the TestFlight modules and systems on the Part. All pertinent data to the system is stored or managed here, and thus if you wish to query or manipulate the system from the outside, this is where you need to go.
No other PartModule should ever implement this Interface on their own or else the entire system will break. Please, just don't do it. Let TestFlight implement the Interface, and your modules use it as you need. To be clear, when I say Implement I mean in the technical, Language sense (https://msdn.microsoft.com/en-ca/library/aa664590%28v=vs.71%29.aspx). I obviously don't mean use as you are intended to use the Core. Just don't go Implementing the ITestFlightCore Interface in your own PartModule, or else the TestFlight system may latch on to your implementation rather than the proper one.
TestFlightInterface is a Static class that essentially wraps calls to ITestFlightCore and makes that underlying API available through System.Reflection
. Due to the complexity of the API not all of the Core API can be exposed properly to Reflection, but I have endeavored to make as much of it accessible as possible.
This Interface should be Implemented by any PartModule that wishes to work as a FlightDataRecorder in the TestFlight system. Only one FlightDataRecorder PartModule should be attached to any given part.
This Interface should be Implemented by any PartModule that wishes to provided a method of reliability calculation to the TestFlight system. There should only ever be one core Reliability module on a part, and that core module is the one responsible for calculating the Base Failure Rate
as well as being responsible for determining if a failure has occurred at any given time, and triggering random failure. However additional Reliability modules can be attached to a part, so long as those additional modules only apply modifiers. TODO need to add more details on this.
This Interface is the one that will most commonly be used by modules looking to extend the system. Implement this Interface on a PartModule to provide a distinct method of failure for the part, for example making it explode, or causing a resource leak. Each Failure module attached to a part adds that module's failure as a possible failure option to the part, and there can be any number of Failure modules on a part.
- MTBF: The Mean Time Between Failure for a given part. This gives an indication of approximately how long the part should last between failures occurring, but is not an exact indication of time until failure. A part can fail before, even long before MTBF, or fail after. With stock TestFlight settings, a part is roughly 50% likely to survive until its MTBF. MTBF is tracked internally in seconds and is equivalent to 1/Failure Rate.
- Failure Rate: A failure rate is the underlying amount of failure occurrences in a sample population. It is not a probability of failure, but rather a rate of failure. IE given a sample population of identical parts, at what rate of time will they break down. Failure rate is in seconds and is equivalent to 1/MTBF.
- Base Failure Rate: This is the standard failure rate of a part, given no external influence. It is determined at the inception of a new instance part based on the flight data available from all previous flights of the same part and does not change over the duration of a part instance's lifetime. With each flight, the recorded data will reduce the Base Failure Rate of the part for the next flight.
- MomentaryFailureRate: This is the moment to moment, or dynamic, failure rate of the part. This is calculated from the part's Base Failure Rate and takes into account any operating conditions that may make the part more likely to fail than normal. There can be multiple Momentary Failure Rates all being tracked at once internally, each assigned to a trigger. The GUI will always show the worst possible Momentary Failure Rate to the player.
- MomentaryFailureModifier: The Momentary Failure Rate must always be tied to the Base Failure Rate. Therefore instead of setting a Momentary Failure Rate directly, plugins set a Momentary Failure Modifier for their desired trigger. This modifier is then combined with any other plugins also working on the same trigger and then a final Momentary Failure Rate is computed.
- Trigger: Internally all Momentary Failure Rates & Modifiers are tracked per PartModule and per Trigger. The trigger is simply a string, case-insensitive, that identifies the condition that is tied to the reason for the momentary modifier. This allows multiple plugins to cooperate and work off the same trigger if they desire to do so.
- Scope: To provide an added level of complexity and game play, all TestFlight operations work on what is known as a Part's Scope. Essentially the Scope is a combination of the current body of influence and the science situation, condensed down to one of three possibilities. _atmosphere, _space, or deep_space. All flight data for a part is stored per scope, and failure rate is calculated per scope. The only thing that transcends scope is operating time
- Operating Time: Simply a measure of the amount of time, in seconds, that a part has been operational since its last failure was repaired. It is this time that is used in calculating chance of failure, with that chance increasing as the operating time approaches the part's MTBF. When a part fails, its operating time it set to -1 until such time as it is repaired, at which time it is reset to 0 and starts counting up again.
String GetScope();
String GetScopeForSituation(String situation);
String GetScopeForSituation(Vessel.Situations situation);
String GetScopeForSituationAndBody(String situation, String body);
String GetScopeForSituationAndBody(String situation, CelestialBody body);
String GetScopeForSituationAndBody(Vessel.Situations situation, String body);
String GetScopeForSituationAndBody(Vessel.Situations situation, CelestialBody body);
Accessible to Reflection Interface: Yes
All of these methods do the same thing, that is they return a final String
that represents the Part's scope based on the given conditions. If not parameters are given the current scope is returned. For any parameter given, that parameter will override the current, with any missing parameters being filled in with the current. For example if you specify a Body
but not a Situation
, then the specified Body will be combined with the current situation to provide a final scope. The returned scope is in the format of <x>_<y>
based on the Body
and Situation
. This returned String
should be used for any other methods which have scope
as a parameter (which is most of them).
String PrettyStringForScope(String scope);
Accessible to Reflection Interface: Yes
Used to convert a given scope
string into a more friendly player string for display to the user. For example the scope "kerbin_atmosphere" will be returned as "Kerbin Atmosphere". In addition, this method will do body translations if the player's settings file defines an alias. So for example "kerbin_atmosphere" may be returned as "Earth Atmosphere" for a player with an RSS configuration.
double GetBaseFailureRate();
double GetBaseFailureRateForScope(String scope);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Returns the Base Failure Rate for a given part, for either the current scope or the specified scope.
FloatCurve GetBaseReliabilityCurve();
FloatCurve GetBaseReliabilityCurveForScope(String scope);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Returns the Reliability Curve for the given part, for either the current or given scope. The Reliability curve is a float curve that indicates how Flight Data is converted to Failure Rate (The term reliability here is a holdover from a previous system). Essentially it says, "With this much Flight Data what is the Part's Failure Rate?".
MomentaryFailureRate GetWorstMomentaryFailureRate();
MomentaryFailureRate GetBestMomentaryFailureRate();
List<MomentaryFailureRate> GetAllMomentaryFailureRates();
MomentaryFailureRate GetWorstMomentaryFailureRateForScope(String scope);
MomentaryFailureRate GetBestMomentaryFailureRateForScope(String scope);
List<MomentaryFailureRate> GetAllMomentaryFailureRatesForScope(String scope);
Accessible to Reflection Interface: No
These functions are not available to the Reflection Interface. Please see the specifics on the Reflection Interface for alternate functions which can be used.
Returns the current computed Momentary Failure Rate of the Part for either the current or specified scope. For convenience you can request the Best or Worst rate, and return a single Momentary Failure Rate, or you can request all of them in which case you get a List of MomentaryFailureRates returned. MomentaryFailureRate
is a struct that details all the information on the rate, including its trigger, and failureRate.
public struct MomentaryFailureRate
{
public String scope;
public String triggerName;
public double failureRate;
// ALWAYS check if valid == true before using the data in this structure!
// If valid is false, then the data is empty because a valid data set could not be located
public bool valid;
}
double GetMomentaryFailureRateForTrigger(String trigger);
double GetMomentaryFailureRateForTriggerForScope(String trigger, String scope);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Returns just the actual failureRate value for a specified Momentary Failure Rate trigger in either the current or specified scope.
double SetTriggerMomentaryFailureModifier(String trigger, double multiplier, PartModule owner);
double SetTriggerMomentaryFailureModifierForScope(String trigger, double multiplier, PartModule owner, String scope);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Set the Momentary Failure Modifier for a given trigger in either the current or specified scope. For convenience the methods will return back to the caller the current calculated Momentary Failure Rate for that trigger.
String FailureRateToMTBFString(double failureRate, TestFlightUtil.MTBFUnits units);
String FailureRateToMTBFString(double failureRate, TestFlightUtil.MTBFUnits units, int maximum);
String FailureRateToMTBFString(double failureRate, TestFlightUtil.MTBFUnits units, bool shortForm);
String FailureRateToMTBFString(double failureRate, TestFlightUtil.MTBFUnits units, bool shortForm, int maximum);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Convenience methods that take the given failureRate
and format a MTBF string in the given units
(Seconds, Minutes, Hours, Days, Years). If maximum
is specified, then the returned MTBF will be automatically upscaled if the given units
allows it to exceed the given maximum. For example if you call this method and ask for an MTBF in Seconds, with a maximum of 120, if the returned MTBF would exceed 120, the method will automatically convert it to Minutes, Hours, Days, or Years as needed to keep the final value under 120.
If shortForm
is true, then the returned string will be of the format "12345u" where u is the first letter of the units, (s)econds, (m)inutes, (h)ours, (d)days, or (y)ears. If shortForm
is fals, the returned value will be of the form "12345 units".
double FailureRateToMTBF(double failureRate, TestFlightUtil.MTBFUnits units);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
This method functions exactly the same as those that return a formatted string, except this method will only return the final MTBF number, not the string.
double GetFlightData();
double GetFlightDataForScope(String scope);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Returns the current amount of flight data on the given part for either the current or given scope.
double GetFlightTime();
double GetFlightTimeForScope(String scope);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Returns the current amount of flight time on the given part for either the current or given scope.
double SetDataRateLimit(double limit);
double SetDataCap(double cap);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Used to limit the amount of data that can be accumulated on a part. This can be used by mods like KCT to limit data gained in simulations, or it might be used by a mod to restrict data flow based on technology, or even something like RemoteTech to restrict data flow based on antennas.
SetDataRate
will set a multiplier that restricts at what rate the Flight Data is recorded. A value of 1.0 is normal, a value of 0.5 would mean that only 50% of the data would be recorded.
SetDataCap
will enforce a hard cap on the total amount of data recorded by a part, while this does not persist from session to session, it does take into account previously recorded data. Default on this is double.maxValue
Both methods will return the previous setting, making it easy to store the current setting, change it, then change it back when done.
double ModifyFlightData(double modifier);
double ModifyFlightTime(double modifier);
double ModifyFlightData(double modifier, bool additive);
double ModifyFlightTime(double modifier, bool additive);
double ModifyFlightDataForScope(double modifier, String scope);
double ModifyFlightTimeForScope(double modifier, String scope);
double ModifyFlightDataForScope(double modifier, String scope, bool additive);
double ModifyFlightTimeForScope(double modifier, String scope, bool additive);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Use these methods to modify the current amount of flight data stored for a part. In other words, you can use this to add or remove flight data from the part.
additive
defaults to false. If true, the given modifier is added to the existing flight data. If false it is multiplied against the current flight data.
double GetEngineerDataBonus(double partEngineerBonus);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
This method is used to calculate a final flight data bonus for having a crew with engineers on board. The caller should have already calculated the base engineer bonus, and that bonus is simply modified by the player's current difficulty settings and passed back to the caller. For example if the caller calculates an initial engineer bonus of 1.25, and the player's difficulty settings are set at normal, the value of 1.25 will be passed back. But if the player has set a higher or lower difficulty, then the modifier will be adjusted before being passed back. You should always use this method if you apply an engineer bonus so that the player's difficulty setting is respected.
ITestFlightFailure TriggerFailure();
ITestFlightFailure TriggerNamedFailure(String failureModuleName);
ITestFlightFailure TriggerNamedFailure(String failureModuleName, bool fallbackToRandom);
Accessible to Reflection Interface: No
These functions are not directly available to the Reflection Interface. Instead a modified version of them is available that simply returns null, rather than the triggered failure.
Call these methods to trigger a failure on the part. If no failure name is given, then a random failure will be chosen. If fallBackToRandom
is true, then the system will try to trigger a random failure if the specified failure could not be triggered. These methods return the PartModule that is triggered.
List<String> GetAvailableFailures();
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Returns a List of Strings indicating all the named failures available to be triggered on the part.
void EnableFailure(String failureModuleName);
void DisableFailure(String failureModuleName);
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Enables or Disables the specified failure module. A disabled failure will not get triggered by the core.
double GetOperatingTime();
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Returns the total operating time of the part.
double ForceRepair();
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Forces the part's failure to be instantly repaired, even if the repair requirements are not met. However under some conditions this may not be possible, so the return value should still be checked.
Returns number of seconds until repair is complete, 0 if repair is instantly completed, or -1 if repair failed.
double AttemptRepair();
Accessible to Reflection Interface: Yes
When called through the Reflection Interface, an additional first parameter of Part is required.
Attempt to repair the Part's current failure. The repair conditions must be met before repair will be attempted.
Returns number of seconds until repair is complete, 0 if repair is instantly completed, or -1 if repair failed.