RELEASED Content Patcher *

Loads content packs that change the game's images and data without replacing XNB files.

Thread Status:
Not open for further replies.
  1. Pathoschild

    Pathoschild Cosmos Killer

    Content Patcher 1.8 is now available!

    Release notes:
    • Added new tokens:
      • IsOutdoors: whether the player is outdoors.
      • LocationName: the name of the player's current location.
      • Target: the target field value for the current patch.
      • TargetWithoutPath: the target field value for the current patch (only the part after the last path separator).
    • Added map patching.
    • Added support for list assets in the upcoming Stardew Valley 1.4.
    • Improved errors when token parsing fails.
    • Fixed patches not applied in some cases.
    • Fixed incorrect error message when Default and AllowValues conflict.
    • Fixed confusing errors when a content pack is broken and using an old format version.
    Thanks to @spacechase0 for contributions to support the new tokens!
     
      hatmouse likes this.
    • pepoluan

      pepoluan Big Damn Hero

      Oooohhh, the "Map Patching" feature sounds great! Now I can mix-and-match changes to a map!

      Also, the IsOutdoors token would be a great boon in CP-fying mods that customize villagers' appearance according to season and in-/out-door position!

      ETA: I've updated my "Clean & Block" mod to use the "EditMap" action. Seems to work well so far. Great job @Pathoschild !
       
        Last edited: May 17, 2019
      • pepoluan

        pepoluan Big Damn Hero

        I have a question: Is there a case where the dimension of the FromArea is different from the dimension of the ToArea? Example:

        Code:
          "FromArea": { "X":0, "Y": 0, "Width": 64, "Height": 64 },
          "ToArea": { "X": 128, "Y": 64, "Width": 32, "Height": 32}
        
        If there's no foreseeable need for such "rescaling", maybe we can make the "ToArea" simpler; probably add a "ToCoord" parameter instead? Or maybe allowing the "Width" and "Height" keys to be omitted in the "ToArea" arg?

        Because to the best of my knowledge, even though the "X" and "Y" might differ, the "Width" and "Height" are always the same because people want to do a 1:1 replacement.
         
        • pepoluan

          pepoluan Big Damn Hero

          Yesterday, I had just spent a goodly amount of time converting an XNB mod into a CP version of.

          The catch: The sprites in the PNG of the XNB mod does not map with the sprites in SDV 1.3's XNB.

          So, I'm forced to do 2 "EditImage" actions to map the PNG of the mod onto the PNG of the game's original.

          Then I discovered another XNB mod from the modder that replaces just parts of the game's original... on 14 areas (each "area" are rectangular shaped, but the total of the 14 areas does not make a rectangular shape). I am thus forced to create 14 "EditImage" actions, each containing a pair of "FromArea" and "ToArea" pairs.

          That made me think:

          It would be nice if we can have something like "MultiAreas" ability in the next version of CP.

          Let me illustrate:

          This is a portion of the converted mod:
          Code:
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 0, "Y": 0, "Width": 64, "Height": 112 },
                      "ToArea": { "X": 0, "Y": 0, "Width": 64, "Height": 112 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 0, "Y": 0, "Width": 64, "Height": 112 },
                      "ToArea": { "X": 0, "Y": 0, "Width": 64, "Height": 112 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 64, "Y": 16, "Width": 16, "Height": 96 },
                      "ToArea": { "X": 64, "Y": 16, "Width": 16, "Height": 96 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 64, "Y": 16, "Width": 16, "Height": 96 },
                      "ToArea": { "X": 64, "Y": 16, "Width": 16, "Height": 96 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 96, "Y": 0, "Width": 96, "Height": 16 },
                      "ToArea": { "X": 96, "Y": 0, "Width": 96, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 96, "Y": 0, "Width": 96, "Height": 16 },
                      "ToArea": { "X": 96, "Y": 0, "Width": 96, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 144, "Y": 16, "Width": 16, "Height": 16 },
                      "ToArea": { "X": 144, "Y": 16, "Width": 16, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 144, "Y": 16, "Width": 16, "Height": 16 },
                      "ToArea": { "X": 144, "Y": 16, "Width": 16, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 176, "Y": 16, "Width": 16, "Height": 16 },
                      "ToArea": { "X": 176, "Y": 16, "Width": 16, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 176, "Y": 16, "Width": 16, "Height": 16 },
                      "ToArea": { "X": 176, "Y": 16, "Width": 16, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 240, "Y": 0, "Width": 32, "Height": 16 },
                      "ToArea": { "X": 240, "Y": 0, "Width": 32, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 240, "Y": 0, "Width": 32, "Height": 16 },
                      "ToArea": { "X": 240, "Y": 0, "Width": 32, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 304, "Y": 0, "Width": 16, "Height": 16 },
                      "ToArea": { "X": 304, "Y": 0, "Width": 16, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 304, "Y": 0, "Width": 16, "Height": 16 },
                      "ToArea": { "X": 304, "Y": 0, "Width": 16, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 80, "Y": 80, "Width": 48, "Height": 16 },
                      "ToArea": { "X": 80, "Y": 80, "Width": 48, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 80, "Y": 80, "Width": 48, "Height": 16 },
                      "ToArea": { "X": 80, "Y": 80, "Width": 48, "Height": 16 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 0, "Y": 160, "Width": 64, "Height": 80 },
                      "ToArea": { "X": 0, "Y": 160, "Width": 64, "Height": 80 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 0, "Y": 160, "Width": 64, "Height": 80 },
                      "ToArea": { "X": 0, "Y": 160, "Width": 64, "Height": 80 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 64, "Y": 160, "Width": 32, "Height": 64 },
                      "ToArea": { "X": 64, "Y": 160, "Width": 32, "Height": 64 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 64, "Y": 160, "Width": 32, "Height": 64 },
                      "ToArea": { "X": 64, "Y": 160, "Width": 32, "Height": 64 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 96, "Y": 176, "Width": 32, "Height": 64 },
                      "ToArea": { "X": 96, "Y": 176, "Width": 32, "Height": 64 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 96, "Y": 176, "Width": 32, "Height": 64 },
                      "ToArea": { "X": 96, "Y": 176, "Width": 32, "Height": 64 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 416, "Y": 320, "Width": 32, "Height": 80 },
                      "ToArea": { "X": 416, "Y": 320, "Width": 32, "Height": 80 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 416, "Y": 320, "Width": 32, "Height": 80 },
                      "ToArea": { "X": 416, "Y": 320, "Width": 32, "Height": 80 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 48, "Y": 368, "Width": 48, "Height": 80 },
                      "ToArea": { "X": 48, "Y": 368, "Width": 48, "Height": 80 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 48, "Y": 368, "Width": 48, "Height": 80 },
                      "ToArea": { "X": 48, "Y": 368, "Width": 48, "Height": 80 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 128, "Y": 1056, "Width": 32, "Height": 32 },
                      "ToArea": { "X": 128, "Y": 1056, "Width": 32, "Height": 32 },
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "FromArea": { "X": 128, "Y": 1056, "Width": 32, "Height": 32 },
                      "ToArea": { "X": 128, "Y": 1056, "Width": 32, "Height": 32 },
                      "When": { "town_interior": "dark_chocolate" }
                  }
          
          The envisioned "MultiArea" feature can reduce that nightmare to this:
          Code:
                  {
                      "Action": "EditImage",
                      "Target": "townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "MultiAreas": [
                          { "FromX": 0, "FromY": 0, "Width": 64, "Height": 112 },
                          { "FromX": 64, "FromY": 16, "Width": 16, "Height": 96 },
                          { "FromX": 96, "FromY": 0, "Width": 96, "Height": 16 },
                          { "FromX": 144, "FromY": 16, "Width": 16, "Height": 16 },
                          { "FromX": 176, "FromY": 16, "Width": 16, "Height": 16 },
                          { "FromX": 240, "FromY": 0, "Width": 32, "Height": 16 },
                          { "FromX": 304, "FromY": 0, "Width": 16, "Height": 16 },
                          { "FromX": 80, "FromY": 80, "Width": 48, "Height": 16 },
                          { "FromX": 0, "FromY": 160, "Width": 64, "Height": 80 },
                          { "FromX": 64, "FromY": 160, "Width": 32, "Height": 64 },
                          { "FromX": 96, "FromY": 176, "Width": 32, "Height": 64 },
                          { "FromX": 416, "FromY": 320, "Width": 32, "Height": 80 },
                          { "FromX": 48, "FromY": 1056, "Width": 48, "Height": 80 },
                          { "FromX": 128, "FromY": 1056, "Width": 32, "Height": 32 }
                      ],
                      "When": { "town_interior": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "Maps/townInterior",
                      "FromFile": "assets/townInteriorV1.png",
                      "MultiAreas": [
                          { "FromX": 0, "FromY": 0, "Width": 64, "Height": 112 },
                          { "FromX": 64, "FromY": 16, "Width": 16, "Height": 96 },
                          { "FromX": 96, "FromY": 0, "Width": 96, "Height": 16 },
                          { "FromX": 144, "FromY": 16, "Width": 16, "Height": 16 },
                          { "FromX": 176, "FromY": 16, "Width": 16, "Height": 16 },
                          { "FromX": 240, "FromY": 0, "Width": 32, "Height": 16 },
                          { "FromX": 304, "FromY": 0, "Width": 16, "Height": 16 },
                          { "FromX": 80, "FromY": 80, "Width": 48, "Height": 16 },
                          { "FromX": 0, "FromY": 160, "Width": 64, "Height": 80 },
                          { "FromX": 64, "FromY": 160, "Width": 32, "Height": 64 },
                          { "FromX": 96, "FromY": 176, "Width": 32, "Height": 64 },
                          { "FromX": 416, "FromY": 320, "Width": 32, "Height": 80 },
                          { "FromX": 48, "FromY": 1056, "Width": 48, "Height": 80 },
                          { "FromX": 128, "FromY": 1056, "Width": 32, "Height": 32 }
                      ],
                      "When": { "town_interior": "dark_chocolate" }
                  }
          


          Note that in the "MultiAreas" system example above, only "FromX" and "ToX" were specified; there is no "ToX" nor "ToY" because the (X,Y) coord of the target is the same as the (X,Y) coord of the source.

          If the target has different (X,Y) from the source, we can specify it explicitly for example:
          Code:
                  {
                      "Action": "EditImage",
                      "Target": "TileSheets/Craftables",
                      "FromFile": "assets/CraftablesHypothetical.png",
                      "FromArea": { "X": 0, "Y": 0, "Width": 128, "Height": 128 },
                      "When": { "craftables": "dark_chocolate" }
                  },
                  {
                      "Action": "EditImage",
                      "Target": "TileSheets/Craftables",
                      "FromFile": "assets/CraftablesHypothetical.png",
                      "FromArea": { "X": 0, "Y": 128, "Width": 128, "Height": 224 },
                      "ToArea": { "X": 0, "Y": 416, "Width": 128, "Height": 224 },
                      "When": { "craftables": "dark_chocolate" }
                  }
          
          Code:
                  {
                      "Action": "EditImage",
                      "Target": "TileSheets/Craftables",
                      "FromFile": "assets/CraftablesHypothetical.png",
                      "MultiAreas": [
                          { "FromX": 0, "FromY": 0, "Width": 128, "Height": 128 },
                          { "FromX": 0, "FromY": 128, "Width": 128, "Height": 224, "ToX": 0, "ToY": 416 }
                      ],
                      "When": { "craftables": "dark_chocolate" }
                  }
          


          I think modders can appreciate the "MultiAreas" feature as it can potentially greatly reduce the number of JSON lines that need to be typed into content.json, and/or reducing the number of PNG files need to be created if for each replacement area a new PNG file was created (to cater for non-contiguous and/or non-rectangular area).
           
          • Sabs like "labs"

            Sabs like "labs" Void-Bound Voyager

            For the most part I don't use sprite sheets for changes in CP mods because I've found they're heavier than having loose images... so I use loose files when creating CP mods. Out of curiosity, how would you handle this kind of multiple changes where individual sprite changes are being pulled from individual files rather than from a sprite sheet?
             
            • pepoluan

              pepoluan Big Damn Hero

              Well, I'm not the original modder, so I just convert an XNB mod into a CP one... and having to live with the problems that entailed.

              The "MultiAreas" feature of course has no impact if you actually replace sprites/tiles with one file per sprite/tile; you still have to specify an "EditImage" action per each "FromFile".

              So the "MultiAreas" feature is meant for modders who want to put all their replacement sprites for one particular Target into one big PNG file instead of a bunch of small PNG files. The "FromFile" needs not be the same size of the "Target" asset; that's the purpose of explicitly specifying the "FromX", "FromY", "Width", and "Height" values: So one FromFile can be carved every which way to be applied to various locations in the Target asset.

              Having one PNG (containing all the replacement sprites/tiles) instead of a bunch of PNG files has two advantages:
              1. A big PNG can be optimized -- size-wise -- much better than a bunch of small PNG files.
                (I use PNGcrush to make the final PNG files smaller -- sometimes by a wide margin!)

              2. If the modder decides to change a thing, say change the color being used into a different hue, or make the replacement sprites lighter/darker, etc. ... instead of having to open-edit-save a bunch of PNG files, they can do everything in one file.
                That of itself certainly has advantages, such as: Easier matching (of styles) between sprites, not forgetting to modify one file out of many because everything is self-contained, etc.
               
              • Pathoschild

                Pathoschild Cosmos Killer

                @pepoluan Thanks for the suggestions! There are a lot of changes in 1.7/1.8 and the upcoming 1.8.1, so I'm holding off on more changes for a while. I do want to improve those cases in a future version though. To keep things simple I wouldn't want a separate ToCoord field, but making the width/height fields optional is a definite possibility.

                A possible alternative to MultiAreas is the current "PatchMode": "Overlay" field, which lets you overlay the source spriteseheet onto the target while ignoring transparent areas in the source. That's especially useful for recolors, since the source/target align pixel-perfectly.
                 
                  pepoluan likes this.
                • pepoluan

                  pepoluan Big Damn Hero

                  Ahh, you're right! For the particular mod I'm converting. "Overlay" is definitely will cut it nicely. Thanks for reminding me!

                  I have seen some other mods, though, which were not mere recolor but actually changed the shape of the sprite, and when the new sprite is slimmer/smaller, that will cause glitches such as older textures "peeking through" when the PatchMode is set to Overlay. In this case I guess the mod maker/converter will have to resort to the "Replace" action.
                   
                  • babybird22

                    babybird22 Void-Bound Voyager

                    hi Pathoschild! Me again having some problems when creating the marriage mod...
                    I have created a Wizard Marriage Mod, which includes daily dialogues, marriage dialogues, heart event, new schedule, etc.
                    At this stage i started to test my mod, and got marriage with wizard
                    however, after the marriage ceremony i found that the game will crash when i went to sleep.
                    This buds will also make my other save crash even i have married with other NPC (e.g. Alex)

                    As I have spent couple of hours but fails to find any error in my mod... could you mind helping me to look at the SAMPI error log?
                    Also attach the marriage mod (chinese version only though) for your reference. Thank you so much.
                     
                      Last edited: May 26, 2019
                    • Pathoschild

                      Pathoschild Cosmos Killer

                      @babybird22 The main issue is "FormatException: 輸入字串格式不正確。 [...] 於 StardewValley.NPC.parseMasterSchedule(String rawData)", which means it can't parse a number in the Wizard's schedule file. It might be due to the double spaces here:
                      upload_2019-5-26_13-13-24.png
                      Since the fields are space delimited, the game will parse that as time=900, map=, x=WizardHouse and fail because WizardHouse isn't a number.
                       
                      • Pathoschild

                        Pathoschild Cosmos Killer

                        Content Patcher 1.8.1 is now available!

                        Release notes:
                        • Improved patch summary:
                          • now tracks the reason a patch wasn't loaded (instead of showing a heuristic guess);
                          • added more info for local tokens;
                          • simplified some output.
                        • Improved errors when a local file doesn't exist.
                        • Fixed patch update bugs in Content Patcher 1.8.
                         
                          pepoluan likes this.
                        • baby.bird22

                          baby.bird22 Orbital Explorer

                          this bud is fixed now! Thank you so much!!;)
                           
                          • Pathoschild

                            Pathoschild Cosmos Killer

                          • pepoluan

                            pepoluan Big Damn Hero

                            @Pathoschild , I'm just wondering: Is it possible to enlarge existing map by specifying a To coordinate that's outside of vanilla's tbin dimension?

                            So, let's say vanilla map is 30x8 (so, max coordinates would be (29, 7), can I enlarge by specifying To coordinate of, say (20,7) then patch in a 10x7 "expansion"?
                             
                            • Clotho

                              Clotho Subatomic Cosmonaut

                              uhhhhh so hi, i literally have no idea what i'm doing. i've spent like an hour trying to make a springobjects overlay file and i'm getting this.

                              [​IMG]


                              please tell my dumbass what i did wrong
                               
                              • Pathoschild

                                Pathoschild Cosmos Killer

                                @pepoluan Not yet, but I do want to add that in a future version.

                                @Clotho You have a JSON syntax error in your content.json file. You can use this JSON validator tool to highlight errors, and feel free to post the file here if you can't find it and I'll help.
                                 
                                  pepoluan and Clotho like this.
                                • Clotho

                                  Clotho Subatomic Cosmonaut

                                  Last edited: May 31, 2019
                                • LadyEleven

                                  LadyEleven Void-Bound Voyager

                                  Not the one who asked the question but THANKS FOR THAT LINK. That looks super handy-dandy!
                                   
                                  • pepoluan

                                    pepoluan Big Damn Hero

                                    @Pathoschild Ooh, I just got another idea for improvement!

                                    Load Order Specification.

                                    So we can explicitly specify whether one mod should be loaded only after/before another mod.

                                    Not sure how to implement this as metadata, though. Maybe within manifest.json as "LoadBefore" : [ list of mod uniqueIDs ] and "LoadAfter" : [ list of mod uniqueIDs ].

                                    Or maybe within CP's config.json itself: "LoadFirst" : [ mods to load first before everything else, in order specified ] and "LoadLast" : [ mods to load after everything else, in order specified ] . Other mods not in these two lists will be loaded in-between.

                                    (Sorry, for the string of ideas, pathoschild... I hope I don't come across as annoying...)
                                     
                                    • Pathoschild

                                      Pathoschild Cosmos Killer

                                      @pepoluan Suggestions are welcome! Content Patcher uses SMAPI's standard dependency feature for setting load order, which lets you load a mod after specified mods. To load a mod before another, you'd add it to the other mod's manifest as a dependency.
                                       
                                      Thread Status:
                                      Not open for further replies.

                                      Share This Page