# Config integration

A script can read settings that the user controls. The `Config` global is your mod's own settings namespace, shown to players in the settings menu and persisted to a config file. Use it to give players a number that they can adjust, or a list of choices. Players then do not have to edit your Lua.

`Config` is available to every patch script with `PM` and `J`. `CampaignConfig` is also available. It works the same way, but it keeps a separate value for each campaign.

## Defining an entry

You declare an entry with `Config:Define(section, name)`, chain a few descriptors, and finish with `:Bind()`. Binding returns a live handle you read through:

```lua
local thrustScale = Config:Define("Tweaks", "ThrustScale")
    :Type(Double)
    :Default(1.0)
    :Range(0.5, 2.0)
    :Desc("Scales the thrust readout in the engine window.")
    :Bind()
```

`Define` takes a section and a name, which is how the entry is grouped and labeled in the settings menu. The following builder members are then used to fill it out:

* `:Type(...)` sets the value type. The built-in types are the globals `String`, `Integer`, `Double`, `Boolean`, and `Color`. This one is required.
* `:Default(value)` sets the value used on first launch, before the player changes anything.
* `:Range(min, max)` constrains a number to a slider. Optional extra arguments set the slider step count and number format.
* `:Values({...})` constrains the value to a fixed set of choices.
* `:Desc(text)` sets the description shown in the settings menu. `:NameLoc(key)` and `:DescLoc(key)` set localization keys instead, for translated text.
* `:Feature(id)` and `:NoFeature(id)` show the entry only while a [feature](/doc/campaign-features-9YIewcIArR) is on, or off. See below.
* `:Tag(name)` attaches a metadata tag.
* `:Bind()` finalizes the entry and returns the handle.

Entry definition is idempotent. If you define the same entry in multiple Lua files for your mod, it will not create multiple config entries, and if the form of all the entries is the same then it does not matter which one runs first. This means that you are safe to define config handles in a [library](/doc/sharing-lua-with-require-hXbW2HK8Ep) file for your mod.

## Reading and writing the value

The handle has a `value` field. Read it to get the current setting, assign it to change the setting (which is automatically persisted):

```lua
if thrustScale.value ~= 1.0 then
    -- the player has changed it
end
```

If you only need to read an entry you defined elsewhere, `Config:Get(section, name)` returns a handle for an existing entry, or `nil` if it was never defined.

## Settings and patches

PatchManager keeps a [cache](/doc/caching-and-invalidation-QifFi4oev9) for each feature set. The cache does not monitor settings. When a patch reads a setting, the cache keeps the value from the last build of that set. A change to the setting does not cause a rebuild. Thus, do not make the output of your patches depend on a setting.

Content that a player turns on or off for each campaign is a [feature](/doc/features-geboWdIiDN). Gate the patch on the feature, not on a setting:

```lua
PM.Parts:Patch("BuffHeavyEngines")
        :Feature("BuffHeavyEngines")
        :Named("engine_2v_methalox_mainsail")
        :Do(function(part) ... end)
```

The player turns the feature on for a campaign in the feature editor. Each set has its own patch run and its own cache, so no cache becomes stale. Use settings only for runtime behaviour: values that the code of your mod reads while the game runs.

## Showing an entry only with a feature

`:Feature(id)` on the builder shows the entry in the settings menu only while that feature is on in the active set. `:NoFeature(id)` shows the entry only while that feature is off. An id without a mod prefix is a feature of your mod. An entry that you define inside `PM:WithFeature` automatically gets the feature of that scope:

```lua
local hardModeMultiplier = Config:Define("HardMode", "CostMultiplier")
    :Type(Double):Default(2.0)
    :Feature("HardMode")
    :Bind()
```

All entries are also hidden while the default feature of your mod is off.

## Per-campaign settings

`CampaignConfig` has the same `Define`, `Get` and `Mod` members as `Config`, but each campaign keeps its own values:

* The values are saved with the campaign.
* A new campaign starts with the default values.
* Players change the values in the settings of your mod, under a Campaign heading. This heading shows when they open the settings from the pause menu of a campaign that has your mod on.

Use `CampaignConfig` for choices that apply to one playthrough, not to the player:

```lua
local startingFunds = CampaignConfig:Define("Campaign", "StartingFunds")
    :Type(Integer):Default(10000)
    :Bind()
```

As with `Config`, use `CampaignConfig` in runtime code. A patch serves all campaigns that have the same set, so a patch cannot read the values of one campaign.

## Using another mod's config

`Config:Mod(modId)` gives you read and write access to the config of a different mod. A script can use it to react to a setting of that mod. Do not use it for your own settings. Use `Config:Define` and `Config:Get` as shown on this page.

## Config file location

Your mods config file location depends on whether or not it is a "standalone" Lua mod. If it is standalone, then the config file will be in the mods folder right next to your Lua file. If not then the config file will be in the root of your mod's folder next to its SWInfo manifest. The game stores `CampaignConfig` values in the save of each campaign.