Jump to content

[1.2.2] TestFlight - v1.8.0 - 01 May 2017 - Bring Flight Testing to KSP!


Agathorn

Recommended Posts

During a KCT simulation there shouldn't be failures. Or at least add an option to disable that.

There are plans for better integration but until such time as 1) KCT integrates with TF using the API i've supplied, or B) KCT makes an API that TF can use to integrate with it, there isn't anything I can do.

TestFlight provides an API to allow KCT to do that and more, but magico13 never got around to doing any implementation. He has talked about maybe making an API for KCT, and if he does, and that API gives me what I need, then at that time I will look into better integration.

Link to comment
Share on other sites

There are plans for better integration but until such time as 1) KCT integrates with TF using the API i've supplied, or B) KCT makes an API that TF can use to integrate with it, there isn't anything I can do.

TestFlight provides an API to allow KCT to do that and more, but magico13 never got around to doing any implementation. He has talked about maybe making an API for KCT, and if he does, and that API gives me what I need, then at that time I will look into better integration.

Since I don't know how long enneract will take to get HoloDeck to a functional state, and because I feel bad about not getting around to this earlier, I'm gonna take a look at this now. Won't be in a full release for a while, but it'll be in dev versions of KCT. I just need to figure out how to disable or enable failures on a whole craft. Still learning how you've got the API set up. In case it matters, I'm planning on using the hybrid method.

Sorry about the confusion/delay. The past few months have been an interesting time and plans keep getting shuffled around.

E: Looks like I just get all the failures on a part, loop over them, and disable them by name. Then to reenable failures you get all the failures and enable them by name. Correct?

E2: Next question. How exactly do I get the ITestFlightCore for a specific part? I'm assuming it's related to a PartModule maybe? Still trying to wrap my head around this :P

E3: About to test if this code works. If so, then I think I've got the hang of it. Doing things like keeping partial data will be harder, but at least letting people disable failures makes sense.

E4: HAHA! It works ;) Alright, consider the ability to disable/re-enable part failures to be in the next dev versions.

Edited by magico13
Link to comment
Share on other sites

Since I don't know how long enneract will take to get HoloDeck to a functional state, and because I feel bad about not getting around to this earlier, I'm gonna take a look at this now. Won't be in a full release for a while, but it'll be in dev versions of KCT. I just need to figure out how to disable or enable failures on a whole craft. Still learning how you've got the API set up. In case it matters, I'm planning on using the hybrid method.

Sorry about the confusion/delay. The past few months have been an interesting time and plans keep getting shuffled around.

E: Looks like I just get all the failures on a part, loop over them, and disable them by name. Then to reenable failures you get all the failures and enable them by name. Correct?

E2: Next question. How exactly do I get the ITestFlightCore for a specific part? I'm assuming it's related to a PartModule maybe? Still trying to wrap my head around this :P

Hmm you know what, those API examples are embarrassingly out of date now, as a lot has changed in the core code. For example, finding the core is very different now due to the query system.

The good news is you don't need to worry about it. Things are actually easier now then they were back then :)

The easiest way to do it is to use TestFlightInterface (https://github.com/jwvanderbeck/TestFlight/blob/dev/TestFlightCore/TestFlightCore/TestFlightInterface.cs) which is, essentially an API wrapper around the API :P Its job is to make it easier to interact with TF through Reflection. Every method in TestFlightInterface is static, so that makes them very simple to call from Reflection. Furthermore any of the methods that deal with a part specifically (which is 99% of them, other than some basics like checking if TF is enabled, etc) take the Part as a param, and then find the core for you internally.

I would look at the Interop example code: https://github.com/jwvanderbeck/TestFlightAddon/blob/master/TFInteropExample.cs for a simpler example of how to work with the TestFlightInterface, but in a nutshell:

Initial setup: https://github.com/jwvanderbeck/TestFlightAddon/blob/master/TFInteropExample.cs#L11-L26

That will then give you a cached tfInterface handle to the TestFlightInterface which you can use to invoke the various Interface methods.

For example:


tfInterface.InvokeMember("DisableFailure", tfBindingFlags, null, null, new System.Object[] { this.part, "TestFlightFailure_ResourceLeak" });

Side note, while the API has been very stable, I would verify things as they stand in the "dev" branch just in case. One example is that Scope is going away in 1.3, so all the methods dealing with Scope aren't needed anymore.

- - - Updated - - -

E4: HAHA! It works ;) Alright, consider the ability to disable/re-enable part failures to be in the next dev versions.

LOL you got it working faster than I could type up my reply. Is that a sign I made it good? :)

Link to comment
Share on other sites

LOL you got it working faster than I could type up my reply. Is that a sign I made it good? :)

It seems pretty easy to work with now that I have an idea of what I'm doing. I almost never work with PartModules, so I wasn't sure if what I was doing was correct. But it listed off all the possible failure modes when I asked it to, so I'm assuming things are working properly ;) I'll do a bunch of random launches and see if I can get things to fail/not fail when I want them to.

I'm just doing this currently:


foreach (Part p in FlightGlobals.ActiveVessel.Parts)
{
if (p.Modules.Contains("TestFlightCore"))
{
TestFlightAPI.ITestFlightCore coreMod = p.Modules["TestFlightCore"] as TestFlightAPI.ITestFlightCore;
//disable failures
foreach (string failureName in coreMod.GetAvailableFailures())
{
KCTDebug.Log(p.partInfo.name + ":" + failureName);
coreMod.DisableFailure(failureName);
}
}
}

E: Hmm. Failure still occurring. Might need to do something else.

E2: Might try out the interface instead. Will report back if I have success or problems.

E3: Nope. Supposedly disabled failures are still being triggered using that method instead of the hybrid method. It will gladly tell me all the possible failures, but using those I can't actually disable them. I think it might be on your side.

When you disable a failure you lower and trim the name: failureModuleName = failureModuleName.ToLower().Trim();

When you check if a module is in the disabled list, you don't: PartModule pm = fm as PartModule; if (!disabledFailures.Contains(pm.moduleName)) {...}

I bet there's some case issues there, since the names that I'm getting have capitals in them, meaning it will never find them in the list if they're made lowercase.

Edited by magico13
Link to comment
Share on other sites

It seems pretty easy to work with now that I have an idea of what I'm doing. I almost never work with PartModules, so I wasn't sure if what I was doing was correct. But it listed off all the possible failure modes when I asked it to, so I'm assuming things are working properly ;) I'll do a bunch of random launches and see if I can get things to fail/not fail when I want them to.

I'm just doing this currently:


foreach (Part p in FlightGlobals.ActiveVessel.Parts)
{
if (p.Modules.Contains("TestFlightCore"))
{
TestFlightAPI.ITestFlightCore coreMod = p.Modules["TestFlightCore"] as TestFlightAPI.ITestFlightCore;
//disable failures
foreach (string failureName in coreMod.GetAvailableFailures())
{
KCTDebug.Log(p.partInfo.name + ":" + failureName);
coreMod.DisableFailure(failureName);
}
}
}

E: Hmm. Failure still occurring. Might need to do something else.

E2: Might try out the interface instead. Will report back if I have success or problems.

E3: Nope. Supposedly disabled failures are still being triggered using that method instead of the hybrid method. It will gladly tell me all the possible failures, but using those I can't actually disable them. I think it might be on your side.

When you disable a failure you lower and trim the name: failureModuleName = failureModuleName.ToLower().Trim();

When you check if a module is in the disabled list, you don't: PartModule pm = fm as PartModule; if (!disabledFailures.Contains(pm.moduleName)) {...}

I bet there's some case issues there, since the names that I'm getting have capitals in them, meaning it will never find them in the list if they're made lowercase.

I commented on the bugs on GitHub, but wanted to follow up here as well. Right now your code above is problematic as it isn't the proper way to get the Core on a part. There can be multiple Cores (or any model really) on a part, but only one will be the active one. This is because things like engines in RO for example can have multiple configurations on the same part because of RealFuels. So TestFlight has a Query system that can be used to define multiple modules and which configurations to hook to.

Anyway long story short you need to either 1) Use TestFlightInterface and just specify the part, and let it hook to the proper Core, or 2) If you are going to get the Core yourself, you need to call the API to let it get the right one for you. https://github.com/jwvanderbeck/TestFlight/blob/dev/TestFlightAPI/TestFlightAPI/TestFlightAPI.cs#L103

Link to comment
Share on other sites

I've changed it since then to use the reflection based method.


if (KCT_Utilities.TestFlightInstalled && KCT_GameStates.TestFlightPartFailures && GUILayout.Button("Disable Part Failures"))
{
KCT_GameStates.TestFlightPartFailures = false;
foreach (Part part in FlightGlobals.ActiveVessel.Parts)
{
bool tfAvailableOnPart = (bool)KCT_Utilities.TestFlightInterface.InvokeMember("TestFlightAvailable", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { part });
if (tfAvailableOnPart)
{
foreach (string failureName in (List<string>)KCT_Utilities.TestFlightInterface.InvokeMember("GetAvailableFailures", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { part }))
{
KCTDebug.Log(part.partInfo.name + ":" + failureName);
KCT_Utilities.TestFlightInterface.InvokeMember("DisableFailure", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { part, failureName });
}
}
}
}
if (KCT_Utilities.TestFlightInstalled && !KCT_GameStates.TestFlightPartFailures && GUILayout.Button("Enable Part Failures"))
{
KCT_GameStates.TestFlightPartFailures = true;
foreach (Part part in FlightGlobals.ActiveVessel.Parts)
{
bool tfAvailableOnPart = (bool)KCT_Utilities.TestFlightInterface.InvokeMember("TestFlightAvailable", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { part });
if (tfAvailableOnPart)
{
foreach (string failureName in (List<string>)KCT_Utilities.TestFlightInterface.InvokeMember("GetAvailableFailures", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { part }))
{
KCTDebug.Log(part.partInfo.name + ":" + failureName);
KCT_Utilities.TestFlightInterface.InvokeMember("EnableFailure", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new System.Object[] { part, failureName });
}
}
}
}

If/when I get into doing more interactions with TestFlight, I'll clean that up some more, but for now it appears to work with the modified TestFlight I have.

Link to comment
Share on other sites

Release 1.3 (v1.3.1.0)

GitHub, or KerbalStuff

Highlights

KSP v1.0.2 Compatible

No more scope

As of v1.3, the concept of flight scope has been removed form TestFlight. This means that part reliability and flight data are universal. Removal of scope reduced the complexity of the code, but more importantly opened up things for coming soon features that simply couldn't be done well while scope was there. It made things too complex for the player.

ContractConfigurator Support

TestFlight now supports ContractConfigurator by adding a new contract goal to gather flight data on a part. This allows contract authors to add flight testing! NOTE: While the support is there, currently no contracts actually use it.

Stock Configs

This version of TestFlight introduces some basic preliminary config files to support Stock parts for everyone who wanted to play with TestFlight but don't play RealismOverhaul. More fleshed out configs will come later and i'm really hoping I can enlist some community help on these, as I personally don't play stock.

TestFlight Plugin, and Config Packs

TestFlight is now distributed in pieces consisting of one ZIP file for the core plugin, without any configs, and then separate config packs, currently for RealismOverhaul and Stock. NOTE: Under this new model, you must make sure to download and extract both the core plugin and one config pack.

There may be some initial hiccups on CKAN due to this change, as it isn't possible for me to test it 100% before releasing. Any issues I will endeavor to fix as quickly as possible. Please let me know if you run into any problems!

Change Log

•API: new API stubs for interrogating scenario data store

•GAME-PLAY: The concept of '*scope*' no longer applies, and data and reliability is universal. This is a major change that paves the way for newer features coming soon.

•CONFIGS - ALL: Updated reliability configs to use noscope format

•NEW: ContractConfigurator support. TestFlight now creates a new Contract goal for gaining flight data on a part. This allows contract authors to incorporate flight testing into contracts.

•FIX: Fixed data type errors in noscope api changes. Added data overloads for float, int, bool, and double

•NEW: Property added to TestFlightCore `startFlightData` that can be used to indicate that a part should start with a given amount of existing flight data

•NEW: TestFlightScenario available in all scenes

•FIX: ContractConfigurator don’t try to validate part string during initial load, as we won’t have a scenario available then

•FIX: ContractConfigurator only display data remaining if some data has been collected

•KSP: Updated and compiled for KSP v1.0.0

•NEW: TestFlight now distributed as multiple files, with a core Plugin Only distribution and multiple Config Packs, currently for RealismOverhaul and Stock.

•FIX: If TestFlight title property is not defined or blank, use the part's stock title instead

•FIX: Fix possible infinite loop when the TestFlightCore had a configuration without query in it

•NEW: Allow any module to have a blank or undefined config. In such cases it is considered always active

•CONFIGS - STOCK: Added RT5, RT10, BACC, and Kickback solid boosters

•CONFIGS - STOCK: Added: LV-T30, LV-T45, LV-909, Poodle, Skipper, Mainsail liquid engines

•CONFIGS - RO: WAC-Corporal and XLR11 engines start fully tested

•CONFIGS - STOCK: Fixed incorrect configuration tags on stock solid engines

•CONFIGS - STOCK: First tier stock liquid and solid engines start at max data

already researched

•API: Added API to TestFlightManager for persisting arbitrary data for a save game

•NEW: Added per save game settings

•NEW: Parts can be set to always be at maximum flight data in a specific save game

•NEW: TestFlight can be enabled or disabled on a per save game basis

•FIX: When part’s start at MaxData they start at properly the maximum data defined by the ReliabilityCurve and not some insane high value.

•FIX: NREs caused by save game without existing data store

•NEW: Added save game settings to the KSC level TestFlight settings window

•FIX: Engines would continue gaining data when shutown. Engines now use finalThrust to determine running state

•NEW: Added `maxData` property to TestFlightCore to indicate the maximum amount of flight data the part can obtain.

•CONFIGS - STOCK: Added stock resource tank configs

•NEW: Flight data caps out at `maxData` as defined by the TestFlightCore. Closes #68

•CONFIGS - STOCK: Add maxData to all the stock engine configs

•NEW: Added default savegame settings

•API: Updated SaveData API to allow passing a default value to be used in the case where the saved data could not be found or converted to type

•CONFIGS - RO: Added proper `maxData` lines to all existing RO engine configs (Thanks @NathanKell!)

•CONFIGS - STOCK: Don't treat command pods with resources as resource tanks

•FIX: Updated AV .version to KSP 1.0

•NEW: Updated build system to include a version file for configs

•NEW: Split core and config packs into separate netkans

•FIX: Updated ReducedThrust code to work with FuelFlow (Reducing fuel flow results in loss of thrust) for KSP 1.0

•NEW: Failure_ReducedMaxThrust now supports new KSP 1.0 engines as well as RF EngineSolver engines- Refactored EngineModuleWrapper to no longer split between ModuleEngines and ModuleEnginesFX, and to support new EngineSolverengines such as ModuleEnginesRF

•FIX: No longer use FAR (when installed) to get atmospheric density, as KSP 1.0 has proper values now

•NEW: Compiled for KS 1.0.2

•NEW: Compiled for ContractorConfigurator 1.0.4

•NEW: Failure_ResourceLeak is now more flexible in how the leak amounts are defined. By default it functions as normal, however you can optionally specify values to be in percent of maximum resource capacity or percent of current resource level. By adding the suffixes %t or %c respectively.

•NEW: Added `calculatePerTick` property to Failure_ResourceLeak. If set to `true` then any percent values will be re-calculated each tick. If`false` then they will only be calculated initially at the time of failure. Default values is `false`.

•FIX: Leaked resources will no longer pull from other parts!

•FIX: Proper lowercase check for failure module names. (Thanks @magico13!)

•FIX: Catch situation where TriggerFailure() has no valid failures inthe list. (Thanks @magico13!)

•NEW: Core.dataCap is now a float percentage rather than a hard number

•NEW: Add API method GetMaximumFlightData() which returns the most amount of flight data possible to be gained on a part

•FIX: Parse leak values as en-US format

Edited by Agathorn
Link to comment
Share on other sites

  • 2 weeks later...

Are there any plans to make this compatible with the Dangit! mod (or one of the other failure and EVA repair mods)? It carries on some of the same principles but I think it could be made way better if it used progressive reliability vs everything having a set reliability the whole game

Link to comment
Share on other sites

Are there any plans to make this compatible with the Dangit! mod (or one of the other failure and EVA repair mods)? It carries on some of the same principles but I think it could be made way better if it used progressive reliability vs everything having a set reliability the whole game

No, and frankly I don't understand why people keep asking me this? This and DangIt! basically do the same thing in totally different ways. How could they possibly work together? TestFlight is designed to simulate failures in a more realistic rather than random way, and to allow parts to improve in reliability through flight testing. AFAIK DangIt! is the exact opposite, making parts get worse with age based on an inventory system.

EDIT: Ok the above comes off more upset than it really is :) Really it isn't anger, its confusion. I honestly don't see how the two could possibly work together.

Edited by Agathorn
Link to comment
Share on other sites

Are the mean times between failure in stock supposed to be either ~50 minutes or 111 minutes? I was testing the stock version of TestFlight, and that's what I'm getting atm. I remember the last time I did RO, I had failures in seconds rather than hours. Any ideas on what I'm doing wrong?

Edited by FanaticalFighter
Link to comment
Share on other sites

Are the mean times between failure in stock supposed to be either ~50 minutes or 111 minutes? I was testing the stock version of TestFlight, and that's what I'm getting atm. I remember the last time I did RO, I had failures in seconds rather than hours. Any ideas on what I'm doing wrong?

Possibly, but I would have to run the numbers. I did make the Stock configs be a lot more reliable. Honestly as I don't play with stock, I just spit-balled some numbers to get things running.

Link to comment
Share on other sites

Are the mean times between failure in stock supposed to be either ~50 minutes or 111 minutes? I was testing the stock version of TestFlight, and that's what I'm getting atm. I remember the last time I did RO, I had failures in seconds rather than hours. Any ideas on what I'm doing wrong?

Same here. Considering this mod under heavy development, and the stock configs new and experimental, here's what I did:


// massively increase long term part reliability and amount of
// attainable test data, markedly reduce amount of initially
// available data if available
@PART
[*]:HAS[@MODULE[TestFlightCore]&@MODULE[TestFlightReliability]]:FINAL{
@MODULE[TestFlightCore]{
@startFlightData = 1000
@maxData = 1000000000
}

@MODULE[TestFlightReliability]{
@reliabilityCurve{
key,2 = 100000 0.000001
key,3 = 10000000 0.00000001
key,4 = 1000000000 0.0000000001
}
}
}


// generic patch for all (most?) engines
// LFO, Jets, Nerva: ModuleEngines, MultiModeEngine, ModuleEnginesFX
// RCS: ModuleRCS
// beware of engineer* etc., otherwise @MODULE[*engine*] could have
// been so simple...
// maybe HAS[[@MODULE[*engine*]]&[!@MODULE[*engineer*]]] might work
@PART
[*]:HAS[@MODULE[ModuleEngines]|@MODULE[MultiModeEngine]|@MODULE[ModuleEnginesFX]|@MODULE[ModuleRCS]&!MODULE[TestFlightCore]]:NEEDS[TestFlight]:FINAL{
MODULE{
name = TestFlightInterop
}
MODULE{
name = TestFlightCore
//startFlightData = 10000
maxData = 1000000000
}
MODULE{
name = FlightDataRecorder_Engine
flightDataEngineerModifier = 0.25
flightDataMultiplier = 5
}
MODULE{
name = TestFlightReliability
reliabilityCurve{
key = 0 0.0005
key = 10000 0.0001
key = 100000 0.000001
key = 10000000 0.00000001
key = 1000000000 0.0000000001
}
}
MODULE{
name = TestFlightFailure_ShutdownEngine
REPAIR = None
weight = 16
failureType = software
failureTitle = Engine Shutdown
duRepair = 50
duFail = 100
severity = failure
}
MODULE{
name = TestFlightFailure_ReducedMaxThrust
REPAIR{
canBeRepairedInFlight = False
canBeRepairedOnSplashed = False
canBeRepairedByRemote = True
repairChance = 50
}
weight = 32
failureType = mechanical
failureTitle = Loss of Thrust
duRepair = 250
duFail = 100
severity = failure
}
MODULE{
name = TestFlightFailure_Explode
failureTitle = Explosion!
weight = 2
duFail = 400
failureType = mechanical
severity = major
}
}

That should take care of most engines. I haven't looked at the tanks yet, and I guess other parts could have failure modes as well, such as parachutes, or even structural elements. But this works for me as a first step.

Edited by Corax
Typo in .cfg
Link to comment
Share on other sites

Possibly, but I would have to run the numbers. I did make the Stock configs be a lot more reliable. Honestly as I don't play with stock, I just spit-balled some numbers to get things running.

Looks like you may need a bit of help getting the Stock configs. I have tons of free time at the moment seeing as I just got out of school, and I play Stock as well as RO, so I have some experience in both environments. If you could point me to some documentation of the config, I could whip up a stock config and push it to the git.

Link to comment
Share on other sites

Looks like you may need a bit of help getting the Stock configs. I have tons of free time at the moment seeing as I just got out of school, and I play Stock as well as RO, so I have some experience in both environments. If you could point me to some documentation of the config, I could whip up a stock config and push it to the git.

I will see if I can get something typed up. It is something I need to do anyway, I have just been avoiding it :)

Link to comment
Share on other sites

Some *very* initial docs on the YAML config format: https://github.com/jwvanderbeck/TestFlight/wiki/YAML-Configuration-Syntax

Also if you look at the YAML files, especially the RO ones you will find some comments here and there to help understand some of the nuances. Beyond that the best way to learn as usual is to just dive in, play with it, and ask questions. So please any questions, just ask here.

Edited by Agathorn
Link to comment
Share on other sites

Love the mod, thank you for the work u put into it!

I just checked wiki/configs... is there a plan for stuff like ReacionWheels/Solarapanels/RCS-blocks/Winglets failures!?

The only "two" modules i could find that can fail is engine and resources, or did i miss a thing?

Link to comment
Share on other sites

Love the mod, thank you for the work u put into it!

I just checked wiki/configs... is there a plan for stuff like ReacionWheels/Solarapanels/RCS-blocks/Winglets failures!?

The only "two" modules i could find that can fail is engine and resources, or did i miss a thing?

No you didn't miss anything. Those are the parts I started with, but the rest can definitely be added. Just need to do configs for them, and if we need new failure modules more applicable to certain parts than I am more then happy to create them. We just need to work out exactly what is needed.

Link to comment
Share on other sites

No you didn't miss anything. Those are the parts I started with, but the rest can definitely be added. Just need to do configs for them, and if we need new failure modules more applicable to certain parts than I am more then happy to create them. We just need to work out exactly what is needed.

Oh ok, can't wait... im not a programer so i really can't help, but maybe there is a way to interact with the right-click gui so that you can disable certain things and then remove them from the list!?

Also... small suggestions if you allow:

I find the Guis a bit unhandy in my opinion... i would enjoy in-flight highlighting parts to show condition, like far did that with the drag&lift part highlight thingy back in 0.90 plus a right-click part info for reliability!?

Link to comment
Share on other sites

No you didn't miss anything. Those are the parts I started with, but the rest can definitely be added. Just need to do configs for them, and if we need new failure modules more applicable to certain parts than I am more then happy to create them. We just need to work out exactly what is needed.

A general failure type mode would be appropriate for a lot of different parts. if it's possible. Something that makes the part completely ignore anything you attempt to do to it. It would also work as a good placeholder for making configs and somewhere down the line, you could add more appropriate failure modes.

Link to comment
Share on other sites

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