cheese3660 Posted December 11, 2023 Share Posted December 11, 2023 (edited) Patch Manager A mod for all your generic patching needs! Spacedock: https://spacedock.info/mod/3482/Patch Manager Github: https://github.com/KSP2Community/PatchManager Author: KSP2 Community Description Patch Manager is a mod for KSP2 that functions as a sort of spiritual successor to Module Manager for KSP1, its purpose is to allow for the patching of existing JSON definitions for anything that exists in the KSP2 Addressables files (this includes Parts/Galaxies/Planets/Tech/Resources/Etc...), along with the creation thereof. It does this by allowing the user to write patches and patch libraries in a custom syntax derived loosely off of SCSS, a lot of the functioning of which is documented in the reference for the language. How to Make Patches The best place to learn how to make patches is by asking people in the: KSP2 Modding Society Discord Server Other places to learn are the aforementioned reference (which will be being updated to add more information) Or by looking at how it is used in other mods (all examples are licensed under MIT): Community Resources by KSP2 Community (Patches: https://github.com/KSP2Community/CommunityResources/tree/main/plugin_template/patches, Libraries: https://github.com/KSP2Community/CommunityResources/tree/main/plugin_template/libraries) Orbital Survey by @Falki(Patch to add the module to all antennae: https://github.com/Falki-git/OrbitalSurvey/blob/master/plugin_template/patches/OrbitalSurvey_module.patch) Kerbal Life Support System by @Safarte (Patches: https://github.com/Safarte/KerbalLifeSupportSystem/tree/main/plugin_template/patches, Libraries: https://github.com/Safarte/KerbalLifeSupportSystem/blob/main/plugin_template/libraries/_constants.patch) Dependencies SpaceWarp (0.1.5.0 or later) Premonition For SpaceWarp (0.2.0 or later) Edited January 15 by cheese3660 bump version Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted December 13, 2023 Author Share Posted December 13, 2023 The new location for the documentation for this mod will be: https://pm.kerbal.wiki, still somewhat WIP, but should be much better than the GitHub wiki. Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted December 19, 2023 Author Share Posted December 19, 2023 Patch Manager v0.5.0 Adds the new stage system, config system, and tech tree patching. **Full Changelog**: https://github.com/KSP2Community/PatchManager/compare/v0.4.0...v0.5.0 Docs will be updated tomorrow, but to use the new tech tree stuff, use the `:tech` ruleset Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted December 21, 2023 Author Share Posted December 21, 2023 Patch Manager v0.6.0 Updates tech tree stuff to allow for node deletion Adds support for missions Adds support for experiments **Full Changelog**: https://github.com/KSP2Community/PatchManager/compare/v0.5.0...v0.6.0 Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted December 24, 2023 Author Share Posted December 24, 2023 V 0.6.1 Fix bug related to tech node deletion Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted December 26, 2023 Author Share Posted December 26, 2023 Patch Manager 0.7.0 ## What's Changed - Unquoted Strings - List Subtraction - Standalone patches (hopefully) ## Breaking changes - Prefix expressions have been removed and replaced with mutating definitions, instead of `: +[` do ` +: [` **Full Changelog**: https://github.com/KSP2Community/PatchManager/compare/v0.6.1...v0.7.0 Quote Link to comment Share on other sites More sharing options...
munix Posted December 26, 2023 Share Posted December 26, 2023 Patch Manager v0.7.1 This is a hotfix for a bug that occurs when rebuilding cache. Quote Link to comment Share on other sites More sharing options...
shoe7ess Posted December 29, 2023 Share Posted December 29, 2023 Hey, thank you for the mod! I've been working on my own .patch files and learning the syntax based on the wiki. I can make the part changes I'd like pretty easily, however I'm trying to convert a .konfig file over to a .patch file since I was told Konfig was being/already is deprecated. Could I get some help translating the Mun Rotation (and preferably a Custom Skybox) .konfig scripts over to .patch files? I honestly don't know where to start since I've only just started getting use to this language, but I can't quite wrap my mind around how to make it work. The black skybox and .konfig show that they should work on 0.2, but nothing loads (and I only get on kpatcher line in my log files, and it's a ton of errors). If anyone could help, the .konfig codes are: Mun Rotation Konfig: [Target(Mun)] [Module(CelestialBodyComponent)] [Data(CelestialBodyProperties)] Data.rotationPeriod = 800; Data.rotates = true; Data.isTidallyLocked = false; Module.SetDefinition(Data); Custom Skybox Konfig: [Target(Black)] [Module(Skybox)] [Data(int)] Data = 1024; Thanks for the hard work on this mod. I'll continue to attempt to create the .patch files for the above in the meantime. If I come across a solution I'll update as needed. Quote Link to comment Share on other sites More sharing options...
munix Posted December 29, 2023 Share Posted December 29, 2023 (edited) 3 hours ago, shoe7ess said: Hey, thank you for the mod! I've been working on my own .patch files and learning the syntax based on the wiki. I can make the part changes I'd like pretty easily, however I'm trying to convert a .konfig file over to a .patch file since I was told Konfig was being/already is deprecated. Could I get some help translating the Mun Rotation (and preferably a Custom Skybox) .konfig scripts over to .patch files? I honestly don't know where to start since I've only just started getting use to this language, but I can't quite wrap my mind around how to make it work. The black skybox and .konfig show that they should work on 0.2, but nothing loads (and I only get on kpatcher line in my log files, and it's a ton of errors). If anyone could help, the .konfig codes are: Mun Rotation Konfig: [Target(Mun)] [Module(CelestialBodyComponent)] [Data(CelestialBodyProperties)] Data.rotationPeriod = 800; Data.rotates = true; Data.isTidallyLocked = false; Module.SetDefinition(Data); Custom Skybox Konfig: [Target(Black)] [Module(Skybox)] [Data(int)] Data = 1024; Thanks for the hard work on this mod. I'll continue to attempt to create the .patch files for the above in the meantime. If I come across a solution I'll update as needed. For the first one, it should be something like this: @patch celestial_bodies; :json celestial_bodies > data { @if $$bodyName == "Mun" { rotationPeriod: 800; isTidallyLocked: false; } } I tested only briefly, but it seems to work. For the second one, there's no direct replacement, since Patch Manager can only edit or create JSON files (which the games uses for the definitions of parts, planets, science, and things like that), but the skybox is just a texture, and Konfig seems to have included a lot of custom code to get that to work, so the next best thing would be to take the C# code from Konfig's source and use it to put together your own mod that replaces the skybox textures similarly to how it did. Edited December 30, 2023 by munix Quote Link to comment Share on other sites More sharing options...
shoe7ess Posted December 29, 2023 Share Posted December 29, 2023 (edited) Spoiler For the first one, it should be something like this: @patch celestial_bodies; :json celestial_bodies > data { @if $$bodyName == "Mun" { rotationPeriod: 800; isTidallyLocked: false; } } I tested only briefly, but it seems to work. For the second one, there's no directly replacement, since Patch Manager can only edit or create JSON files (which the games for the definitions of parts, planets, science, and things like that), but the skybox is just a texture, and Konfig seems to have included a lot of custom code to get that to work, so the next best thing would be to take the C# code from Konfig's source and use it to put together your own mod that replaces the skybox textures similarly to how it did. You are awesome. I was actually on the right (well, I thought maybe it had to be editing .json data), but thank you for saving me the time on that! I may make that my first C# project (never programmed with that language before and, although the stock one is quite beautiful, the one I made from Space Engine would be gorgeous). However, I've worked on a part patch for about 3 hours of troubleshooting and is just not taking. I'm attempting to increase the ejection impulse of the radial decouplers in the game. Originally I wanted to just multiply the values by 10 but was running into too many errors I didn't understand in the log so I eventually just landed on a flat "5000" kN for each part. However, no matter how hard I try, I can't get it working. I have tried the following different methods: Spoiler :parts #decoupler_1v_radial { > Module_Decoupler { ejectionForce: 5000 EjectionImpulse: 5000 } } :parts #decoupler_1v_radial { @merge { ejectionForce: 5000 EjectionImpulse: 5000 }; } :parts #decoupler_1v_radial { ejectionForce: 5000 EjectionImpulse: 5000 } I have attempted with and without the "EjectionImpulse" line and receive no errors in the log, but they still have default impulse values... Edited December 30, 2023 by shoe7ess Quote Link to comment Share on other sites More sharing options...
munix Posted December 30, 2023 Share Posted December 30, 2023 (edited) 58 minutes ago, shoe7ess said: You are awesome. I was actually on the right (well, I thought maybe it had to be editing .json data), but thank you for saving me the time on that! I may make that my first C# project (never programmed with that language before and, although the stock one is quite beautiful, the one I made from Space Engine would be gorgeous). However, I've worked on a part patch for about 3 hours of troubleshooting and is just not taking. I'm attempting to increase the ejection impulse of the radial decouplers in the game. Originally I wanted to just multiply the values by 10 but was running into too many errors I didn't understand in the log so I eventually just landed on a flat "5000" kN for each part. However, no matter how hard I try, I can't get it working. I have tried the following different methods: Hide contents :parts #decoupler_1v_radial { > Module_Decoupler { ejectionForce: 5000 EjectionImpulse: 5000 } } :parts #decoupler_1v_radial { @merge { ejectionForce: 5000 EjectionImpulse: 5000 }; } :parts #decoupler_1v_radial { ejectionForce: 5000 EjectionImpulse: 5000 } I have attempted with and without the "EjectionImpulse" line and receive no errors in the log, but they still have default impulse values... You got pretty close, the main differences are that you need semicolons after the assignments, and it's actually Module_Decouple without the "r" at the end. To access the data inside a module, you need to go a level deeper into Data_Decouple. Also, I don't think the impulse needs to be patched here. Here it is: Spoiler :parts #decoupler_1v_radial { * > Module_Decouple > Data_Decouple { ejectionForce *: 10; } } And if you wanted to do it for all radial decouplers at once (also showing the shorter version of the selector): :parts #decoupler_??_radial > Module_Decoupler > Data_Decouple { ejectionForce *: 10; } Edited December 30, 2023 by munix Quote Link to comment Share on other sites More sharing options...
munix Posted December 30, 2023 Share Posted December 30, 2023 Patch Manager v0.7.2 This is a hotfix for the CoreModule.CurrentUniverse API property, making it static. Quote Link to comment Share on other sites More sharing options...
shoe7ess Posted December 30, 2023 Share Posted December 30, 2023 1 hour ago, munix said: You got pretty close, the main differences are that you need semicolons after the assignments, and it's actually Module_Decouple without the "r" at the end. To access the data inside a module, you need to go a level deeper into Data_Decouple. Also, I don't think the impulse needs to be patched here. Here it is: Hide contents :parts #decoupler_1v_radial { * > Module_Decouple > Data_Decouple { ejectionForce *: 10; } } And if you wanted to do it for all radial decouplers at once (also showing the shorter version of the selector): :parts #decoupler_??_radial > Module_Decoupler > Data_Decouple { ejectionForce *: 10; } Man, you are awesome. Thanks for the info, I'm glad I wasn't too far off. I could plow MM like a boss back in the day and I can't wait to reach the same point with PM Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted December 30, 2023 Author Share Posted December 30, 2023 2 hours ago, munix said: To access the data inside a module, you need to go a level deeper into Data_Decouple. The reason I didnt shorten this for reference, is that there are modules (usually ones derived from others) that can have multiple data types Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted December 30, 2023 Author Share Posted December 30, 2023 Patch Manager v0.7.3 This is a hotfix that enables list subtraction in `-:` statements Quote Link to comment Share on other sites More sharing options...
Cave_Lupum Posted January 1 Share Posted January 1 Happy new year and I am thrilled to have a way of patching KSP2 thanks to your mod and also apologize, if my questions sound a bit simple, this due to me being exactly that. Used to create simple patches in KSP1 using Modul Manager, but I am stuck a bit with Patch Manager on KSP2 now. #1 Looking for a reference on what fields exist for parts/resources, e.g. your patch "rover_0v_wheel" in the wiki uses field "mass". How would I know that the field "mass" exists at all? (Though got a slight suspicion these fields are still the same as they where in KSP1, right?) #2 Especially trying to increase ElectricCharge for batteries and don't seem to get the hang of how to patch resources. Thanks again for your work and I am in no hurry please! Quote Link to comment Share on other sites More sharing options...
munix Posted January 1 Share Posted January 1 16 minutes ago, Cave_Lupum said: Happy new year and I am thrilled to have a way of patching KSP2 thanks to your mod and also apologize, if my questions sound a bit simple, this due to me being exactly that. Used to create simple patches in KSP1 using Modul Manager, but I am stuck a bit with Patch Manager on KSP2 now. #1 Looking for a reference on what fields exist for parts/resources, e.g. your patch "rover_0v_wheel" in the wiki uses field "mass". How would I know that the field "mass" exists at all? (Though got a slight suspicion these fields are still the same as they where in KSP1, right?) #2 Especially trying to increase ElectricCharge for batteries and don't seem to get the hang of how to patch resources. Thanks again for your work and I am in no hurry please! Definitely not bad questions! To see the stock parts and their fields, you can use the small TextAssetDumper plugin (it's also on CKAN), which adds a "DUMP" button to the main menu, and after clicking that, in the plugin's folder you'll find dump/text_assets/parts_data, and inside it you'll see the JSON definition files for all parts. For the second question, it should look like this, it's a bit different from what the wiki tells you, it needs to be updated: :parts #storage_??_battery* { * > resourceContainers { * > .ElectricCharge { capacityUnits *: 100; initialUnits *: 100; } } } Quote Link to comment Share on other sites More sharing options...
Cave_Lupum Posted January 1 Share Posted January 1 1 hour ago, munix said: Definitely not bad questions! To see the stock parts and their fields, you can use the small TextAssetDumper plugin (it's also on CKAN), which adds a "DUMP" button to the main menu, and after clicking that, in the plugin's folder you'll find dump/text_assets/parts_data, and inside it you'll see the JSON definition files for all parts. For the second question, it should look like this, it's a bit different from what the wiki tells you, it needs to be updated: :parts #storage_??_battery* { * > resourceContainers { * > .ElectricCharge { capacityUnits *: 100; initialUnits *: 100; } } } Thanks so much for your quick reply, much appreciated! Already managed to pull the mentioned dump and I am comforted a bit, that it was no wonder I wasn't able to deduct the correct use of the :resource RuleSet . Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted January 2 Author Share Posted January 2 Patch Manager v0.8.0 This update adds support for string interpolation, done via `#{...}` inside of a quoted string. It also adds support for `@each`/`@for`/`@while` loops inside of selection blocks. 6 hours ago, munix said: For the second question, it should look like this, it's a bit different from what the wiki tells you, it needs to be updated: Wiki has been updated Quote Link to comment Share on other sites More sharing options...
Superfluous J Posted January 2 Share Posted January 2 (edited) I've not been able to find references for editing things that aren't parts or resources. I see there's a generic "json" option but no one seems to have used it yet so I can't just steal copy and modify their code for my own use. I'm trying to affect the axial tilt of planets and moons. I used the Text Asset Dumper mod (which is fantastic) and with it, I have the file for - say - Mun. In there is this code (extra stuff stripped): { "version": "0.3", "useExternal": false, "data": { "bodyName": "Mun", ... "axialTilt": { "x": 0.0, "y": 0.0, "z": 0.0 }, ... } } I've tried everything I can think of, basically at random because I have no idea what I'm doing. The most recent patch file that failed is: :json #mun > data { @set { axialTilt: { x: 30.0, y: 0.0, z: 0.0 } }; } I've tried with quotes around those strings. I've tried putting "data" as a section below "@set" containing "axialTilt" (with and without quotes around the strings), without that semicolon, and with the semicolon elsewhere... I'm trying to mimic what I see people doing with parts, but it's just not working out for me. Could someone tell me the 8-10 things I'm doing wrong, and how to do them correctly so I can finally get to creating my "Kerbolar System As I See It" patch? Edited January 2 by Superfluous J Quote Link to comment Share on other sites More sharing options...
munix Posted January 2 Share Posted January 2 (edited) 15 minutes ago, Superfluous J said: I've tried everything I can think of, basically at random because I have no idea what I'm doing. The most recent patch file that failed is: :json #mun > data { @set { axialTilt: { x: 30.0, y: 0.0, z: 0.0 } }; } I've tried with quotes around those strings. I've tried putting "data" as a section below "@set" containing "axialTilt" (with and without quotes around the strings), without that semicolon, and with the semicolon elsewhere... I'm trying to mimic what I see people doing with parts, but it's just not working out for me. Could someone tell me the 8-10 things I'm doing wrong, and how to do them correctly so I can finally get to creating my "Kerbolar System As I See It" patch? You can use the patch in this post as inspiration: The most important part is to first use the @patch directive. It's needed when using the generic json ruleset, so that we don't have to try to patch every single label that exists in the game. And the other thing is that you can only really use the #name syntax with the specialized rulesets, because the generic json one doesn't know where to find the name of a general JSON asset, so you have to get around it by using a condition. I think those two changes should be enough to get your patch working. Edit: Oh and you shouldn't need to use @set for this, since that would replace the contents of the whole file with just the axial tilt. Edited January 2 by munix Quote Link to comment Share on other sites More sharing options...
Superfluous J Posted January 2 Share Posted January 2 44 minutes ago, munix said: You can use the patch in this post as inspiration LOL I seem to have checked everywhere but this thread Thanks a ton! Quote Link to comment Share on other sites More sharing options...
Superfluous J Posted January 2 Share Posted January 2 Again, thank you. I am getting all a'tilty over here. However I've hit another snag. SOME world properties are stored in their own json files, but orbital parameters (most importantly for me right now is inclination) are stored in the file GalaxyDefinition_Default which is a json file but was not given the extension json (or any extension) by the Text Asset Dumper. In it for - say - Minmus we have this: { "Name": "Default", "Version": "0.0.1", "CelestialBodies": [ ... { "GUID": "Minmus", "PrefabKey": "Celestial.Minmus.Simulation", "OrbitProperties": { "referenceBodyGuid": "Kerbin", "inclination": "6", "eccentricity": "0", "semiMajorAxis": "47000000", "longitudeOfAscendingNode": "78", "argumentOfPeriapsis": "38", "meanAnomalyAtEpoch": "0.9", "epoch": "0" }, ... }, ] } ...and I'm not sure how to define that in my file. I tried a couple things before giving up. The one I felt the most confident of was just adding it to the main :json celestial_bodies > data { ... @if $$bodyName == "Minmus" { axialTilt: { x: -23.0, y: 0.0, z: 0.0 }; inclination: -23; } @if $$GUID == "Minmus" { inclination: -23; } ... } I get why it doesn't work (or at least I think I do). There is no "data" in the GalaxyDefinition_Default file. I don't know how to fix it, though, in my file to reference that one. I tried to reverse engineer what I already have, but the first line ":json celestial_bodies > data {", I don't know how I'd have found out "celestial_bodies" on my own, so don't know how to figure out what I'd need to use to locate Minmus' inclination in the GalaxyDefinition_Default file. Quote Link to comment Share on other sites More sharing options...
cheese3660 Posted January 2 Author Share Posted January 2 As for the GalaxyDefinition_Default stuff, this is what a WIP mod I'm working on, Shoemaker, is meant to address, but thats a bit out from release, as I have to figure out some stuff about scaling planets still. Shoemaker will be an addon for PM meant specifically for planet modding. Quote Link to comment Share on other sites More sharing options...
munix Posted January 2 Share Posted January 2 (edited) 8 hours ago, Superfluous J said: Again, thank you. I am getting all a'tilty over here. However I've hit another snag. SOME world properties are stored in their own json files, but orbital parameters (most importantly for me right now is inclination) are stored in the file GalaxyDefinition_Default which is a json file but was not given the extension json (or any extension) by the Text Asset Dumper. The way the addressables system works is that assets are assigned labels, a single asset can have multiple labels (for example, parts have a label of their own name, but all of them also have "parts_data", that way the game can load all parts at once, included ones from mods - they just have to be labeled with "parts_data"). What TextAssetDumper does is that inside TextAssetDumper/dump/text_assets, it creates a folder for every addressable label that contains text assets (which are usually JSON files, even if without an extension). So, if you want to find all the celestial bodies, you can look inside the "celestial_bodies" folder, since that's the common label for them, and that's also what the Patch Manager patch needs to target. Similarly, you can find a folder called GalaxyDefinition_Default in there, which contains the definition of the galaxy, and the orbital parameters of all the celestial bodies in it. So, you'll need to write a patch that specifically targets that label. And to do that, you need to use a @patch statement to tell Patch Manager to include that label: @patch GalaxyDefiniton_Default; Now Patch Manager will include this this label when patching assets. This specific patch is a bit more complicated, because all variables/fields are considered immutable, so you can't just edit some nested value, instead you have to redefine them with a new object. The best way to "edit" an array like CelestialBodies is to use the "map" function from the "builtin:list" library, which is called on all the elements of the array and then returns a new modified version of the array. You can define a closure to pass to the "map" function, like I do with $inclineMinmus in the example below. There we check if the current element has the GUID of Minmus, and if it does, we use another function, "set" from "builtin:dictionary", to replace the values of the object. The inner "set" creates a copy of the OrbitProperties object with the "inclination" field's value set to 45. Then, that copied and modified object is used to create a copy of the "$body" variable, now with its OrbitProperties field set to the previously created object. Passing $inclineMinmus to $value:map(...) will return the CelestialBodies array with Minmus's inclination modified to 45. And last, we use @set to replace the entire value of CelestialBodies with the result of the "map" function. @use 'builtin:list'; @use 'builtin:dictionary'; @patch 'GalaxyDefinition_Default'; $inclineMinmus: @function($body) { @if $body['GUID'] == 'Minmus' { $body: $body:set( 'OrbitProperties', $body['OrbitProperties']:set( 'inclination', 45.0 ) ); } @return $body; }; :json GalaxyDefinition_Default { * > CelestialBodies { @set $value:map($inclineMinmus); } } But yeah, as Cheese said, this is just a temporary solution, she is working on a better one. Edited January 2 by munix Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.