Caching and invalidation

Running every patch against every asset takes time, so PatchManager does not do it on every launch. It caches the patched output and reuses it until something that would change the result changes. Understanding what counts as "something changed" explains why an edit sometimes does not show up until you force a rebuild.

What is cached

PatchManager caches the final patched assets: the JSON after all patches in all passes have run. It keeps a separate cache for each feature set that it patches for, because two sets run different patches and load different content. The main menu has its own set, and each campaign has its own set. At a launch or a campaign load, if nothing that applies to the set has changed, PatchManager loads the cached output of the set. It does not run your patches again. This is invisible when it works and confusing when it does not, which is the reason this page exists.

Inspecting the cache to see the final result

The cache is not just an optimization, it is the single most useful debugging artifact PatchManager produces. It lives in a folder called pm_cache in the game's working directory, next to pm_summary.log, and it contains the exact final state of every patched asset. The summary tells you what happened. The cache shows you the result: the asset as the game loads it, after all patches from all mods in that set have run.

Inside pm_cache you will find:

  • sets/: one folder for each feature set. The id of the set is the name of the folder. Each folder contains these files:

    • inventory.json.

    • summary.log: the section of the summary for that set. It starts with the features of the set.

    • patches.log: the patch part of the last rebuild of the set.

  • archives/: one .zip for each patched label. The name of an archive is a hash of its contents. Sets that have an identical result for a label share one archive.

  • prefabs/: the resolved prefab patch plans.

To find the archive for a label, do these steps:

  1. Open the summary.log in each folder under sets/.

  2. Find the set whose features agree with the campaign that you examine.

  3. Open the inventory.json of that set. It lists each patched label, the archive that contains the label, and the assets in the label.

  4. Find the entry for your label. For example, parts are under the parts_data label. The parts_data entry gives the archive in archives/ that contains the patched parts for that set.

The zip contains one file for each asset. The name of each file is the id of the asset. Each file contains the final patched JSON of the asset. For example, the parts_data archive contains one entry for each part in that set. The name of the entry is the part id, and the entry contains the part data after all patches.

This gives you two things that are hard to get any other way.

Checking the final state of your patches. Open the archive for the label you patched, find your asset's entry, and read the JSON. That is ground truth. It reflects your change and everything every other mod did to the same asset, in final form. It is the most direct way to confirm a value actually landed and was not overwritten by a later patch, which is the one thing the summary cannot show you (the summary says your patch APPLIED, but not what the value ended up as after the patches that ran after yours).

Finding the ids of other assets. The entry names in an archive are the asset ids. When you need the exact id of a part to put in :Named, open the parts_data archive and read the names of the entries. This is a reliable, complete list of real ids, which beats guessing or hunting through game files. Look in a set that has the content you need. For example, a set without Ksp2Redux:Parts has no stock parts.

Two caveats. The cache shows the most recent build of that set. If the cache was served and not rebuilt (see below), it shows the last built state, which can be older than your newest edits. Force a rebuild to refresh it. Also, the JSON in the archive can be minified. To make it easier to read, turn on Indent Patched JSON in the Patch Manager settings, or use a JSON formatter.

What triggers a rebuild

A feature set never uses the cache of a different set. For one set, PatchManager rebuilds when one of these items changes:

  • The patch files of the mods in the set. PatchManager makes a hash of each .lua file of each mod whose default feature is in the set, and of the Redux .lua files. When you edit a patch and launch again, the hash changes and PatchManager rebuilds. A change to a mod that is not in the set does not change the cache of that set.

  • The mods in the set. The swinfo.json of each mod is part of the key of the set. When you install, update or remove a mod that is in the set, PatchManager rebuilds the set.

  • The game or Patch Manager version.

If none of these changed, the cache is reused, and patches do not run.

The cache does not monitor config values. When your patches read a setting, the cache of a set keeps the value that the set was built with. A change to the setting does not cause a rebuild. If a player must be able to turn content on or off, put the content in a feature. Each feature set has its own cache. See Config integration.

To force a rebuild, do one of these:

  • Delete the pm_cache folder.

  • Turn on Always Invalidate Patch Manager Cache under Advanced in the Patch Manager settings, then restart the game.

When that setting is on, PatchManager rebuilds each set the first time it patches for that set in a session. In the Unity editor, it always does this.

How many sets are kept

PatchManager keeps the set caches that it will possibly use again:

  • It always keeps the starting set of each campaign pack.

  • It always keeps the set of each single-player save.

  • It keeps a maximum of 10 other sets. When it adds a set, it deletes the least recently used set. It also deletes each archive that no remaining set uses.

When a change is not showing up

If you changed something and the game does not reflect it, the cache is the first suspect:

  • Edited a patch file but see no change: confirm you saved the file. A saved edit changes the hash and rebuilds.

  • Changed a setting but see no change: a setting never causes a cache rebuild. If the setting controls the output of your patches, use a feature instead.

  • Looking at the wrong set: the change is in the cache of the set that you loaded. Examine the summary.log in the correct folder in sets/, or the section of pm_summary.log that has the active mark.

  • Still stale: the summary reflects the most recent run. If it does not show your patch, the cache was served rather than rebuilt.

  • If all else fails: Delete pm_cache and it will be rebuilt on the next run