Translating a Mod from TMXL ToolKit to Content Patcher

WIth tmxl toolkit (and its companion mod, PYTK) becoming increasing obsolete, some modders are moving away from wanting these frameworks. Sadly, a lot of older mods rely on these frameworks to load their locations, and as these are the ones more likely to be abandoned, players will be looking for unofficial updates that switch them across to using the versatile and well maintained Content Patcher framework.

Here is a step by step guide into switching a mod across from TMXL Toolkit to CP (and a few other dependencies, which will be explained below).

For this exercise you will need:

  1. An obsolete mod that adds at least one new location
  2. Content Patcher’s Guide on Github
  3. Visual Studio Code or some other mod editing program
  4. Tiled may be useful, if you are comfortable with opening and editing maps.

GETTING STARTED

Most mod packages will contain several folders. These are typically labelled as such:

Where [CP] denotes a Content Patcher folder and [TMX] a TMXLT folder.

Your first step should be to open the [TMX] folder and copy the assets folder into the [CP] folder. As these mostly contain Maps, I recommend creating a folder with an obvious name, so you end up with a Directory link of:

[CP] (Modname)/assets/Maps

Make sure when you transfer the maps, you also transfer all of the tilesheets and other relative parts. Dumping the whole folder across is probably the easiest way to go!

Now, in Visual Studio Code, open the content.json inside both folders side by side. We need to transfer the important information from the TMX content.json into the CP content.json.

LOCATIONS

In the TMXL file you will see various sections, each beginning with a different key, I will run through one by one what each means. The first is:

"addMaps": [
    {
      "name": "FairyPool",
      "file": "assets/FairyPool.tmx"
    }
  ],

addMaps is what TMXL uses to add a new location. ‘Location’ is the term given to a map within the game that is accessible by players and (potentially) NPCs, during active game play. This mod adds a Location called FairyPool.

Here’s the same Location added via Content Patcher:

"Format": "1.23.0",
"CustomLocations": [
   {
     "name": "Custom_LK_FairyPool",
     "FromMapFile": "assets/Maps/FairyPool.tmx"
        },
    ],
"Changes": [

Not that different is it? Note that the name of the map has now changed. This is because Content Patcher requires you to preface all custom maps with the words Custom_. This is for future proofing – what if the vanilla game also added a FairyPool location? It is also recommended to include the name of the mod, or in this case the creator, to avoid conflict with other mods that might also use the same name. This greater reduces the risk of your map conflicting with someone else’s.

The “CustomLocations” are best added FIRST in the content.json, just under the “Format” line, as seen here and they must be above “Changes” (which is where the bulk of your content adjustments will go). They cannot be added with conditions, or use dynamic tokens. Make sure your directory path is accurate.

Now note that with your changed map name, EVERY mention of the original map in the game MUST be changed to reflect this. If an NPC’s schedule takes them to the FairyPool map, this must now be changed to Custom_LK_FairyPool. If Data/Locations exist for the area, these too must be changed. Your warps must also be fixed, and we’ll get onto this next.

But, Congratulations, now your Location exists as a new Location in Content Patcher!

But how to access it?

Return to your TMXL content.json, and look for the following:

"mergeMaps": [
  {
    "name": "Woods",
    "file": "assets/Woods-Patch.tmx",
    "position": [0,5]
    }, 
  ],
"onlyWarps": [
  {
    "name": "Woods",
    "addWarps": [ "0 11 FairyPool 39 26 0 12 FairyPool 39 27"]
    },

This portion firstly adds a small map patch that opens up the entrance into the new area, then adds the warp (access point) to get there. To transfer these across to Content Patcher, we must now move into the “Changes”:[ part of the CP content.json

"Changes": [
  {
   "Action": "EditMap",
   "Target": "Maps/Woods",
//Adding in the Map patch
   "FromFile": "assets/Maps/Woods-Patch.tmx",
   "ToArea": {"X": 0,"Y": 5,
                "Width": 4,"Height": 13},
//Adding in the Warps
   "TextOperations": [
     {
       "Operation": "Append",
       "Target": [ "MapProperties", "Warp" ],
       "Value": "0 11 Custom_LK_FairyPool 39 25 0 12 Custom_LK_FairyPool 39 26",
       "Delimiter": " "
                }
            ]
        },

“Append” means “add this warp onto any existing warps”. It is used so that it will not overwrite any pre-existing warps (ie: those already built into the map) or any that are added via other mods. You should never entirely overwrite a vanilla map’s warps. This can break other mods, and cause serious issues. “Delimiter” refers to “what to put between this and any other properties that might be appended in”. The only parts you will need to edit here for your own maps are in bold in the image above:

  • Name of the map you are editing
  • Your FromFile Directory and map name
  • The X and Y coordinates (These are the top left hand corner, and can be copied directly from the TMX content.json)
  • The width and height of the map you are patching in. As TMXL content.json doesn’t worry about this, you may need to open the patch map in Tiled and count the tiles. If there are any Red Xs on the screen when you do this, make sure you close it without saving it. If you save it, it will break.
  • Your warp value. Copy this from the addWarps in the Content.json. Don’t forget to change the prefix!

Now you should be able to open your game and see if you can access the map. Keep an eye on the Smapi console for any error messages.

If there’s no errors, then GREAT! Now it’s time to find and adjust all instances of the map names in the mod and change them to the new Location name.

This includes:

  • NPC spawn points
  • NPC schedule points
  • Data/Locations
  • Data/Events/<locationName> will now become Data/Events/Custom_<locationName>
  • Warps between custom maps (if the map files are .tmx files, these can be opened and edited using VSC, if they are tbin files you will need to open them in Tiled and edit them that way).
If you miss any warps and try to pass through one, your screen will turn black and lock on the “loading” screen. The smapi console will spam red text, which most tellingly contains the words “FadetoBlack” and BellsAndWhistles”. This means the game is trying to access a map that doesn’t exist and you will need to exit and fix the warp. You cannot salvage your day and will need to restart.

MORE COMPLEX STUFF

IF you are set on removing TMXL toolkit and PYTK entirely from your game/mod, you may also need to adjust the following map features:

  • change any TouchAction LoadMap properties to TouchAction Warp – This is a farmer only warp and put in position to ensure circular routes are not created. (You just need to change the word “LoadMap” to “Warp” otherwise the code is identical). If you have an Action LoadMap warp, no equivalent exists – you’ll just have to change it to Action Warp and hope NPCs don’t use it (or block it off elsewhere).
  • Rename any additional layers to Back2, Buildings2 etc if they are not already called this and install the Mod Extra Map Layers. Because vanilla maps are limited to 4 layers (Back, Buildings, Front and AlwaysFront), many maps use pytk’s features to add extra layers
  • @LoadWater T can be replaced with indoorWater T (note the capitalization) – this adds water shimmer (and visible fish, if that mod is installed) to water indoors/in caves.
  • There is currently no equivalent or replacement for CropLayers. You’ll just have to remove them, or replace with Farm Type Manager or built in map patches.
  • Lua code can probably be added via Content Code but I am not experienced enough to do this.

SPOUSE ROOMS

Look for this piece of code in your [TMX] content.json

"spouseRooms": [
 {
   "name": "Aideen",
   "file": "assets/SpouseRoomAideen.tmx"
    }

In 1.5.5 update, the ability to add spouse rooms via CP was added. It is highly recommended that you DO NOT install any [TMX] Spouse Rooms EVEN if you decide to continue using TMXL toolkit. They are highly buggy and can cause issues with Free Love, Farmhouse walls and each other. If you do not intend to marry a specific custom NPC and its spouse room is added as a separate folder, do not install that folder.

Sadly, you DO need to edit the spouse rooms to make them work with Content Patcher’s set up, making this a more complicated process then above.

On the left is the [TMX] Spouse room, on the right is the [CP] Spouse room.

Differences to note:

  • The [CP] spouse room measures 6 x 9 tiles in size. (the [TMX] 7 x 10).
  • The [CP] spouse room does not contain an outer wall
  • The names of the layers on the [TMX] spouseroom have changed to the more generic standard map layer names.
  • AlwaysFront layer no longer exists.

Save your modified map into the same Maps folder as the other maps above (or elsewhere, it doesn’t really matter as long as you can find it again!

{
   "Action": "EditData",
   "Target": "Data/SpouseRooms",
   "Entries": {
     "Aideen": "Lemurkat_EastScarp_SpouseRoom/0"
               }
       },
{
   "Action": "Load",
   "Target": "Maps/Lemurkat_EastScarp_SpouseRoom",
   "FromFile": "assets/Maps/SpouseRoomsEastScarp.tmx"
       },

What we are doing here is adding our NPC spouse room into an existing file named “Data/spouseRooms”

To do this, we need to tell it the name of our spouse, then give the name of the spouseroom map. This must be unique: hence why in the above I have used <myname>_<modname>_SpouseRoom the final field there is the frame number for your map. If you were loading multiple NPCs in the one mod, then you would number each spouse room from 0 upwards.

The second part loads our Map into the folder, so that the game can read it. I have put in bold again the parts you will need to change. Make sure your directory path is accurate!

You can also add spousePatios (the outdoor area where the spouse hangs out during the day) in the same manner. Previous to 1.5.5, you needed another framework mod to add spouse patios, thus they are not part of this conversion process. Do feel free to design your own though! Details on how to add them can be found in the CP documentation on Github (link above).

FESTIVAL POSITIONS

Most mods have already moved festival positions across to loading via CP, since this feature was added early in 1.5’s release. However, you may find a few older mods that still only have them in the [TMX] folder. If you really want the NPCs to attend the festivals, you will need to translate them across too.

[TMX] content.json code

"festivalSpots": [  
  {
     "name": "Aideen",
     "map": "Town-Christmas", 
     "position": [45, 60],
     "direction": 3
        },
....(continues on with all the festivals)
]

must be changed into [CP] content.json code

{
  "Action": "EditData",
  "Target": "Data/Festivals/winter25",
  "TextOperations": [
      {
       "Operation": "Append",
       "Target": [ "Entries", "Set-Up_additionalCharacters"],
        "Value": "Aideen 45 60 3",
        "Delimiter": "/"
         }
     ]
 },

This is a fairly simple process, mostly involving a lot of cut and paste. You will need to change the Target to match the date of the Festival rather than the name of the map, and add the character’s details as in bold above.

And voila! You’re done – now all that remains is to double check all those warps… and I mean all of them!

1 Comment (+add yours?)

  1. symphorine
    Dec 22, 2022 @ 04:50:17

    I just used this guide to convert a couple mods for my personal playthrough; thank you, it was very clear and useful!

    Reply

Leave a comment