Stardew Valley
0 of 0

File information

Last updated

Original upload

Created by

agent56

Uploaded by

agent56

Virus scan

Safe to use

About this mod

Adds Content Patcher tokens for randomized colors for children and more.

Requirements
Permissions and credits
This mod generates a series of tokens in order to have unique appearances for an unlimited* number of children.
*as many as Stardew supports, including children across multiplayer households. Currently locked to 20 though due to Content Patcher's 'no numbers in tokens' rule. Feel free to bug if that is insufficient.

Features:
Random Colors:
Using configurable spouse color definitions and a little bit of math, this mod will create a file containing random HSV hair, skin, and eye colors for each child.

*Note*: Does not automatically support player spouses at the moment -- multiplayer is hard to test by myself 🙃

Unique Child Tokens:
Creates dozens of tokens to support unique child appearances in Content Patcher mods

Automatic content.json Creation:
Will take a content.json file and replicate it to support up to a configured amount of custom children.

Config:
config.json
Simple options supported by Generic Mod Config Menu

"AllAdopted": true/false (default: false)
Whether all children will be generated with a parent of 'Adopted' rather than using the parent's spouse
"GenesForSameSex": true/false (default: true)
Whether to use the parent's spouse for same sex marriages rather than 'Adopted'.
"GenderSpecificAlts": true/false (default: true)
Whether male and female should be considered separately when generating 'Alt'-related tokens
"NumAlts": 0-8 (default: 1)
The number of 'Alt's to generate for tokens (0 means Alt will always be '')
Useful if you want to be able to make two male children with the same coloring to look different in some way.
"NumChildIDsToGenerate": 1+ (default: 8)
The number of tokens to generate as well as the number of content files to generate when using the automatic content.json generation feature.
"ValidSpouses":
A list of spouse definitions for the random colors feature
"<Spouse Name>": {
      "HairColor": {
        "H": <0-360>,
        "S": <0-100>,
        "V": <0-100>
      },
      "EyeColor": {
        "H": <0-360>,
        "S": <0-100>,
        "V": <0-100>
      },
      "SkinColor": {
        "H": <0-360>,
        "S": <0-100>,
        "V": <0-100>
      }
    }
"FarmerSkinColors":
A list of skin colors that correspond to the ones used by the farmer (the first one is Skin 1, the second is Skin 2, etc.).
If you use a skin color replacer, you will want to change this.
{
        "H": <0-360>,
        "S": <0-100>,
        "V": <0-100>
}
"AdoptedSkinColors":
A list of skin colors to pick from when a child is 'Adopted' (to prevent random green babies when you don't want that).
By default I just stuck the first seven vanilla Stardew farmer skintones in there.
"ColorNames":
A list of color definitions, in case 'Blue' is not specific enough for your modding purposes.
To avoid colors randomly overwriting one another, try to make sure your mins and maxes don't overlap.
(ex. to create 'Cyan', copy Blue and make its Hue Max to 200. Then, change the original Blue's Hue Min to 200. 
    "<Color Name>": {
      "Hue": {
        "Min": <0-358>,
        "Max": <1-360>
      },
      "Saturation": {
        "Min": <0-99>,
        "Max": <1-101>
      },
      "Value": {
        "Min": <0-99>,
        "Max": <1-101>
      }
    }
"SkinColorNames":
Same as above, but for use for skintones. Defaults with way too few.
"Ages":
A configurable list of ages for compatibility with mods like LittleNPCs that add 'ages' above toddler
These should be ordered youngest to oldest, with the oldest Age having a maximum Age of 'null'
"<Age Name>":<Maximum Age (exclusive)>

Saves/<Save Folder Name>.json
A list of children in the save specified. Share its contents with your multiplayer companions to sync child appearance.
The key is "<Unique Multiplayer ID of Parent>_<Child Name>"
"NPCParentName": The second parent used to generate hair, eye, and skin color. Set to "Adopted" for random color generation, or one of "ValidSpouses" to change their genetic parent.
"AltNum": a number signifying which 'Alt' sprites this child will use. (0 is "", 1 is "_1")
"HairColor": HSV values that were generated for this child. Delete key to reroll on load.
"EyeColor": HSV values that were generated for this child. Delete key to reroll on load.
"SkinColor": HSV values that were generated for this child. Delete key to reroll on load.


Tokens:
Base:
Child ID is FirstChild, SecondChild, etc. up to the number specified in "NumChildIDsToGenerate"
"<Child ID>Alt": values: ["", "_1", "_2"..."_<NumAlts>"]
        "<Child ID>Gender": values: ["Male", "Female", "Unknown"]
"<Child ID>Age": values: ["<Ages 0>","<Ages 1>"...]
        "<Child ID>Parent": values: ["","<ValidSpouses 0>", "<ValidSpouses 1>"...]
        "<Child ID>Hair": values: ["<ColorNames 0>", "<ColorNames 1>"...]
        "<Child ID>Eyes": values: ["<ColorNames 0>", "<ColorNames 1>"...]
        "<Child ID>SkinColor": values: ["<SkinColorNames 0>", "<SkinColorNames 1>"...]

content.json Generation:
  • Create a content.json file using 'FirstChild' for all instances you'd like child data to be duplicated across all children
    (example from my Children Inherit Colors mod)

    {
    "Format": "1.28.0",
    "ConfigSchema": {
    "KrobusMonsterBabies": {
    "AllowValues": "true, false",
    "Default": "true"
    }
    },
    "Changes": [
    // FirstChild
    {
    "LogName": "FirstChild Skin load",
    "Action": "Load",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/Skin/{{agent56.GeneticsAPI/FirstChildSkinColor}}.png"
    },
    {
    "LogName": "FirstChild Eyes load",
    "Action": "EditImage",
    "Patchmode":"Overlay",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/Eyes/{{agent56.GeneticsAPI/FirstChildEyes}}.png"
    },
    {
    "LogName": "FirstChild Baby Hair load",
    "Action": "EditImage",
    "Patchmode":"Overlay",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/Hair/{{agent56.GeneticsAPI/FirstChildHair}}.png",
    "When": {
    "HasFile:{{FromFile}}": true
    }
    },
    {
    "LogName": "FirstChild Toddler Hair load",
    "Action": "EditImage",
    "Patchmode":"Overlay",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/Hair_{{agent56.GeneticsAPI/FirstChildGender}}{{agent56.GeneticsAPI/FirstChildAlt}}/{{agent56.GeneticsAPI/FirstChildHair}}.png",
    "When": {
    "HasFile:{{FromFile}}": true
    }
    },
    // Clothing
    {
    "LogName": "FirstChild Baby base load",
    "Action": "EditImage",
    "Patchmode":"Overlay",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/Base.png",
    "When": {
    "HasFile:{{FromFile}}": true
    }
    },
    {
    "LogName": "FirstChild Toddler Clothing load",
    "Action": "EditImage",
    "Patchmode":"Overlay",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/Clothing/Hair/{{agent56.GeneticsAPI/FirstChildHair}}.png",
    "When": {
    "HasFile:{{FromFile}}": true,
    "Time": "{{Range: 0600, 2000}}"
    },
    "Update": "OnTimeChange"
    },
    {
    "LogName": "FirstChild Toddler Clothing load",
    "Action": "EditImage",
    "Patchmode":"Overlay",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/Clothing/Eyes_{{agent56.GeneticsAPI/FirstChildGender}}/{{agent56.GeneticsAPI/FirstChildEyes}}.png",
    "When": {
    "HasFile:{{FromFile}}": true,
    "Time": "{{Range: 0600, 2000}}"
    },
    "Update": "OnTimeChange"
    },
    {
    "LogName": "FirstChild Toddler Clothing load",
    "Action": "EditImage",
    "Patchmode":"Overlay",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/PJs/{{agent56.GeneticsAPI/FirstChildGender}}.png",
    "When": {
    "HasFile:{{FromFile}}": true,
    "Time": "{{Range: 2000, 2600}}"
    },
    "Update": "OnTimeChange"
    },
    // Krobus Override
    {
    "LogName": "FirstChild Krobus override",
    "Action": "EditImage",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/{{agent56.GeneticsAPI/FirstChildParent}}/Base.png",
    "When": {
    "HasFile:{{FromFile}}": true,
    "KrobusMonsterBabies": true
    }
    },
    {
    "LogName": "FirstChild Krobus override",
    "Action": "EditImage",
    "Target": "Characters/FirstChild",
    "FromFile": "assets/{{agent56.GeneticsAPI/FirstChildAge}}/{{agent56.GeneticsAPI/FirstChildParent}}/Base_{{agent56.GeneticsAPI/FirstChildGender}}.png",
    "When": {
    "HasFile:{{FromFile}}": true,
    "KrobusMonsterBabies": true
    }
    }
    ]
    }
  • Launch Stardew Valley with my mod
  • Your content.json files should be in Genetics API/GeneratedContent, with 'FirstChild' being replaced where appropriate.
    ***You will need the content.json file and all the json files within the assets folder there as well.***

Compatibility:
Compatible with FamilyPlanning? I think? There were no logged errors, so it seems Genetics API silently overwrites its changes to the child sprites.
Compatible with LittleNPCs by intercepting all asset calls for its "<>LittleNPCName" assets and redirecting them to my '<nth>Child' asset path if there is no "<>LittleNPCName" asset defined already.