Issues that can plague TweakScale
(and any other Add'On to tell the true)
I already explained about Overrules and HotFixes. Today I want to explain exactly what are the problems that were affecting TweakScale in the past (or still are), and that ended up motivating the Warnings, Alerts, Overrules and HotFixes. :)
Zero mass is evil. Negative mass too. And these affect every part that has mass, i.e., everything and the kitchen's sink. Including the Modules.
And this is not exclusive for TweakScale, every single Add'On that mangles with the mass are prone to this glitch (as Fuel Switches).
This is not a problem, but a fact: we can't have parts with negative or zero mass. So we must be careful to avoid such situations (at least, by accident), or we end up injecting divisions by zero into the Physics Engine. And divisions by zero are bad, really bad. It injects NaNs on everything, and the games goes crazy. Really crazy.
Negative mass inverts the forces on that part - specially thrust. This is the reason some crafts get "stuck" in the launchpad . You apply the thrust on a part, this part "pushes" the next, but that next part has negative mass and the force vector is negated and then it pushes back the first part. If we are talking a heavy fuel tank, that pushing back is enough to over stress everything and so things goes to space in the most unpleasant and undesirable way. Zero mass zero the forces, so the part became unmovable. Same thing.
Since TweakScale, when scaling a part, obviously scales the mass, TweakScale is the preferential victim of the problems I will describe below. But make no mistake, TweakScale can be the preferential victim, but it's not the only one.
Gravity appears to be affected too, as the statics around the launch pad start to explode by itself if you leave the craft lingering time enough on the launchpad - even with engines off.
Every single problem below can, eventually, end up with Zero or Negative mass. And that's the reason I need to tackle down them before doing any further development. So, in a nutshell: don't blame the Screaming Victim. :)
New parts, new code. This is on me. Real Life and that pesky Toe Stomping Fests I will describe below prevented me to carry on these tasks, so I decided to withdraw, in runtime, TweakScale from that parts to prevent breakage.
- Any part (stock or not) that has ModuleVarianPart with mass. Issue #13.
- Well, scaling parts with Variant is working - except for mass. The (clever) algorithm that applies the exponents to the datuns doesn`t knows (yet) about ModulePartPariant that have mass. And so, applies the exponent only on the root part and ignore the Variant.
- It happens that on some parts, the root mass is negative or zero, and the mass on the selected Variant is applied to it to get the final mass of the part. Well, if I scale the negative mass enough, the Variant mass would no be enough to make the total mass above zero (or can make it equals zero).
- Any part with B9PartSwitch and Modular Fuel Tanks. Issues #54 and #56.
- Patching a part with more than one fuel switch is bad enough.
- Instead of play cat-and-mouse with problems with Fuel Switches, is more sensible to do not patch a part with more than one Fuel Switch! :)
- Any part with FSBuoyancy. Issue #9.
- Don't have a clue yet about what's happening.
These are things that I want to solve, but not before getting patches right. It's nuts to fight a two front war. The present iteration, TweakScale 2.4.3.x , is finishing with that patch problems. The next iteration, 2.4.4.x will have these (and more, as Serenity) parts supported.
This is, easy, the worst problem at the moment. And this is not on me, as TweakScale depends of correctly written patches in order to correctly do its job.
Rogue patching happens when one or more patches apply the same (or slightly different) patch on the same part by accident; by something that changed somewhere, sometime; or by plain disregarding anything else. I'm pretty sure these patches worked fine on that time on the developer's machine - but we need to have these patches working fine now and on the users' machine, otherwise things may go kaput.
Of course some of the default TweakScale patches were also defective. The detected ones are already fixed, and besides I had eye balling all of them by now, some of the default patches relates to Add'Ons I don't find for downloading anymore. So, yeah, these will be deprecated on the 220.127.116.11 release, but they will be available on the Extras folder on the distribution ZIP - just in case.
These patches renders any Add'On using bad or unintended rules for doing the job. Worse, since rogue patching usually is unintended, it's not controlled and so you can have the GameDatabase mangled into a bad configuration without notice, and once you load Crafts and Savegames using that ruined GameDatabase, you have corrupted Crafts and Savegames in your installment. The really nasty side effect of this is that, sometimes, by fixing the GameDatabase you ruin your Savegames that became "addicted" to the ruined one.
Besides affecting any Add'On, TweakScale by its nature and popularity ends up being the most usual Screaming Victim of these rogue patches -TweakScale need correct rules in order to scale things, including mass - and as I explained above, making errors on handling the mass of a part is ruinous.
Of course, not every rogue patching ends in disaster. Some of them are just annoyances. But it's easier (and more feasible) to detect any rogue patching and fix them, than to try to workaround in code every single possibility of bad patching in order to overcome the effects - not to mention that this would be a fool's errand, as it's not possible to automatically guess the right patching with accuracy except on the most simple mistakes.
The following issues are related to this problem:
- Issue #12.
- Issue #15.
- Issue #20.
- Issue #24.
- Issue #30.
- Issue #34.
- Issue #45.
- Issue #49.
- Issue #56.
- Issue #58.
- Issue #60.
- Issue #62.
- Issue #63.
- Issue #67.
- Issue #69.
- Issue #70.
And the list is growing. :)
Please note that not a single one of that issues is related to the TweakScale (the Module). None of this is TweakScale's fault, but it happens that since TweakScale is injected on every Add'On on an installment, and are somewhat popular, TweakScale has a huge exposition to the problem, and so, it's the most usual Screaming Victim of these problems. And, boy, TweakScale is screaming nowadays.
Unholy Interactions Between Modules
This one, thanks Krakens, are not that usual nowadays :). But when it happens… :'(
What happens is that some Modules, besides working fine by themselves, now and then borks (or make bork) with a second Add'On. The most interesting case is about a Fuel Switch that, when have his toes stomped by a second Fuel Switch, injects Zero Mass into TweakScale computing. This one was somewhat… interesting… to isolate and detect - besides being simple to workaround. :P
However, not always these problems are due mistakes or flaws. One very hard to get rid nowadays is this one: some Add'Ons (TweakScale between them) uses the Main Menu scene to trigger a lot of initialization procedures, what nowadays happens concurrently (since 1.4.0, I think).
Some of them (including TweakScale) needs to read the GameDatabase. But others (including TweakScale) needs to write something into the GameDatabase. And when you have more than one Add'On writing into the GameDatabase at the same time and without controlling the concurrency, we have a Toe Stomping Fest. By some reason (and I don't know if the one that can explain this is Squad or Unity), when an Add'On overwrites something into the GameDatabase, any other guy trying to read that same data at the same time gets an NRE.
It's a wild, wide guess, but I think that when you iterate over the GameDatabase, you iterate over a copy of pointers to the data structures. And when someone writes a new version of a data structure, the old version is deallocated and any previous copy of that collection of pointers now have some invalid pointers - and we bork relentlessly on a Null Reference Exception while trying to read that pointer.
In a way or another, I managed to mitigate the problem by delaying my turn on the GameDatabase using some heuristics that I managed to make to work most of the time, but not always. Again, this is a fool's errand : every single time a new Add'On decides it needs to configure something on the GameDatabase when the game starts, it's risking stomping the TweakScale's toes. To tell you the true, I think that TweakScale must not be the only one being stomped, but anyway - TweakScale needs to be the last one to check the GameDatabase in order to detect any problems and to setup some needed data before the user loads a savegame - since TweakScale fixes things on the GameDatabase, these fixes need to be applied before any savegame is loaded!
In a nutshell - if the Add'On has this decorator
[KSPAddon(KSPAddon.Startup.MainMenu, <a_boolean_value>)] on a MonoBehaviour and access the GameDabase on its event handlers, this dude is a serious candidate to be a victim, a perpetuator or both on this problem. :)
Again, I want to stress that this is not exactly TweakScale's fault. And it's not a third part Add'On's fault neither - every single one of them work fine by themselves. But yet we need some way to manage the access to the GameDatabase in order to prevent this Toe Stomping Fest, and this is not something that any Add'On Author can do by him/herself - we depend on each other on this.
This is the reason I proposed a new feature on Module Manager, by the way.
We, as a Community, have some work to do. In the mean time, I'm writing workarounds. :)