Mod Loader/Stories
A story pack adds people, conversations, and dress commissions with a mod.json file. You can write short dialogue in JSON or use Yarn Spinner for choices and branching. No DLL is needed.
Start with an example
examples/story-starter has Rose introduce Aster, then adds visits and a pigeon commission. examples/gerard-my-immortal is a fuller example: Gerard has three portraits and a red-and-black commission with different conversations for each result. Install one example, restart the game, and play past the opening tutorial. Other conversations can appear first, so the new client might not arrive immediately. Back up your save before testing story changes.
What goes in a story pack?
| Manifest list | What it adds |
|---|---|
clients
|
A person based on a game character, with optional portraits, postcard, and body shape. |
storyDialogues
|
A scene with a client and lines. Played scenes are remembered in the save. |
commissions
|
A job with a client, budget, delivery method, requirements, and outcome dialogue. |
Gerard's pack has this layout. Put your own pack in Dressmaker/Mods/YourPackName/ with the same structure:
gerard-my-immortal/
mod.json
dialogue.yarn
portraits/
verycool_npc_neutral.png
verycool_npc_smiling.png
verycool_npc_frowning.png
The pack ID and each client, scene, and commission ID become part of the save. Keep them stable after release. Changing an ID can make the game treat existing progress as new content.
Add a client and portraits
A custom client starts from a native character. baseCharacter supplies the game's existing character setup; your pack can give that client a new name, body shape, and images. Gerard uses Rose as the base:
"clients": [
{
"id": "gerard",
"name": "Gerard",
"baseCharacter": "Rose",
"portrait": "portraits/verycool_npc_neutral.png",
"happyPortrait": "portraits/verycool_npc_smiling.png",
"sadPortrait": "portraits/verycool_npc_frowning.png"
}
]
Image paths are relative to mod.json. Use PNG or JPG. The regular portrait is the default face; happyPortrait and sadPortrait are optional. If you leave an expression out, it uses the regular portrait. You can also provide a postcard image. Replace an image at the same path to update an expression, then restart the game and check it in a fresh conversation. Give every portrait the same canvas size so the character does not jump around when expressions change.
This changes portraits, not the in-game 3D character model. Optional shape values adjust the copied character's bust, waist, and hips sliders from 0 to 1. For a commission's target body measurements, use measurementsCm on the commission instead.
Add a commission
Gerard's screening_dress commission uses "client": "gerard" and "delivery": "visit". It asks for a Cool score of at least 25, a Goth score of at least 25, only red and black panels, and at least 20% of each colour:
"requirements": [
{ "type": "tag", "tag": "Cool", "value": 25 },
{ "type": "tag", "tag": "Goth", "value": 25 },
{ "type": "color", "colors": ["Red", "Black"] },
{ "type": "colorPercentage", "color": "Red", "value": 20 },
{ "type": "colorPercentage", "color": "Black", "value": 20 }
]
The colour list rules out other colours; the percentage rules make both colours necessary. The pack also sets a 750 coin budget and bust, waist, and hips measurements in centimetres. See requirement types for fabric, garment, accessory, and quality rules.
Write dialogue with Yarn Spinner
Yarn Spinner is the dialogue language used by Dressmaker. A node is one conversation with a title and a body. Lines beginning -> are choices; indented lines run after that choice. Commands in <<angle brackets>> can change portraits or control the conversation. The loader compiles the files listed in yarnFiles when it loads your pack, so you do not need a separate Yarn build step.
List the file in mod.json: "yarnFiles": ["dialogue.yarn"]. The node title must match the content it replaces. For Gerard's commission prompt, the pack ID yuuma.gerard-my-immortal becomes yuuma_gerard_my_immortal in the title:
title: Mod_yuuma_gerard_my_immortal_screening_dress_Prompt
---
<<set_portrait_neutral>>
I was told you handle dress emergencies. #line:gerard_intro_02
-> What colours would you like? #line:gerard_choice_colours
<<set_portrait_happy>>
Red and black. #line:gerard_reply_colours
-> How dramatic should it be? #line:gerard_choice_style
<<set_portrait_sad>>
Very dramatic. #line:gerard_reply_style
===
This is a shortened example based on Gerard's pack. Each #line: tag should be unique in your Yarn files. Gerard has four commission nodes ending in _Prompt, _Complete, _Failed, and _Excelled. The game chooses the result node after checking the finished dress. A story scene uses Mod_ followed by its full scene ID, without a result suffix. A matching Yarn node replaces the short lines in mod.json.
Use <<set_portrait_neutral>>, <<set_portrait_happy>>, or <<set_portrait_sad>> to switch between the images assigned to those slots. These are Dressmaker's Yarn commands. To add another expression, you would need a C# plugin; story pack JSON currently exposes these three portrait slots and the postcard.
Control when a scene appears
Put availability on a storyDialogues or commissions entry when a scene should wait for progress in the save. This example waits until level 5 and after your pack's introduction scene has played:
"availability": {
"minimumLevel": 5,
"afterDialogues": ["introduction"]
}
All listed conditions must be true. You can also use afterStory, minimumRelationship, and afterQuests. Use availability for a lasting story sequence; the loader checks it against saved game progress. Pigeon commissions also need the game's pigeon feature unlocked.
For a choice that changes only the current conversation, Yarn supports <<set>> and <<if>>:
<<set $askedAboutColour = false>>
-> Ask about colour. #line:colour_choice
<<set $askedAboutColour = true>>
Red and black. #line:colour_reply
-> Talk about the deadline. #line:deadline_choice
The screening is tomorrow. #line:deadline_reply
<<if $askedAboutColour>>
Thanks for checking the colours. #line:colour_followup
<<else>>
Please remember: red and black. #line:deadline_followup
<<endif>>
Do not rely on a Yarn variable to survive saving and quitting. Use afterDialogues or afterQuests for progress between visits. The Yarn Spinner flow control guide covers more branching syntax.
Test the story
- Back up a save before installing your story pack.
- Trigger each scene and commission in its intended order. Try every choice, portrait, and commission result.
- Save and restart. Check that completed scenes do not repeat unexpectedly and gated scenes appear when they should.
- Read
BepInEx/LogOutput.logfor a missing image, client, quest, tag, or Yarn node.
Field reference
The story fields page lists the client, commission, requirement, availability, measurement, and Yarn fields. Native IDs and outcomes are in BepInEx/config/DressmakerMods/story-reference.json.