Modder's upgrade guide

How to migrate your content pack to the latest format version

Update from 0.x to 1.0

New content pack format

This is back compatibility break. Old content packs in old format used by beta versions 0.x is not supported. Migration to new content pack format is needed.

The content pack format was upgraded to new format version 2.0. Content pack structure for NPC Adventures was changed.

  • NPC Adventures content packs just defines the companion disposition only
  • Lore content (like dialogues, events and etc) was moved under Content Patcher control.
  • Quests are under Quest Framework control.

Moved targets

  • Data/CompanionDispositions -> companions/<companionName>.json in NPC Adventures content pack folder (known as disposition file)
  • Data/AnimationDescriptions -> Content Patcher Data/animationDescriptions
  • Dialogue/<NpcName> -> Content Patcher Dialogue/<NpcName> (standard game dialogue file for concrete NPC)
  • Data/Buffs -> Under field Buffs in disposition file (NPC Adventures content pack)
  • Strings/Buffs -> Under field BuffsDescription in disposition file (NPC Adventures content pack)
  • Weapons/<NpcName> -> Under field Weapons in disposition file (NPC Adventures content pack)
  • Data/IdleBehaviors -> Under field IdleBehaviors in disposition file (NPC Adventures content pack)
  • Data/IdleNPCDefinitions -> Under field IdleBehaviors in disposition file (NPC Adventures content pack)
  • Strings/Mail -> Content Patcher Data/mail
  • Data/Events -> Content Patcher Data/Events/<locationName>
  • Data/Quests -> Under Quest Framework control (as QF content pack)
  • Data/Forages -> Content Patcher Mods/purrplingcat.npcadventures/Forages

How to migrate old content pack to new format

New format uses individual json file per each defined companion in folder companions/ in the NPC Adventures content pack directory. The disposition file structure was changed from string dictionary to a model structure.

We have a companion NPC Abigail in old content pack format and we want migrate her to new format.

Old content.json file

{
  "Format": "1.4",
  "Changes": [
    {
      "Target": "Data/CompanionDispositions",
      "FromFile": "assets/Data/CompanionDispositions.json"
    },
    {
        "Target": "Strings/Mail",
        "FromFile": "assets/Strings/Mail.json"
    },
    {
      "Target": "Dialogue/Abigail",
      "FromFile": "assets/Dialogue/Abigail.json"
    },
    {
      "Target": "Data/Buffs",
      "FromFile": "assets/Data/Buffs.json"
    },
    {
      "Target": "Strings/SpeechBubbles",
      "FromFile": "assets/Strings/SpeechBubbles.json"
    },
    {
      "Target": "Data/AnimationDescriptions",
      "FromFile": "assets/Data/AnimationDescriptions.json"
    },
    {
      "Target": "Data/IdleBehaviors",
      "FromFile": "assets/Data/IdleBehaviors.json"
    },
    {
      "Target": "Data/IdleNPCDefinitions",
      "FromFile": "assets/Data/IdleNPCDefinitions.json"
    },
    {
      "Target": "Strings/Buffs",
      "FromFile": "assets/Strings/Buffs.json"
    }
  ]
}

and all targeted files by the content definition file.

As first step we migrate Data/CompanionDispositions target which adds Abigail from file assets/Data/CompanionDispositions.json in the content pack directory.

{
  "Abigail": "recruitable/warrior//5/0",
}

This means we have companion NPC called Abigail which is a warrior and requires 5 hearts to accept adventure.

As next step we create file companions/Abigail.json and as content we add:

{
  "Format": "2.0",
  "Name": "Abigail",
  "Skills": [
    { "Name": "warrior" }, // Abigail is a warrior companion class
  ],
  "Rules": {
    "f Abigail 1250": "accept" // Accepts adventure if you have 5 hearts or more. This uses EPU conditions
  }
}

Now we have migrated Abigail as a companion to new format. But When we play the game and recruit her, we see Abigail fight with fists only and she has no idle behavior, grants no buffs and etc. Now this is best time to migrate other stuff into new companion disposition file. Also we have no companion dialogues for her.

Let's migrate Data/Buffs from assets/Data/Buffs.json which contains:

{
  "Abigail": "0/0/0/0/1/0/0/0/0/1/0/1",
}

In our new file companions/Abigail.json we add new field Buffs with buff parameters array and BuffsDescription

{
  // ...
  "Buffs": {
    "Attack": 1,
    "Luck": 1,
    "Speed": 1
  },
  "BuffsDescription": "[abigail.buffs]", // This targets i18n translation in `i18n` folder. This feature is provided by SMAPI
}

Create file i18n/default.json

{
  "abigail.buffs": "Hanging out with Abigail gets your adventurer's blood pumping!#You gain +1 Speed, +1 Luck and +1 Attack."
}

Let's go migrate weapons

Abigail in our content pack doesn't define weapons, because she uses default weapons in NPC Adventures. Since version 1.0 there are no default weapons, so we want to define them.

Add field Weapons to companions/Abigail.json

{
  // ...
  "Weapons": {
    // The key is Farmer's fighting level and the value is a weapon name used by companion 
    // when farmer has fighting on the defined level or higher
    "0": "Abby's Planchette", // 1-3
    "1": "Steel Smallsword", // 4-8
    "2": "Pirate's Sword", // 8-14
    "3": "Cutlass", // 9-17
    "4": "Forest Sword", // 8-18
    "5": "Iron Edge", // 12-25
    "6": "Holy Blade", // 18-24
    "7": "Bone Sword", // 20-30
    "8": "Tempered Broadsword", // 29-44
    "9": "Obsidian Edge", // 30-45
    "10": "Lava Katana" // 55-64
  },
}

Now it's time to migrate idle behaviors from Data/IdleNPCDefinitions, Data/IdleBehaviors and Data/AnimationDescriptions

Add field IdleBehaviors

{
  // ...
  "IdleBehaviors": [
    {
      "Behavior": "Animate",
      "Animations": [
        // Animations are defined in game content file `Data/animationDescriptions` editable by Content Patcher
        // Custom animations define with Content Patcher
        "abigail_sit_ground",
        "abigail_flute" 
      ],
      "Tendency": 5,
      "MinDuration": 10,
      "MaxDuration": 30
    },
    {
      "Behavior": "Lookaround",
      "FaceMinSeconds": 2,
      "FaceMaxSeconds": 5,
      "Tendency": 2,
      "MinDuration": 10,
      "MaxDuration": 30
    }
  ]
}

So, we have complete new companion disposition file

{
  "Format": "2.0",
  "Name": "Abigail",
  "Skills": [
    { "Name": "warrior" }
  ],
  "Rules": {
    "f Abigail 1250": "accept"
  },
  "Buffs": {
    "Attack": 1,
    "Luck": 1,
    "Speed": 1
  },
  "BuffsDescription": "[abigail.buffs]",
  "Weapons": {
    "0": "Abby's Planchette", // 1-3
    "1": "Steel Smallsword", // 4-8
    "2": "Pirate's Sword", // 8-14
    "3": "Cutlass", // 9-17
    "4": "Forest Sword", // 8-18
    "5": "Iron Edge", // 12-25
    "6": "Holy Blade", // 18-24
    "7": "Bone Sword", // 20-30
    "8": "Tempered Broadsword", // 29-44
    "9": "Obsidian Edge", // 30-45
    "10": "Lava Katana" // 55-64
  },
  "IdleBehaviors": [
    {
      "Behavior": "Animate",
      "Animations": [
        "abigail_sit_ground",
        "abigail_flute" 
      ],
      "Tendency": 5,
      "MinDuration": 10,
      "MaxDuration": 30
    },
    {
      "Behavior": "Lookaround",
      "FaceMinSeconds": 2,
      "FaceMaxSeconds": 5,
      "Tendency": 2,
      "MinDuration": 10,
      "MaxDuration": 30
    }
  ]
}

Also we update manifest.json in our NPC Adventures content pack and we remove old files (content.json and all assets referenced by this file).

{
  "Name": "NPC Adventures example content pack",
  "Author": "PurrplingCat",
  "Version": "2.0.0", // increase major version
  "Description": "Example companion for NPC Adventureas",
  "UniqueID": "PurrplingCat.ExampleCompanionNpcAdventures",
  "MinimumApiVersion": "3.13.0", // Target latest SMAPI (3.13 when I was written this docs)
  "UpdateKeys": [ "Nexus:1234" ],
  "ContentPackFor": {
    "UniqueID": "purrplingcat.npcadventure",
    "MinimumVersion": "1.0.0-alpha" // Update required minimum version of NPC Adventures to 1.0
  }
}

Now it's time to define lore content (like dialogues, speech bubbles, events, quests and etc) with Content Patcher. This requires create new content pack for Content Patcher. See NPC Adventures Content Patcher content pack (placed in Mods/NPC Adventures/[CP] NPC Adventures) for example how to do it.

See also