Difference between revisions of "Modding alternate races"

From Wildermyth Wiki
(Initial page creation)
 
(Adding categories)
 
Line 622: Line 622:


If multiple mods are installed that overwrite these files & check for relatedness, only one mod will be able to win. Is there a way that we can coordinate our efforts to test for race more generically and apply the appropriate effect across multiple mods? Feel free to join the Wildermyth Discord to discuss this in the #tools-and-modding channel!
If multiple mods are installed that overwrite these files & check for relatedness, only one mod will be able to win. Is there a way that we can coordinate our efforts to test for race more generically and apply the appropriate effect across multiple mods? Feel free to join the Wildermyth Discord to discuss this in the #tools-and-modding channel!
[[Category:Modding]]
[[Category:Modding Guides]]

Latest revision as of 18:12, 22 February 2023

In the base game, all of your heroes are humans. Though they can undergo various transformattions through certain events, they still remain fundamentally human. Fantasy is full of weird and wonderful sentient species though, and this guide will walk you through the process using the Drauven PCs mod as an example & reference.

This guide assumes that you have already created a mod and are familiar with the basics. Check out the Modding Guide if you need help getting started.

Creating the Base History & Aspects

To begin, create a new history entry. Create a file in the assets/data/history of your mod (creating any missing folders as necessary), then make a new blank text file and give it a name like drauvenBase.json

To start, make a placeholder object with a category and ID. This history entry is going to add and remove aspects to our heroes, so let's also go ahead and add placeholders for these as well. You can copy this template in and change the name from drauven to your race's name:

{
	"id": "drauvenBase.001",
	"category": "drauvenBase",
	"impliedAspects": [],
	"removeAspects": [],
	"showInSummary": false
}

Removing the Human Skin Layers

First step for any good nonhuman race will be to remove all of the human visuals. We can do this by removing the humanSkin aspects associated with the various limbs and adding a few more humanSkin aspects to suppress the rest.

To remove all the limbs, we set up our removeAspects list to remove the following:

	"removeAspects": [
		"humanSkin_naturalLeftArm",
		"humanSkin_naturalLeftHand",
		"humanSkin_naturalRightArm",
		"humanSkin_naturalRightHand",
		"humanSkin_naturalLeftLeg",
		"humanSkin_naturalRightLeg",
		"humanSkin_naturalHead"
	]

To remove the torso, we need to add an aspect in the impliedAspects list:

	"impliedAspects": [
		"humanSkin_suppressTorso"
	]

With these aspects added & removed, our character should now be a completely blank slate!

Some other aspects that you may consider adding, depending on the nature of your race, include:

  • humanSkin_suppressClothes: Clothing layers will not be drawn, but the character can still use armour (it will just be invisible)
  • ATTACHMENTS_suppressArmor: Character cannot wear armour (so will be relying on other aspects for their defence)

Non-Human Base Stats & the nonhuman Aspect

For our Drauven mod, we wanted to give Drauven characters a different set of base stats compared to what humans get. To accomplish this, we created an aspect called nonhuman, whose role it is to reverse certain features that are granted to humans by default and to check for non-human characters in events so that we can require or forbid normal humans from being assigned to various roles.

Please feel free to use this aspect and add it to any new races you create! You can create a text file called assets/data/aspects/races.json and paste the following code:

[
{
	"id": "nonhuman",
	"stats": {
		"ARMOR": 0,
		"BLOCK": -45,
		"CHARISMA": -15,
		"DODGE": -45,
		"HEALTH": -5,
		"MELEE_ACCURACY": -100,
		"PERCEPTION": -10,
		"PHYSICAL_DAMAGE_BONUS": 0,
		"POTENCY": 0,
		"RANGE_ACCURACY": -100,
		"RECOVERY_RATE": -25,
		"RETIREMENT_AGE": -45,
		"SPEED": -1,
		"STUNT_CHANCE": -15,
		"TENACITY": -15,
		"WARDING": 0
	},
	"importance": -1
}
]

The above stats will zero-out all the basic human ones, leaving you free to define your own without having to worry about mental math to subtract out the human baseline. You can then add your own racial stats, giving you something that might look like this: (Remember that if you're editing a JSON file directly, you will need to make sure there is a comma between each entry in a list, such as between two aspect definitions)

{
	"id": "drauven_pc",
	"effects": [],
	"stats": {
		"ARMOR": 0,
		"BLOCK": 55,
		"CHARISMA": 10,
		"DODGE": 35,
		"HEALTH": 3,
		"MELEE_ACCURACY": 100,
		"PERCEPTION": 12,
		"PHYSICAL_DAMAGE_BONUS": 0,
		"POTENCY": 0,
		"RANGE_ACCURACY": 100,
		"RECOVERY_RATE": 40,
		"RETIREMENT_AGE": 65,
		"SPEED": 1,
		"STUNT_CHANCE": 15,
		"TENACITY": 20,
		"WARDING": 0
	},
	"voice": "defaultDrauven"
}

Now go back to your "base" history entry above and add the two new aspects to your impliedAspects list. It should look something like this:

	"impliedAspects": [
		"humanSkin_suppressTorso",
		"nonhuman",
		"drauven_pc"
	]

Creating an Effect for Faster Character Generation

It is possible to create an effect associated with an initialization aspect to help make generating NPCs of your race faster and more consistent. This is especially if you have multiple steps involved in your race assignment such as setting history, applying a theme, and triggering a re-randomization of Customization fields. Whenever an NPC is being generated through implications, you initialization effect will run before the comic starts, so new NPCs will have all of the desired traits.

For example, the Drauven PCs mod uses the following initialization aspect & effect:

{
	"modId": "wildermyth-drauven-pcs",
	"id": "drauven_pc_init",
	"effects": [ "drauven_pc_init" ],
	"importance": -1,
	"showChangeInComics": "never",
	"invalidatesSkin": true,
	"lifespan": "all"
}
{
"id": "drauven_pc_init",
"info": {
	"dataVersion": 1,
	"sourceFile": "drauven_pc_init",
	"modId": "wildermyth-drauven-pcs",
	"author": "justEthaniguess & Ironskink",
	"STUB": "Initialize our Drauven characters"
},
"type": "ABILITIES_CHANGED",
"targets": [
	{ "template": "SELF" }
],
"outcomes": [
	{
		"class": "Aspects",
		"removeAspects": [ "drauven_pc_init" ]
	},
	{
		"class": "AddHistory",
		"target": "self",
		"addHistory": [
			[ "drauvenBase" ]
		]
	},
	{ "class": "ApplyTheme", "theme": "drauven", "piece": "torso" },
	{
		"class": "CustomizeHero",
		"randomizeSlots": [ "drauven01_Head", "drauven02_Feathers", "drauven03_Horns", "drauven04_Whiskers" ],
		"randomizeColors": [ "skin" ]
	}
]
}

Adding Skin Layers

Skin layers can be added either using a theme, using aspects, or by a combination of both.

  • Layers that are applied to the head or face will include the field "headOffset": true. Names for the files will be exactly the same as the names defined in the layers.
  • Layers that are applied to the body will generally be "rig-specific." Names for the image files need to be prefixed with the rig being used for the character. (For example, if the layer is named alternatTorso, the game will look for files named hunterF_alternateTorso.png, etc.

By default, the 6 rigs are hunterF, hunterM, mysticF, mysticM, warriorF and warriorM.

Using a Theme

A theme is a fast way to set up layers for a character and will automatically overwrite human visuals. Theme parts can also be set to automatically apply if specific other part(s) are present, allowing you to fully transform a character into a member of your custom race by only applying a single part.

A theme allows you to specify other themes that are incompatible with your racial theme (eg: our Drauven are ineligible to get the Wolf, Bear, Gem or Skeletal themes for various lore and graphical reasons). However, if you transform all of a character's limbs using theme parts, your custom race won't be eligible for any other themes as there are no free slots that can further be transformed.

The easiest way to create a theme is to start from an existing theme (such as Wolf). Copy the file into your mod folder at assets/data/themes, then open the file in either the in-game editor or your favourite text or code editor to change the layer names to match the names of the assets you have created/are creating for your race.

If your alternate race will be holding weapons, make sure to go to the "arms" layers and remove the leftGrip and rightGrip from the "replaces" list.

Using Aspects

Aspects can be given an array of skinLayers that work just like the layers in a theme file. An advantage of setting up your skin layers through aspects is that the character's limbs remain free for transformations, thus allowing your custom race to gain transformations just like a human can.

Skin layers can be defined with list of aspects that are required for the layer to show and a list of aspects that should block a layer from showing. This allows you to automatically turn off layers for limbs if that limb is transformed.

For example, our drauvenSkin_naturalLeftLeg aspect is defined to replace the default humanSkin_naturalLeftLeg aspect. It is set to display as long as the leg is not being replaced by a theme limb, bandaged limb or prosthetic limb.

  {
    "modId": "wildermyth-drauven-pcs",
    "id": "drauvenSkin_naturalLeftLeg",
    "stats": { "SPEED": 1.7 },
    "importance": -1,
    "invalidatesSkin": true,
    "skinLayers": [
      {
        "name": "Drauv_LegL",
        "tint": "skin",
        "ifNoOwnerAspects": ["themeSlotFilled_leftLeg", "drauvenSkin_bandagedLeftLeg", "drauvenSkin_prostheticLeftLeg"],
        "depth": 1101
      }
    ]
  }

Posing: Heads, Hands & Weapons

If your alternate race will be holding items, you will want to make sure you have created one & two handed arm poses plus open, closed, book, and two-handed (closed) hand poses for both the left and right arms/hands. You can check the rigMode to see if the model is being drawn with a one or two handed weapon, and the ifRightHandGrasp and ifLeftHandGrasp attributes to see what the character is holding.

To help with layer ordering, you may want to separate the arms into 'upper' and 'lower' sections and separate the closed & book hands & thumb layers so that they can overlap the items being held appropriately.

Here is an example of layer definitions for the right arm and hand of our Drauven characters:

  {
    "modId": "wildermyth-drauven-pcs",
    "id": "drauvenSkin_naturalRightArm",
    "importance": -1,
    "invalidatesSkin": true,
    "skinLayers": [
      {
        "name": "Drauv_ArmR_upper",
        "tint": "skin",
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm"],
        "depth": 1350,
        "rigMode": "oneHanded"
      },
      {
        "name": "Drauv_ArmR_lower",
        "tint": "skin", 
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm"],
        "depth": 3000,
        "rigMode": "oneHanded"
      },
      {
        "name": "Drauv_ArmR_2handed_upper",
        "tint": "skin",
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm"],
        "depth": 1350,
        "rigMode": "twoHanded"
      },
      {
        "name": "Drauv_ArmR_2handed_lower",
        "tint": "skin",
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm"],
        "depth": 8000,
        "rigMode": "twoHanded"
      }
    ]
  },
  {
    "modId": "wildermyth-drauven-pcs",
    "id": "drauvenSkin_naturalRightHand",
    "importance": -1,
    "invalidatesSkin": true,
    "skinLayers": [
      {
        "name": "Drauv_handR_open",
        "tint": "skin",
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm", "drauvenSkin_bandagedRightArm", "drauvenSkin_prostheticRightArm"],
        "depth": 6000,
        "ifRightHandGrasp": "open",
        "rigMode": "oneHanded"
      },
      {
        "name": "Drauv_handR_closed",
        "tint": "skin",
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm", "drauvenSkin_bandagedRightArm", "drauvenSkin_prostheticRightArm"],
        "depth": 8001,
        "ifRightHandGrasp": "weapon",
        "rigMode": "oneHanded"
      },
      {
        "name": "Drauv_handR_closed_thumb",
        "tint": "skin", 
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm", "drauvenSkin_bandagedRightArm", "drauvenSkin_prostheticRightArm"],
        "depth": 6000,
        "ifRightHandGrasp": "weapon",
        "rigMode": "oneHanded"
      },
      {
        "name": "Drauv_handR_book",
        "tint": "skin", 
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm", "drauvenSkin_bandagedRightArm", "drauvenSkin_prostheticRightArm"],
        "depth": 6000,
        "ifRightHandGrasp": "book",
        "rigMode": "oneHanded"
      },
      {
        "name": "Drauv_handR_book_thumb",
        "tint": "skin", 
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm", "drauvenSkin_bandagedRightArm", "drauvenSkin_prostheticRightArm"],
        "depth": 8001,
        "ifRightHandGrasp": "book",
        "rigMode": "oneHanded"
      },
      {
        "name": "Drauv_handR_2handed",
        "tint": "skin", 
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm", "drauvenSkin_bandagedRightArm", "drauvenSkin_prostheticRightArm"],
        "depth": 8002,
        "rigMode": "twoHanded"
      },
      {
        "name": "Drauv_handR_2handed_thumb",
        "tint": "skin",
        "ifNoOwnerAspects": ["themeSlotFilled_rightArm", "drauvenSkin_bandagedRightArm", "drauvenSkin_prostheticRightArm"],
        "depth": 6000,
        "rigMode": "twoHanded"
      }
    ]
  }

Creating Race-Specific Customizations

An arbitrary number of customization categories and parts can be defined by creating files in your mod's assets/data/peopleParts file. Each part should be given "type": "extra" and a value for "extraSlot". All parts that have the same extraSlot value will be grouped together on the customization page, and customizations will be listed in alphabetical order of their extraSlot value.

As of Version 1.10 (Suna Lo Haster), you can specify aspects required for the customization to be displayed in the customization menu, thereby allowing you to hide your racial customizations from normal humans, by adding a requireAspects field. If set, the part will only be available to characters that have all of the aspects listed.

Here is an example of one of our Drauven heads:

{
	"type": "extra",
	"extraSlot": "drauven01_Head",
	"requireAspects": ["drauvenSkin_naturalHead"],

	"groups": [
		{"groupIndex": 0, "male": true, "maleWeight": 1, "female": true, "femaleWeight": 1},
		{"groupIndex": 1, "male": true, "maleWeight": 1, "female": true, "femaleWeight": 1},
		{"groupIndex": 2, "male": true, "maleWeight": 1, "female": true, "femaleWeight": 1},
		{"groupIndex": 3, "male": true, "maleWeight": 1, "female": true, "femaleWeight": 1}
	],
	"layers": [
    {
      "name": "replaceHead_drauven_stump",
      "tint": "skin",
      "depth": 4000,
      "headOffset": true,
      "ifOwnerAspect": "drauvenSkin_naturalHead",
      "ifNoOwnerAspects": ["themePiece_crow_head", "themePiece_wolf_head", "themePiece_tree_head", "themePiece_frog_head"],
      "facialExpression": ["neutral", "interested", "grim", "sad", "skeptical", "dubious", "open", "surprised", "scared", "angry", "rage", "scheming", "hit", "dead", "happy", "joke", "joy"]
    }
	]
}

To give user-friendly names to your customization slots, open (or create) a text file as assets/text/dynamic/dynamic.properties and add translations for your extraSlots. For example, the definitions might look something like this:

extraPartSlot.drauven01_Head=Head
extraPartSlot.drauven02_Feathers=Feathers
extraPartSlot.drauven03_Horns=Horns
extraPartSlot.drauven04_Whiskers=Whiskers

Defining a Custom Skin or Hair Palette

As of Version 1.10 (Suna Lo Haster), it is possible to define custom skin & hair colour palettes through aspects.

skinColorPaletteOverride|COLORS "Override the colors shown in the customization palette. Takes any number of hex parameters, e.g. "skinColorPaletteOverride|ff3333|33ff33|55aaff" (Can give an individual a random one of these colors by using the Customize Outcome)"

hairColorPaletteOverride|COLORS "Override the colors shown in the customization palette. Takes any number of hex parameters, e.g. "skinColorPaletteOverride|ff3333|33ff33|55aaff" (Can give an individual a random one of these colors by using the Customize Outcome)"

To have these custom palettes apply to your alternate race characters, we recommend adding these aspects to your base racial history entry.

The Customize Outcome

If your customization aspects are hidden from humans, then they won't be randomly generated when an NPC is created. You can solve this by using the Customize outcome, which will allow you to set or randomize a character's skin colour, hair colour, and one or more of the extra slots. You can see an example of the Customize action in our sample initialization effect above.

Alternate Rigs

COMING SOON

Rig Override Aspect: overrideRig|RIG

Override the rig used for this individual (see assets\data\generation\rigs.json) Will search for class and body-type specific versions first, appending Warrior/Hunter/Mystic and M/F to the id. For example, if RIG is "myRig" and the hero is a male warrior, in order it'll search for myRigWarriorM > myRigWarrior > myRigM > myRig

Rigs are defined in assets/data/generation/rigs.json


Once the rig override is available, modders will be able to specify their own rigs - which will make it a lot easier to line up weapons, items, etc! Note that if you override the rig, the game will be looking for image assets using that new rig name - which means none of the base-game assets will automatically apply to the body of your character! You will need to provide new copies of all files - such as theme limbs, gear, and anything else that begins with a rig-specific prefix for anything that your new rig will support.

Non-Human Name Generation

You can specify a name formula using a history entry that sets the humanName:

For example, to generate a character that uses a name algorithm called drauvenName you could make a history entry that looks like this:

Note: This method can cause some buggy behaviour when customizing the character! A better method of assigning the algorithm is in the works and will be available soon!

{
	"id": "bornDrauven.default",
	"weight": 0.95,
	"category": "bornDrauven",
    "humanName": "drauvenName",
	"showInSummary": false
}

COMING SOON: A better way to override the name generation algorithm via aspects!

Name Algorithm Aspect: "nameFormulaOverride|ALGORITHM_NAME"

Example: "nameFormulaOverride|drauvenName"


Name formulas are defined in the file assets/data/generation/human.names.json

To create new name definitions for your race, add or edit a file with this name in the same relative location in your mod. This file will be structured as an object where the keys are all of your translation keys and the values define the parts used to construct the names.

Sample name generator:

{
    "drauvenName": ["<DrauvenFirstName> <DrauvenConstructedSurnamePrefix><DrauvenSurname>"],
    "drauvenFirstName": ["_OR_", [2, "<PredefinedDrauvenFirstName>"], [7, "<ConstructedDrauvenFirstName>"], [1, "<DrauvenFirstNameBegin><drauvenFirstNameBegin><drauvenFirstNameEnd>"]],

    "predefinedDrauvenFirstName": ["Thuvayn", "Pyarc", "Vrsawl", "Zuvyac", "Colr", "Tranyen", "Mulsc"],

    "constructedDrauvenFirstName": ["<DrauvenFirstNameBegin><drauvenFirstNameEnd>"],
    "drauvenFirstNameBegin": ["lwa", "lau", "zve", "xar", "vyx", "styx", "ghirr", "tsyx", "mexx", "idgr", "thog", "thuv", "py", "vrs", "zu", "kyv", "ksu", "dra", "ts", "dee", "vra", "tsyr", "mul", "tran", "co", "du", "kyo", "kree", "cv", "ady", "boh", "dorb", "dar", "dra", "bor", "groz", "ylc", "kal", "uvz", "dyg", "auk", "yvy", "kve", "cas", "marz", "kras", "lju", "rost", "zbyh", "ves", "srbi", "zahv", "zby", "jaro", "zyz", "osor", "przby", "tych", "vla", "vyas", "zvez"],
    "drauvenFirstNameEnd": ["ysl", "yn", "ayn", "arc", "rc", "rn", "orr", "rek", "ra", "reth", "veth", "xis", "eth", "rok", "xra", "rel", "duk", "yrn", "ish", "ysh", "wn", "osk", "ysk", "ssl", "xol", "awl", "vyac", "orr", "arr", "lr", "lrr", "yen", "sc", "st", "mpv", "yost", "esna", "ka", "jek", "rig", "rut", "myr", "oza", "zet", "ska", "vak", "wia", "cno", "acz", "ki", "cko"],

    "drauvenConstructedSurnamePrefix": ["_OR_", [2, ""], [1, ""]],
    "drauvenSurname": ["_OR_", [2, ""], [1, ""]],

	"drauvenHostileFaction": ["_OR_", [1, "Zagarac"], [1, "Druvimos"]],
	"drauvenOutpostName": ["<DrauvenFirstNameBegin><drauvenFirstNameEnd> Outpost"],

}

When we tell the game to use the `drauvenName` generator, the code will read the entry and see that we need to pick a DrauvenFirstName, a DrauvenConstructedSurnamePrefix and a DrauvenSurname. Capitalization comes from the capitalization of the various pieces: specifying DrauvenFirstName will capitalize whatever is chosen, but using drauvenFirstName will not.

The drauvenFirstName entry showcases an example of the _OR_ option. Everything following the OR is an array with two values. The first value specifies the relative weight/probability of that option being chosen, and the second entry specifies what to generate when that entry is selected. In this case, drauvenFirstName has a 2-in-10 chance of selecting a PredefinedName, a 7-in-10 chance of a ConstructedDrauvenName, which is later defined to be one beginning-sound followed by an ending-sound, and a 1-in-10 chance of combining two beginning-sounds with one ending-sound.

As of Version 1.10 (Suna Lo Haster), the name generator will no longer wipe out other name generators if they have different keys, thereby allowing multiple mods to create arbitrary name generation algorithms. (If your mod includes a key that is identical to one in the base game or another mod, the new definition will overwrite the old one.)

Non-Human Abilities & Skills

You can create a skill deck for your mod and use that to create custom abilities that your characters can select at level-up. Skills are granted by aspects, so start by creating a new file in your assets/data/aspects folder to hold your skill selections. (For example, you might call it assets/data/aspects/drauvenDeck.json)

Adding Race-Specific Skills

A race-specific skill with an upgrade might look something like this:

{
	"modId": "wildermyth-drauven-pcs",
	"id": "drauvenDeck_common_battleyell",
	"effects": [ "drauven_pc_battleyell" ],
	"boostType": "ABILITY_CLASS",
	"legacyAbilityChoice": true,
	"abilityRequiresOneAspectOf": [ "drauven_pc" ],
	"info": { "abilityDeckUsage": "common", "abilityDeckIcon": "bloodrage" }
},
{
	"modId": "wildermyth-drauven-pcs",
	"id": "drauvenDeck_common_battleyell_upgrade",
	"legacyAbilityChoice": true,
	"abilityRequiresOneAspectOf": [ "drauven_pc" ],
	"info": {
		"abilityDeckUsage": "upgrade",
		"upgradeForAbility": "drauvenDeck_common_battleyell",
		"abilityDeckIcon": "bloodrage"
	}
}
  • Using abilityRequiresOneAspectOf we can specify our custom race aspect so that the ability is only offered to our custom characters
  • The effects entry will point to the ID of the actual ability (effect) being granted. (See Modding monster abilities for some additional info on creating ability effects)
  • The abilityDeckUsage can be set to common to make it available to all members of your race, or warrior, hunter or mystic to make it both race and class specific.

Blocking Human-Only Skills

As of Version 1.10 (Suna Lo Haster), if there are skills in the game that you want to keep as human-only you can find those skills in the base game files and copy them into your mod's skill deck file to add a abilityForbidAspects field to them.

abilityForbidAspects If this is an ability aspect, this ability will only be granted to a hero if that hero has none of these aspects.

For example, if you want to block Wolfcall from being offered to your custom race, you would add the following to your aspect file:

{
	"id": "warriorDeck_wolfcall",
	"effects": [ "warrior_wolfcallTriggerOnKill" ],
	"boostType": "ABILITY_CLASS",
	"legacyAbilityChoice": true,
	"abilityForbidAspects": ["drauven_pc"],
	"showInTooltip": true,
	"info": { "abilityDeckUsage": "warrior", "abilityDeckIcon": "wolfcall" }
}

Relatives: Parents & Children

Wildermyth is all about family legacies - and when adding a custom race, it is also possible to update events so that any relatives will also be members of your custom race!

Children Joining the Party

Children are added to the party through the file assets/data/effects/kidRecruit/officialNotification.json. The child's primary parent has the role of sponsor.

In the outcomes section of this file, you can add a Test for the race of the character in the sponsor role and apply your initialization effect if appropriate. For example, in our Drauven mod we use the following:

	{
		"class": "Test",
		"value": "sponsor.drauven",
		"threshold": "1",
		"onPass": {
			"class": "Aspects",
			"target": "hero",
			"addAspects": [
				{ "id": "drauven_pc_init", "value": "1" }
			]
		}
	}

Parents in Comics

Many events generate parents or relatives for characters. To find events that might be generating related characters, use a tool that allows you to search for text in multiple files (such as the project-search feature in VS Code) for instances of "looksSimilarTo".

If the role being generated is a relative of one of your heroes, copy the event to your mod (following the same folder structure that the original event was found in) and duplicate the NPC generation code. We will add a test to each version of the NPC to check if the character they look similar to is of our custom race and apply the initialization effect we made if true.

For example, "Family Business" (encounter_wilderness_familyBusiness_revision.json) defines Parent1 as:

		{
			"npcId": "familyBusiness_Parent1",
			"createEntity": {
				"query": {
					"baseTag": "human",
					"inRelationTo": "hero",
					"setClass": "farmer",
					"setAge": "veryOldAge",
					"looksSimilarTo": "hero"
				},
				"additionalOutcome": {
					"class": "DoAll",
					"outcomes": [
						null,
						{ "class": "AddGear", "itemById": "farmerGarbRough" }
					]
				}
			}

To make the parent Drauven if the hero is themselves Drauven, we update this section by adding a copy of the initial version. The version that tests for 1 - \[our race aspect\] will be executed if the character is not a member of our customer race, and the version that simply tests for our racial aspect will generate if the hero in question is a member of our custom race. For example:

		{
			"npcId": "familyBusiness_Parent1",
			"test": "1-hero.drauven",
			"createEntity": {
				"query": {
					"baseTag": "human",
					"inRelationTo": "hero",
					"setClass": "farmer",
					"setAge": "veryOldAge",
					"looksSimilarTo": "hero"
				},
				"additionalOutcome": {
					"class": "DoAll",
					"outcomes": [
						null,
						{ "class": "AddGear", "itemById": "farmerGarbRough" }
					]
				}
			}
		},
		{
			"npcId": "familyBusiness_Parent1",
			"test": "hero.drauven",
			"createEntity": {
				"query": {
					"baseTag": "human",
					"inRelationTo": "hero",
					"setClass": "farmer",
					"setAge": "veryOldAge",
					"looksSimilarTo": "hero"
				},
				"addAspects": [
					{ "id": "drauven_pc_init", "value": "1" }
				]
			}
		}


Mod Conflicts & Coordination

If multiple mods are installed that overwrite these files & check for relatedness, only one mod will be able to win. Is there a way that we can coordinate our efforts to test for race more generically and apply the appropriate effect across multiple mods? Feel free to join the Wildermyth Discord to discuss this in the #tools-and-modding channel!