Module Manager Patches to TweakScale :: Crash Test Course

It's hard to tell the correct/preferred method/way on a somewhat ad-hoc organization as the KSP Add'On Scene. We can't even agree on how to name it.

I have my reasons to call it Add'On, while most of the people like "Mods" more - besides the Forum calling them Add'On and people calling the Moderators "Mods". All of that was somewhat confusing for me at the beginning.

But I can tell you what I think is the better way to write a patch. At least, for now - someone else can have a better idea later, and I don't have any love for any of my convictions: I throw them alway in the exact instant I'm convinced that something else is better.

Module Manager's documentation is somewhat vast, and besides being not that hard to understand, it's a lot of things to assimilate. So let's split this Crash Test Course into "Use Cases", instead of shoving a gazillion of new technical data into your head.

Use Cases

I'm an Add'On Author/Maintainer and want to add a TweakScale patch to my parts

Welcome to the team. :)

Since you are The One for your Add'On, you are the maximum authority as how things should behave on your parts, and everybody else can choose to agree with you or to write their own patches in order to override yours.

So this can be hairy, as it's incredibly easier to trigger a Rogue Patching Fest - i.e., uncontrolled patching on parts leading to indeterministic (and some times, dangerous) state on the part.

Module Manager has some operators to help us to prevent that Fest. For Add'On Authors/Maintainers, the magic word is :FOR.

Let's imagine you own an Add'On called... FancyAddOn :P and want to add a TweakScale patch to a new fancy tank of yours, called... FancyTank.

You have some options, and the one you may want will depend on how you want to be tied to TweakScale:

Option 1: TweakScale as Hard Requirement

That's the easiest, shove the TweakScale MODULE section into the Config file and forget about patches. :)

PART
{
    name = FancyTank
    module = Part
    author = FancyPants

    mesh = fancy-tank.mu
    rescaleFactor = 0.75

    node_stack_top = 0.0, 3.75, 0.0, 0.0, 1.0, 0.0, 2
    node_stack_bottom = 0.0, -3.75, 0.0, 0.0, -1.0, 0.0, 2
    node_attach = 0.0, 0.0, -2.5, 0.0, 0.0, 1.0, 1

    TechRequired = aerodynamicSystems
    entryCost = 7500
    cost = 2200
    category = Propulsion
    subcategory = 0
    title = Fancy Tank
    manufacturer = Fancy Pants Inc.
    description = A Fancy Tank for your fuel needs!
    bulkheadProfiles = size2

    attachRules = 1,1,1,1,0

    mass = 0.35
    dragModelType = default
    maximum_drag = 0.2
    minimum_drag = 0.3
    angularDrag = 2
    crashTolerance = 20
    breakingForce = 50
    breakingTorque = 50
    maxTemp = 2000
    fuelCrossFeed = True

    RESOURCE
    {
        name = LiquidFuel
        amount = 1200
        maxAmount = 1200
    }

    MODULE
    {
        name = TweakScale
        type = stack
        defaultScale = 2.5
    }
}

Option 2: TweakScale as a Soft Dependency

When using like this, your part will have TweakScale support added to the GameDatabase only if TweakScale is installed, preventing cluttering the game with useless info.

You can add this to the same file as the part (after its definition, of course) or you can put this on a different file. You can create a file only for TweakScale patches, or you can shove all modules into the same patch (multiple MODULE definitions inside the PART).

@PART[FancyTank]:FOR[FancyAddOn]
{
    %MODULE[TweakScale]:NEEDS[TweakScale]
    {
        type = stack
        defaultScale = 2.5
    }
}

The @ says to edit a existent PART, and the whole patch will be ignored if a part called FancyTank is not present on the GameDatabase.

The % before the module says to edit or create a module section for TweakScale. It's how we add a new module section to a config, but also how we edit a existent one (and I think this is a source of problems, but things are what things are).

The :NEEDS says to only apply the patch when TweakScale is installed, otherwise this section will be ignored. Other sections can still be applied.

The :FOR is important: it says that this is a standard patch for the Add'On FancyAddOn, and allows ordering when third-parties wants to edit or add things to your part.

I'm not the Author/Maintainer, but I want to create non-official patches for it.

Usually, it's how most patches for TweakScale born. Someone creates a ser of patches, people start to use it and the Add'On Author/Maintainer decides to include them on his/her standard Distribution.

On the past, some of these patches were included into the TweakScale Standard Distribution - but nowadays, I'm trying to avoid the practice, as it adds to TweakScale the burden of maintaining these patches. It's better to move them to independent "Plugins" to the TweakScale distribution.

Back to business, it's not too different from the previous Use Case, and have some options too.

I want o change a minor detail from the "Official" patches

Do as follows:

@PART[FancyTank]:NEEDS[FancyAddOn]
{
    %MODULE[TweakScale]:NEEDS[TweakScale]:AFTER[FancyAddOn]
    {
        %defaultScale = 5
    }
}

We have a new operator, :AFTER . It says "I'm a third-party, and I want to apply this patch after FancyAddOn patches are applied". Note he % operator in front of defaultScale. ALWAYS use the % operator while applying patches that changes something on a part that it's not yours - unless some very special circumstances, out of scope for this document.

I want to completely overwrite any Standard patch, and impose my own way

Well, you can do as follows

@PART[FancyTank]:NEEDS[FancyAddOn]
{
    -MODULE[TweakScale],* { }
    %MODULE[TweakScale]:NEEDS[TweakScale]:AFTER[FancyAddOn]
    {
        %type = free
    }
}

The - before the first MODULE, as well the ,* after it tells Module Manager to delete every single instance of a MODULE with the name TweakScale.

I'm an end user customizing my own KSP, and I don't care (or want) to publish them

Easy!

@PART[FancyTank]:NEEDS[FancyAddOn]
{
    -MODULE[TweakScale],* { }
    %MODULE[TweakScale]:NEEDS[TweakScale]:FINAL
    {
        %type = free
    }
}

The :FINAL operator tells Module Manager to apply the patch on the end of the patching. It's hardly a good idea to use it on patches meant to be distributed as Add'Ons, doesn't do this unless you have no other alternative.

So this patch, once you add it to a file on your installment, will bluntly obliterate anything else and impose your own changes. Keep in mind that this will void your warranty. ;)

I'm an Add'On Author/Maintainer and I want to customize Stock parts, or a Third-Party Add'On with patches distributed by TweakScale

While I aim to hand over all the patches to "Plugins" and support directly on TweakScale only Stock (and DLC) parts, for the near future I kinda that "own" that patches, so you will need to handle them differently:

@PART[KAXturboprop]:NEEDS[KAX]
{
    -MODULE[TweakScale],* { }
    %MODULE[TweakScale]:NEEDS[TweakScale]:FINAL // Should be :AFTER[TweakScale] but this will be possible only on TweakScale 2.5
    {
        %type = free
    }
}

This patch changes the scaling for KAX's turbo prop engine. You see that :FINAL thingy? It's a stunt, and frankly something that I'm not exactly proud of.

:FINAL should be used only to end-user patches, or for stunts like TweakScale's Overrules and HotFixes. Everybody else should use :AFTER or :BEFORE to tell Module Manager the ordering you want the patch to be applied.

However, these operator needs that the dependency use the :FOR operator, and TweakScale until the future release 2.5 does not use, as it causes breakage on legacy patches (and boy, it really does a ugly breakage). So, for now, TweakScale is not using :FOR, and so people can't use :AFTER or :BEFORE.

So the only remaining option is to use :FINAL for while.

My apologies to this stunt, I'm working hard to make things straight on TweakScale 2.5, and then you will be able to patch Stock parts correctly.

I'm an Add'On Author/Maintainer and I don't like the Patches TweakScale distributes for my Add'On

By all means, talk to me :) I'll gladly hand them over to you and move my owns to a deprecated folder, pinpointing your Add'On as the new canonical patches for the part! ;)