Tutorial: Dynamic HD Portraits

From The Stardew Modding Wiki

Want to make a static HD Portrait? See the tutorial here: Tutorial: How to Add Portraits via HD Portraits.

Sometimes you want to make a portrait dynamic, such as one that changes with the seasons, or a portrait that only displays when a character is at the beach. This tutorial will cover that for HD Portraits. If you've never used HD Portraits before, I'd recommend starting with the basic tutorial for a static portrait linked above.

Getting Started[edit | edit source | hide | hide all]

Remember, HD Portraits just allows you to use Content Patcher to add portraits with tiles larger than 64x64 pixels to the game. As such, a lot of what is in this tutorial is covered in the Content Patcher README.

For this tutorial, we are going to be making seasonal portraits for Sam.

This will be a three step process:

  1. Loading the portraits
  2. Loading the size of the portraits
  3. Configuring HD Portraits to use the appropriate portraits at the appropriate times

Step 1 - Loading the Portraits[edit | edit source | hide]

First we need to add all of the different portraits to the game. Each portrait needs to have its own unique key, but it can be whatever you want it to be.

Put the following code into your content.json, under the "Changes" part of the file (inside the array, signified by []).
	{
		"LogName": "Import Sam Spring Portrait",
		"Action": "Load",
		"Target": "Mods/NameOfMod/Sam_Spring",
		"FromFile": "assets/Sam_Spring.png"
	},
	{
		"LogName": "Import Sam Summer Portrait",
		"Action": "Load",
		"Target": "Mods/NameOfMod/Sam_Summer",
		"FromFile": "assets/Sam_Summer.png"
	},
	{
		"LogName": "Import Sam Summer Beach Portrait",
		"Action": "Load",
		"Target": "Mods/NameOfMod/Sam_Beach",
		"FromFile": "assets/Sam_Beach.png"
	},
	{
		"LogName": "Import Sam Fall Portrait",
		"Action": "Load",
		"Target": "Mods/NameOfMod/Sam_Fall",
		"FromFile": "assets/Sam_Fall.png"
	},
	{
		"LogName": "Import Sam Winter Portrait",
		"Action": "Load",
		"Target": "Mods/NameOfMod/Sam_Winter",
		"FromFile": "assets/Sam_Winter.png"
	},
Here we are adding each of the portraits we want to use to Stardew, to be accessed via HD Portraits later. None of these need to be conditional yet.

Step 2 - Loading the Portrait's Size[edit | edit source | hide]

All of the portraits should have the same tile size. That is to say, each individual portrait should be the same pixel dimensions, and should also be a square.

Now we are going to tell HD Portraits what size to expect the portraits to be. We only need to do this once, for the character whose portraits we are changing.

First, create size.json inside our assets folder. It should look like this, with the number reflecting the pixel width/height of each portrait tile.
{
	"Size": 128
}
Next, we need to tell HD Portraits that this is the size you're using. Add the following to your content.json, again in the "Changes" section of the file. Since we are specifying a portrait for Sam on the beach, which the game treats as a separate portrait, we need to add an additional entry for that.
	{
		"LogName": "Specify Sam Portrait Size",
		"Action": "Load",
		"Target": "Mods/HDPortraits/Sam",
		"FromFile": "assets/size.json"
	},
	{
		"LogName": "Specify Sam Beach Portrait Size",
		"Action": "Load",
		"Target": "Mods/HDPortraits/Sam_Beach",
		"FromFile": "assets/size.json"
	},

Step 3 - Configuring HD Portraits to Load the Portrait You Want, When You Want It[edit | edit source | hide]

This is where your logic will go to dynamically display different portraits, dependent upon Content Patcher conditions. It'll look very similar to a non-[HD Portrait] seasonal Content Patcher portrait mod when it's done.

Add the following to your content.json.
	{
        "LogName": "Select Sam Portrait, Spring",
		"Action": "EditData",
		"Target": "Mods/HDPortraits/Sam",
		"Entries": {
			"Portrait": "Mods/NameOfMod/Sam_Spring"
		},
		"When": {
		    "Season": "Spring"
		}
	},
	{
        "LogName": "Select Sam Portrait, Summer",
		"Action": "EditData",
		"Target": "Mods/HDPortraits/Sam",
		"Entries": {
			"Portrait": "Mods/NameOfMod/Sam_Summer"
		},
		"When": {
		    "Season": "Summer"
		}
	},
	{
        "LogName": "Select Sam Portrait, Summer Beach",
		"Action": "EditData",
		"Target": "Mods/HDPortraits/Sam_Beach",
		"Entries": {
			"Portrait": "Mods/NameOfMod/Sam_Beach"
		},
		"When": {
		    "Season": "Summer"
		}
	},
	{
        "LogName": "Select Sam Portrait, Fall",
		"Action": "EditData",
		"Target": "Mods/HDPortraits/Sam",
		"Entries": {
			"Portrait": "Mods/NameOfMod/Sam_Fall"
		},
		"When": {
		    "Season": "Fall"
		}
	},
	{
        "LogName": "Select Sam Portrait, Winter",
		"Action": "EditData",
		"Target": "Mods/HDPortraits/Sam",
		"Entries": {
			"Portrait": "Mods/NameOfMod/Sam_Winter"
		},
		"When": {
		    "Season": "Winter"
		}
	},
Here we are telling HD Portraits which portrait to use, and when.

Note that I am only specifying Sam's beach portrait when it is summer, otherwise Sam will always be wearing a swimsuit when he's at the beach, and when it's cold out, we don't want that to happen.

Final content.json[edit | edit source | hide]

{
    "Format": "1.26.0",
    "Changes": [
		{
    		"LogName": "Import Sam Spring Portrait",
    		"Action": "Load",
    		"Target": "Mods/NameOfMod/Sam_Spring",
    		"FromFile": "assets/Sam_Spring.png"
    	},
    	{
    		"LogName": "Import Sam Summer Portrait",
    		"Action": "Load",
    		"Target": "Mods/NameOfMod/Sam_Summer",
    		"FromFile": "assets/Sam_Summer.png"
    	},
    	{
    		"LogName": "Import Sam Summer Beach Portrait",
    		"Action": "Load",
    		"Target": "Mods/NameOfMod/Sam_Beach",
    		"FromFile": "assets/Sam_Beach.png"
    	},
    	{
    		"LogName": "Import Sam Fall Portrait",
    		"Action": "Load",
    		"Target": "Mods/NameOfMod/Sam_Fall",
    		"FromFile": "assets/Sam_Fall.png"
    	},
    	{
    		"LogName": "Import Sam Winter Portrait",
    		"Action": "Load",
    		"Target": "Mods/NameOfMod/Sam_Winter",
    		"FromFile": "assets/Sam_Winter.png"
    	},
    	{
    		"LogName": "Specify Sam Portrait Size",
    		"Action": "Load",
    		"Target": "Mods/HDPortraits/Sam",
    		"FromFile": "assets/size.json"
    	},
    	{
    		"LogName": "Specify Sam Beach Portrait Size",
    		"Action": "Load",
    		"Target": "Mods/HDPortraits/Sam_Beach",
    		"FromFile": "assets/size.json"
    	},
    	{
            "LogName": "Select Sam Portrait, Spring",
    		"Action": "EditData",
    		"Target": "Mods/HDPortraits/Sam",
    		"Entries": {
    			"Portrait": "Mods/NameOfMod/Sam_Spring"
    		},
    		"When": {
    		    "Season": "Spring"
    		}
    	},
    	{
            "LogName": "Select Sam Portrait, Summer",
    		"Action": "EditData",
    		"Target": "Mods/HDPortraits/Sam",
    		"Entries": {
    			"Portrait": "Mods/NameOfMod/Sam_Summer"
    		},
    		"When": {
    		    "Season": "Summer"
    		}
    	},
    	{
            "LogName": "Select Sam Portrait, Beach",
    		"Action": "EditData",
    		"Target": "Mods/HDPortraits/Sam_Beach",
    		"Entries": {
    			"Portrait": "Mods/NameOfMod/Sam_Beach"
    		},
    		"When": {
    		    "Season": "Summer"
    		}
    	},
    	{
            "LogName": "Select Sam Portrait, Fall",
    		"Action": "EditData",
    		"Target": "Mods/HDPortraits/Sam",
    		"Entries": {
    			"Portrait": "Mods/NameOfMod/Sam_Fall"
    		},
    		"When": {
    		    "Season": "Fall"
    		}
    	},
    	{
            "LogName": "Select Sam Portrait, Winter",
    		"Action": "EditData",
    		"Target": "Mods/HDPortraits/Sam",
    		"Entries": {
    			"Portrait": "Mods/NameOfMod/Sam_Winter"
    		},
    		"When": {
    		    "Season": "Winter"
    		}
    	}
    ]
}