-
Notifications
You must be signed in to change notification settings - Fork 17
Creating a Pants Content Pack
A content pack for Fashion Sense (FS) allows mod authors to create pants with the following benefits:
- Can be larger than 16x32 pixels
- Can be animated
- Can override the player's pants color
Fashion Sense content packs are compatible with other FS packs, meaning you can have as many Fashion Sense pants as you'd like!
-
Create a parent folder with the content pack's name.
-
Create and fill in
manifest.json
as a content pack. -
Create a
Pants
folder, add it under the content pack's main folder. -
Create a sub-folder under
Pants
with the name of the pantsa. The name of the folder(s) under
Pants
do not matter. -
Create a
pants.json
under the created sub-folder, using the required fields found here. -
Create a
pants.png
under the same sub-folder.a. The image size doesn't matter, so long as it is under 16384x16384 pixels (though smaller files are preferred to reduce memory usage).
A Fashion Sense content pack consists of the following structure:
[FS] Example Pack
├── manifest.json
│
└── Pants
├── Spirit
│ ├── pants.json
│ └── pants.png
│
└── PinkGrassSkirt
├── pants.json
└── pants.png
If this is your first time creating a content pack, it may be useful to read the Stardew Valley Wiki for creating a content pack.
The first step to making your content pack is to create a top level folder with the name of your content pack. For example: [FS] Example Pack
.
After that, you'll want to create the manifest.json
file under that folder. Detailed instructions can be found on the Stardew Valley Wiki. Additionally, you can check out the example manifest.json as a reference.
For example:
[FS] Example Pack
└── manifest.json
It is important to note that the manifest.json
file must contain the following for it to be a content pack by Fashion Sense:
"ContentPackFor": {
"UniqueID": "PeacefulEnd.FashionSense",
"MinimumVersion": "USE.LATEST.VERSION"
}
Note: Replace "MinimumVersion": "USE.LATEST.VERSION"
with the latest version number of Fashion Sense found here.
You will first need to create a Pants
folder underneath your main content pack folder.
After creating the Pants
folder you'll want to create a sub-folder for every pants you want to add, like so:
.
└── Pants
├── Spirit
│
└── PinkGrassSkirt
You can also have sub-folders under the Pants
folder for organizing, like so:
.
└── Pants
├── Animated or Colorable
│ └── Spirit
│
└── Static
└── PinkGrassSkirt
To add a pants to your content pack, the framework requires a pants.json
under each sub-folder of Pants
.
For example:
.
└── Pants
├── Spirit
│ ├── pants.json
│ └── pants.png
│
└── PinkGrassSkirt
├── pants.json
└── pants.png
The file pants.json
determines how the pants is to be applied and allows the usage of certain conditions for animation.
An overview of the required properties for pants.json
:
Property | Description | Default | |
---|---|---|---|
Name |
Required | Name of the pants, which can contain spaces. | N/A |
Format |
Recommended | The format version to use, which should be set to Fashion Sense's current version. | "1.0.0" |
BackPants |
Optional 1 | Specifies how the pants will look while the player is facing backwards. See this page for more details. |
null |
RightPants |
Optional 1 | Specifies how the pants will look while the player is facing right. See this page for more details. |
null |
FrontPants |
Optional 1 | Specifies how the pants will look while the player is facing forward. See this page for more details. |
null |
LeftPants |
Optional 1 | Specifies how the pants will look while the player is facing left. See this page for more details. |
null |
-
At least one
PantsModel
(FrontPants, BackPants, etc.) must be given for the pants to be valid.a. Note that
PantsModel
have their own required properties, as can be seen here.
This is a simple pants.json
, which adds a static (non-animated) pants that applies for all directions while the player is walking or running.
{
"Name": "Pink Grass Skirt",
"FrontPants": {
"DisableGrayscale": true,
"StartingPosition": {
"X": 0,
"Y": 0
},
"BodyPosition": {
"X": 0,
"Y": -21
},
"PantsSize": {
"Width": 16,
"Length": 10
},
"IdleAnimation": [
{
"Frame": 0,
"Duration": 100
}
],
"MovementAnimation": [
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 1,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 2,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 1,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 3,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 1,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 2,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 4,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 2,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
]
},
"BackPants": {
"DisableGrayscale": true,
"StartingPosition": {
"X": 0,
"Y": 10
},
"BodyPosition": {
"X": 0,
"Y": -21
},
"PantsSize": {
"Width": 16,
"Length": 10
},
"IdleAnimation": [
{
"Frame": 0,
"Duration": 100
}
],
"MovementAnimation": [
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 1,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 2,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 1,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 3,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 1,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 2,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 4,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 2,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
]
},
"RightPants": {
"Flipped": true,
"DisableGrayscale": true,
"StartingPosition": {
"X": 0,
"Y": 20
},
"BodyPosition": {
"X": 0,
"Y": -20
},
"PantsSize": {
"Width": 16,
"Length": 10
},
"IdleAnimation": [
{
"Frame": 0,
"Duration": 100
}
],
"MovementAnimation": [
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 1,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 2,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 3,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 4,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
}
]
},
"LeftPants": {
"DisableGrayscale": true,
"StartingPosition": {
"X": 0,
"Y": 20
},
"BodyPosition": {
"X": 0,
"Y": -21
},
"PantsSize": {
"Width": 16,
"Length": 10
},
"IdleAnimation": [
{
"Frame": 0,
"Duration": 100
}
],
"MovementAnimation": [
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 1,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 2,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsWalking",
"Value": true
}
]
},
{
"Frame": 0,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 3,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
},
{
"Frame": 4,
"EndWhenFarmerFrameUpdates": true,
"Conditions": [
{
"Name": "IsRunning",
"Value": true
}
]
}
]
}
}
The StartingPosition
property is used to determine where the starting point is (top-left most pixel for the PantsModel
).
The BodyPosition
property is used to tell the framework where the player's head would be in relation to the pants.
Note: It is important to know that each PantsModel added (FrontPants, BackPants, etc.) must have a StartingPosition
, BodyPosition
and PantsSize
, as the framework uses those properties to display the pants.
The corresponding pants.png
The layout requirements for pants.png
is fairly relaxed, as the framework utilizes StartingPosition
, BodyPosition
and PantsSize
to determine where the pants sprites are located.
See the example pack for references on how to create your pants.
This is an animated pants.json
, which adds a pants with an uniform animation and only applies while the player is facing forward.
{
"Name": "Spirit",
"FrontPants": {
"HideLegs": true,
"StartingPosition": {
"X": 0,
"Y": 0
},
"BodyPosition": {
"X": 0,
"Y": -23
},
"PantsSize": {
"Width": 16,
"Length": 8
},
"UniformAnimation": [
{
"Frame": 0,
"Duration": 100
},
{
"Frame": 1,
"Duration": 100
},
{
"Frame": 2,
"Duration": 100
},
{
"Frame": 3,
"Duration": 100
},
{
"Frame": 4,
"Duration": 100
},
{
"Frame": 5,
"Duration": 100
},
{
"Frame": 6,
"Duration": 100
}
]
}
}
You can see UniformAnimation
was specified with 4 frames. UniformAnimation
always plays, so long as IdleAnimation
and MovementAnimation
aren't given.
To play an animation only while the player is moving, you would instead utilize MovementAnimation
. For more details see the animations page.
Conditions
can also be used to determine which frames are played. See the conditions page for more details.
The corresponding pants.png
The layout requirements for animated pants.png
is fairly relaxed, as it only requires the following condition(s):
- For PantsModel with animation, each frame of the pants should be placed next to each other horizontally (as seen in the example above).
See the example pack for references on how to create your pants.
If you're looking for examples, see the examples page.