Stardew Valley

Swim Mod now accepts content packs! Swim Mod content packs allow you to specify dive locations and edge warps between maps and add features to underwater maps.

Swim mod content packs don't add maps, so if you want to add your own underwater maps, you'll have to create them yourself and add them using a separate TMXL content pack.

There's an example mod in the optional files for LemurKat's Escape to East Scarpe mod that has both a TMXL [TMX] content pack with a new underwater map and a Swim Mod Info [SMI] content pack to allow diving and add underwater features (more below).  I'm using [SM] as the main folder prefix that houses both content packs.

For info on creating a TMXL map content pack, please see the documentation for TMXL Map Toolkit.


Swim Mod Info [SMI] Content Pack Instructions:

Your [SMI] content pack needs only a manifest.json and a content.json file, formatted as follows:


manifest.json

The manifest.json file is standard for content packs, but make sure to add proper dependencies. Here's the example for the underwater East Scape SMI pack



{
"Name": "Underwater East Scarpe Swim Mod Info",
"Author": "aedenthorn",
"Version": "0.1.0",
"Description": "Adds swim mod info to LemurKat's East Scarpe and its underwater map.",
"UniqueID": "aedenthorn.UnderwaterEastScarpeSMI",
"MinimumApiVersion": "2.0",
"ContentPackFor": {
"UniqueID": "aedenthorn.Swim",
"MinimumVersion": "0.9.0"
},
"Dependencies": [
{
"UniqueID": "aedenthorn.Swim",
"IsRequired": true
},
{
"UniqueID": "aedenthorn.UnderwaterEastScarpeTMX",
"IsRequired": true
},
{
"UniqueID": "LemurKat.EastScarpe.TMX",
"IsRequired": true
},
]
}


Notice that it requires aedenthorn.UnderwaterEastScarpeTMX which is the accompanying TMXL content pack. LemurKat.EastScarpe.TMX is the TMX map for Escape to East Scarpe.


content.json

content.json has a single maps node that contains an array of maps and their information. Note that there can only be one dive map info for each map in the game. If you try to add dive map info for a map that already has it, it will fail.

The example pack has info for two maps, the existing EastScarpe map and the new UnderwaterEastScarpe map, in order to allow diving between them:

{
    "maps":[
        {
            "Name":"UnderwaterEastScarpe",
            "Features":[
                "SmolFishies",
                "Crabs",
                "OceanTreasure",
                "OceanResources",
                "Underwater",
                "FixWaterTiles"
            ],
            "DiveLocations": [
                {
                    "OtherMapName":"EastScarpe",
                },
            ],
        },
        {
            "Name":"EastScarpe",
            "Features":[
                "FixWaterTiles"
            ],
            "DiveLocations": [
                {
                    "OtherMapName":"UnderwaterEastScarpe",
                },
            ],
        },
    ]
}

Name should be the GameLocation name (for custom maps, the name given to TMXL in the addMaps node).


Features can include the following:

  • SmolFishies: adds smol fishies like in the Underwater Beach map
  • BigFishies: adds big fishies like in the Underwater Mountain map
  • Crabs: adds hermit and chest crabs like in the Underwater Beach map
  • OceanTreasure: Adds possible treasure chests with treasure taken from the fishing game
  • OceanResources: adds forageables like seaweed and clams
  • Underwater: tells Swim Mod that this is an underwater map to deplete oxygen and other things. If this is included, you NEED a DiveLocation of the same size without specific warp positions as the last DiveLocation, so it can warp there once you run out of oxygen.
  • FixWaterTiles: many maps have some impassable water tiles that you can't swim through. Setting this will try to make them passable for this map.


DiveLocations can include any number of nodes, each one specifying a map you can dive to from this map, with the following subnodes:

  • StartX: the horizontal tile coordinate where this dive spot begins (optional)
  • StartY: the vertical tile coordinate where this dive spot begins (optional)
  • Width: how many tiles wide the dive spot is (optional)
  • Height: how many tiles tall the dive spot is (optional)
  • OtherMapName: the GameLocation name of the map this dive spot leads to
  • OtherMapPos: the position on the other map to dive to, with its own X and Y nodes (see below) (optional)

For example, dive info for a specific area (37,29 to 39,36) on a map to a secret cave's map position 9,6 would look like:

  {
"Name":"MyOutdoorMap",
"DiveLocations": [
 {
 "StartX":37,
 "StartY":29,
 "Width":3,
 "Height":8,
 "OtherMapName":"MySecretCave",
 "OtherMapPos":{
"X":9,
"Y":6,
  }
},
],
 },


If you omit StartX, StartY, Width, and Height, it will dive to that location no matter where you are on the map, as long as you are in water.

If you omit OtherMapPos it will warp you to the same location you are currently at on the other map (and it had better be the same size or bigger!).

Dive locations are checked in order, so you can have multiple specific dive locations, followed by one non-specific dive location as a fallback.


Edge Warps

You can also add EdgeWarps to your maps that will trigger at specified strips when the player crosses the edge of the map swimming. For example, the Swim mod's Town map data has:

  {
"Name":"Town",
"EdgeWarps":[
{
  "ThisMapEdge":"Bottom",
  "FirstTile": 88,
  "LastTile": 92,
  "DestinationHorizontal": true,
  "OtherMapIndex": 0,
  "OtherMapFirstTile": 57,
  "OtherMapLastTile": 62,
  "OtherMapName":"Beach",
},
{
  "ThisMapEdge":"Top",
  "FirstTile": 92,
  "LastTile": 96,
  "DestinationHorizontal": true,
  "OtherMapIndex": 40,
  "OtherMapFirstTile": 64,
  "OtherMapLastTile": 78,
  "OtherMapName":"Mountain",
},
{
  "ThisMapEdge":"Left",
  "FirstTile": 96,
  "LastTile": 103,
  "DestinationHorizontal": false,
  "OtherMapIndex": 119,
  "OtherMapFirstTile": 39,
  "OtherMapLastTile": 48,
  "OtherMapName":"Town",
},
]
  },


ThisMapEdge tells which edge of the map to check (must be one of Top, Right, Bottom, Left).
FirstTile is the lower boundary tile coord to allow this warp on the given edge (Y coord for vertical edges and X for horizontal edges)
LastTile is the upper boundary tile coord to allow this warp on the given edge (Y coord for vertical edges and X for horizontal edges)
DestinationHorizontal says whether the destination edge is horizontal or vertical.
OtherMapIndex is the tile coord of the edge (Y for horizontal edges, X for vertical edges - will be 0 for top and left, otherwise the max coord for bottom and right)
OtherMapFirstTile is the lower boundary tile coord to warp to on the other map's given edge (Y coord for vertical edges and X for horizontal edges)
OtherMapLastTile is the upper boundary tile coord to warp to on the other map's given edge (Y coord for vertical edges and X for horizontal edges)
OtherMapName is the name of the map to warp to.

The warp strip lengths don't need to be equal, it will try to approximate a warp location on different sized strips.

The destination doesn't need to be at the edge of the other map, in case you want to create an artificial edge. For now though, edge warps only occur on the actual edge of the map, so to get back you'd have to create an actual warp tile on your map.

Article information

Added on

Edited on

Written by

aedenthorn

0 comments