So, you've got an awesome idea for a new custom race for Baldur's Gate 3. Great! The only problem is, you have no idea how to actually make a custom race.
Sound like you? Well you're in the right place.
Members of the BG3 Modding Community have created a handy race template to go along with this tutorial. You can download the template here: https://github.com/EmeraldTechnopath/CMTY-Race-Template
Just visit the link, click the green Code button, and then click Download ZIP.
Unzip the zip file, delete the README.md, and you're ready to start following the tutorial.
Just to see what the template has already set up for you, go ahead and pack the mod using Modder's Multitool. (Or LSLIB… if you prefer using it.) Then load it into BG3 Mod Manager, save, export, and run the game.
Start a new game, and you'll see a new Custom Race option at the end of all the vanilla races.
(Note: as of Patch 7, the custom race icon may appear as a tan square. That is normal.)
This Custom Race is going to look a lot like a default Human, but that's okay. We can tweak the visuals as much as we want later.
The template has all of the required components to create that basic Custom Race, and no more than that. You can already see that the race doesn't have any subraces, race features, passives, or spells. We'll get into adding extra parts to the race later on in the tutorial.
But for now, let's close the game and open the template in your preferred code viewer.
Open the Community_Race_Template folder in your preferred code viewer, such as Notepad++ or VSCode.
In this example from VSCode, we can see all of the files that are contained within the template. You can see that we have six files, and we'll go over each of them in detail.
<?xml version="1.0" encoding="utf-8"?>
<contentList> <!-- This is the file that defines the localization, aka the actual text that shows up in game. -->
<!--Base race loca-->
<content contentuid="hdf502bafg2939g4569g820bg200792707f93" version="1">Custom Race</content> <!-- The Name of the custom race. Regenerate this handle before releasing the mod! -->
<content contentuid="h8c7f32e9ga38ag4a4dg95f5g84300a7a48a8" version="1">This custom race is brimming with potential.</content> <!-- The Description of the custom race. Regenerate this handle before releasing the mod! -->
<!--Subraces loca-->
<!--Passives loca-->
</contentList>
This file is not very long, but it is important. This is the Localization file, which handles all of the custom text that is actually going to appear in the game. Any text that your race will need to appear in the game itself will be defined here.
As you can see, there are only two lines defined here, one for the Name of the race and one for the Description. But you can add as many lines as you want and connect them to various parts of your code.
As there's already a dedicated page for creating a meta.lsx, we'll send you over there. Once you understand how the meta works and what it does, come back here.
<?xml version="1.0" encoding="UTF-8"?>
<save>
<version major="4" minor="0" revision="9" build="313"/>
<region id="CharacterCreationPresets"> <!-- This is the file that tells the game important information about what body types need to show up in CC for your race. -->
<node id="root">
<children>
<node id="CharacterCreationPreset"> <!-- Female Standard -->
<attribute id="BodyShape" type="uint8" value="0"/> <!-- 0 = Standard -->
<attribute id="BodyType" type="uint8" value="1"/> <!-- 1 = Female -->
<attribute id="CloseUpA" type="LSString" value="ELF_F_Camera_Closeup_A"/> <!-- Cameras for zooming in in CC -->
<attribute id="CloseUpB" type="LSString" value="ELF_F_Camera_Closeup_B"/> <!-- ^ -->
<attribute id="Overview" type="LSString" value="ELF_F_Camera_Overview_A"/> <!-- ^ -->
<attribute id="RaceUUID" type="guid" value="3328d981-bf97-4e50-8961-fef8cd80c67e"/> <!-- Race ID from races.lsx -->
<attribute id="RootTemplate" type="guid" value="7f52aa3a-40cf-4f75-b190-e773726a8939"/> <!-- Root template from Race_Root_Templates.lsf.lsx -->
<attribute id="SubRaceUUID" type="guid" value="00000000-0000-0000-0000-000000000000"/> <!-- Subrace ID from races.lsx, 00000000-0000-0000-0000-000000000000 if no subrace -->
<attribute id="UUID" type="guid" value="04c52da3-cc33-4f63-88b4-462cdc7ebacc"/> <!-- UUID that tells the game this is its own unique object. Regenerate this before publishing the mod! -->
<attribute id="VOLinesTableUUID" type="guid" value="14df8f45-90af-4bd0-8024-42624da9976e"/> <!-- Sets the lines used when the player previews the voice in CC. Leaving it at the default is recommended. -->
</node>
<node id="CharacterCreationPreset"> <!-- Male Standard -->
<attribute id="BodyShape" type="uint8" value="0"/> <!-- 0 = Standard -->
<attribute id="BodyType" type="uint8" value="0"/> <!-- 0 = Male -->
<attribute id="CloseUpA" type="LSString" value="ELF_M_Camera_Closeup_A"/> <!-- Cameras for zooming in in CC -->
<attribute id="CloseUpB" type="LSString" value="ELF_M_Camera_Closeup_B"/> <!-- ^ -->
<attribute id="Overview" type="LSString" value="ELF_M_Camera_Overview_A"/> <!-- ^ -->
<attribute id="RaceUUID" type="guid" value="3328d981-bf97-4e50-8961-fef8cd80c67e"/> <!-- Race ID from races.lsx -->
<attribute id="RootTemplate" type="guid" value="5dd3feb0-89e5-44e9-9467-5d362b556763"/> <!-- Root template from Race_Root_Templates -->
<attribute id="SubRaceUUID" type="guid" value="00000000-0000-0000-0000-000000000000"/> <!-- Subrace ID from races.lsx, 00000000-0000-0000-0000-000000000000 if no subrace -->
<attribute id="UUID" type="guid" value="54a734e9-462a-480f-ab82-700a62a59142"/> <!-- UUID that tells the game this is its own unique object. Regenerate this before publishing the mod! -->
<attribute id="VOLinesTableUUID" type="guid" value="14df8f45-90af-4bd0-8024-42624da9976e"/> <!-- Sets the lines used when the player previews the voice in CC. Leaving it at the default is recommended. -->
</node>
</children>
</node>
</region>
</save>
This is the file that tells the game important information about what body types need to show up in CC for your race. Right now we only have two: Female Standard (Body Type 1) and Male Standard (Body Type 2). We'll get into adding strong body types (3 and 4) later in the tutorial.
The default camera values given are fine for standard body humans, elves, half-elves, drow, and tieflings. However, if you are making a shorter or taller race, you will need to adjust those camera values so that the camera will zoom in the correct place.
The race ID and subrace IDs will come from Races.lsx, which we will look at later. Similarly, the RootTemplate ID will come from Race_Root_Templates.lsf.lsx.
The UUID is just an ID that tells the game that this is its own unique body type in CC. It doesn't need to be copied anywhere else.
And the VOLinesTableUUID sets the table of voice lines that can play when the player is previewing a voice in CC. Leaving it at the default is recommended.
Because this file is so long, we're not going to paste the entire thing into the wiki. Instead, we'll just look at the Female Character Visuals entry.
<node id="Resource"> <!-- Race Female Standard -->
<attribute id="BaseVisual" type="FixedString" value="4b8ff439-0a98-6e6c-ad48-c695c1c29b27" /> <!-- References the animation set for this body type (Hum, Elf, Gith, etc. animation sets). Note that animation sets from bodies that are typically very different sizes will not transfer over well. -->
<attribute id="BodySetVisual" type="FixedString" value="db6e5918-8514-4dcc-8363-e8fd3c50cce5" /> <!--Connects to the merged file entry's ID field for the body's mesh-->
<attribute id="ID" type="FixedString" value="c6e16e66-2313-4a49-b0e7-1e38e7f25987" /> <!-- Connects to the Root Template UUID for the CharacterVisualResourceID-->
<attribute id="Name" type="LSString" value="Race_Female_Player" /> <!-- Internal name for the race / bodytype combination. Does not affect anything in-game. -->
<attribute id="ShowEquipmentVisuals" type="bool" value="True" /> <!--Indicates whether equipment will show on this player entry-->
<children>
<node id="MaterialOverrides">
<children>
<node id="MaterialPresets">
<children> <!--Sets the color of the entries below-->
<node id="Object">
<attribute id="ForcePresetValues" type="bool" value="False" />
<attribute id="GroupName" type="FixedString" value="02Skin Properties" />
<attribute id="MapKey" type="FixedString" value="02Skin Properties" />
<attribute id="MaterialPresetResource" type="FixedString" value="23d08caf-f88d-0457-6253-8059fdf027d3" /> <!--Material UUID for skin -->
</node>
<node id="Object">
<attribute id="ForcePresetValues" type="bool" value="True" />
<attribute id="GroupName" type="FixedString" value="06Eyes" />
<attribute id="MapKey" type="FixedString" value="06Eyes" />
<attribute id="MaterialPresetResource" type="FixedString" value="62b1c4c9-a8d4-3132-b3a6-1e3294a6551a" /> <!--Material UUID for eyes-->
</node>
<node id="Object">
<attribute id="ForcePresetValues" type="bool" value="True" />
<attribute id="GroupName" type="FixedString" value="03Hair" />
<attribute id="MapKey" type="FixedString" value="03Hair" />
<attribute id="MaterialPresetResource" type="FixedString" value="72f56d86-89a0-d8e3-b3ba-c35c2cee61bc" /> <!--Material UUID for hair-->
</node>
<node id="Object">
<attribute id="ForcePresetValues" type="bool" value="True" />
<attribute id="GroupName" type="FixedString" value="05Makeup" />
<attribute id="MapKey" type="FixedString" value="05Makeup" />
<attribute id="MaterialPresetResource" type="FixedString" value="2c477c0d-15a8-0591-bd94-6acc583666ea" /> <!--Material UUID for makeup-->
</node>
</children>
</node> <!-- Parameters below are for materials that apply to this body type. -->
<node id="ScalarParameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="Opacity" />
<attribute id="Value" type="float" value="2" />
</node>
<node id="ScalarParameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="Reflectance" />
<attribute id="Value" type="float" value="0.6" /> <!--0 = closer to not present, 1 = closer to very present-->
</node>
<node id="ScalarParameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="SecondaryColourIntensity" />
<attribute id="Value" type="float" value="1" /> <!--0 = closer to not present, 1 = closer to very present-->
</node>
<node id="ScalarParameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="IrisEdgeStrength" />
<attribute id="Value" type="float" value="0.7" /> <!--0 = closer to not present, 1 = closer to very present-->
</node>
<node id="ScalarParameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="Redness" />
<attribute id="Value" type="float" value="1.5" />
</node>
<node id="ScalarParameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="True" />
<attribute id="Parameter" type="FixedString" value="Highlight_Intensity" /> <!--hair hightlight intensity parameter-->
<attribute id="Value" type="float" value="0.4" /> <!--0 = closer to not present, 1 = closer to very present-->
</node>
<node id="Vector3Parameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="Lips_Makeup_Color" />
<attribute id="Value" type="fvec3" value="0.44787082 0.14718807 0.14005016" /> <!--first number entry is Red, second is Green, third is Blue-->
</node>
<node id="Vector3Parameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="MakeupColor" />
<attribute id="Value" type="fvec3" value="0.049433455 0.011126081 0.010397801" /> <!--first number entry is Red, second is Green, third is Blue-->
</node>
<node id="Vector3Parameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="Eyes_IrisColour" />
<attribute id="Value" type="fvec3" value="0.58597296 0.3636039 0.1869885" /> <!--first number entry is Red, second is Green, third is Blue-->
</node>
<node id="Vector3Parameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="Eyes_IrisSecondaryColour" />
<attribute id="Value" type="fvec3" value="0.51740134 0.19046287 0.06972708" /> <!--first number entry is Red, second is Green, third is Blue-->
</node>
<node id="Vector3Parameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="Eyes_BloodColour" />
<attribute id="Value" type="fvec3" value="0.35865393 0.04145189 0.034230206" /> <!--first number entry is Red, second is Green, third is Blue-->
</node>
<node id="Vector3Parameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="Eyes_ScleraColour" />
<attribute id="Value" type="fvec3" value="0.3992933 0.32038155 0.28881598" /> <!--first number entry is Red, second is Green, third is Blue-->
</node>
<node id="Vector3Parameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="False" />
<attribute id="Parameter" type="FixedString" value="AddedColor" />
<attribute id="Value" type="fvec3" value="0.025700033 0 0" /> <!--first number entry is Red, second is Green, third is Blue-->
</node>
<node id="Vector3Parameters">
<attribute id="Color" type="bool" value="False" />
<attribute id="Custom" type="bool" value="True" />
<attribute id="Enabled" type="bool" value="True" />
<attribute id="Parameter" type="FixedString" value="Highlight_Color" />
<attribute id="Value" type="fvec3" value="0.7372549 0.54901963 0.4117647" /> <!--first number entry is Red, second is Green, third is Blue-->
</node>
</children>
</node>
<node id="Slots"> <!-- Sets the default meshes for each slot for the body type. -->
<attribute id="Bone" type="FixedString" value="" />
<attribute id="Slot" type="FixedString" value="Head" />
<attribute id="VisualResource" type="FixedString" value="675271af-039a-38fa-eee2-1f406c94bfa0" /> <!--Matched to the CharacterCreationAppearanceVisuals file using the VisualResource UUID. Use the UUID associated with the head you want to be the default when loading the race and body type.-->
</node>
<node id="Slots">
<attribute id="Bone" type="FixedString" value="" />
<attribute id="Slot" type="FixedString" value="ModestyLeaf" />
<attribute id="VisualResource" type="FixedString" value="dec25989-ed08-895e-4ae0-5c9b44352bf0" /> <!--Matched to the CharacterCreationAppearanceVisuals file using the VisualResource UUID. Use the UUID associated with the modesty leaf (lower) you want to be the default when loading the race and body type.-->
</node>
<node id="Slots">
<attribute id="Bone" type="FixedString" value="" />
<attribute id="Slot" type="FixedString" value="ModestyLeaf" />
<attribute id="VisualResource" type="FixedString" value="13bb4168-a5e4-fe82-f3df-57721a1ffed3" /> <!--Matched to the CharacterCreationAppearanceVisuals file using the VisualResource UUID. Use the UUID associated with the modesty leaf (upper) you want to be the default when loading the race and body type.-->
</node>
<node id="Slots">
<attribute id="Bone" type="FixedString" value="" />
<attribute id="Slot" type="FixedString" value="Hair" />
<attribute id="VisualResource" type="FixedString" value="6bcb9954-7418-d234-2509-009d4892039e" /> <!--Matched to the CharacterCreationAppearanceVisuals file using the VisualResource UUID. Use the UUID associated with the hair you want to be the default when loading the race and body type.-->
</node>
<node id="Slots">
<attribute id="Bone" type="FixedString" value="" />
<attribute id="Slot" type="FixedString" value="Private Parts" />
<attribute id="VisualResource" type="FixedString" value="338ced1c-058d-95ec-bb6a-074d48de0d29" /> <!--Matched to the CharacterCreationAppearanceVisuals file using the VisualResource UUID. Use the UUID associated with the private parts you want to be the default when loading the race and body type.-->
</node>
</children>
</node>
This is the CharacterVisuals file, which defines a lot of stuff about how your race appears and what it uses as default values (think the appearance of the character when you first select the race).
<?xml version="1.0" encoding="utf-8"?>
<save>
<version major="4" minor="0" revision="9" build="328" />
<region id="Races"> <!-- This is the file that sets up important information about your race. -->
<node id="root">
<children>
<node id="Race">
<attribute id="DisplayName" type="TranslatedString" handle="hdf502bafg2939g4569g820bg200792707f93" version="1" /> <!-- Display name for the race, links to Community_Race_Template.loca.xml -->
<attribute id="Description" type="TranslatedString" handle="h8c7f32e9ga38ag4a4dg95f5g84300a7a48a8" version="1" /> <!-- Description for the race, links to Community_Race_Template.loca.xml -->
<attribute id="DisplayTypeUUID" type="guid" value="899d275e-9893-490a-9cd5-be856794929f" /> <!-- Humanoid display type (what precisely does this do?) -->
<attribute id="Name" type="FixedString" value="Community_MainRace" /> <!-- Internal name for race, doesn't affect anything in-game -->
<attribute id="ParentGuid" type="guid" value="899d275e-9893-490a-9cd5-be856794929f" /> <!-- Humanoid Parent ID, this connects the entry to the humanoid race entry in the vanilla Races file.-->
<attribute id="ProgressionTableUUID" type="guid" value="78cb9632-c52c-47d6-8588-4779228fc892" /> <!-- Progression table, regenerate before releasing mod! -->
<attribute id="RaceEquipment" type="FixedString" value="EQ_Underwear_Humans"/> <!-- Default underwear for the race -->
<attribute id="RaceSoundSwitch" type="FixedString" value="Human" /> <!-- Sound made when selecting the race -->
<attribute id="UUID" type="guid" value="3328d981-bf97-4e50-8961-fef8cd80c67e" /> <!-- Unique Race UUID, regenerate before releasing mod! -->
<children> <!-- Most of the colors and visuals that the race can choose from in CC, such as eye color, hair color, hairs, and beards. -->
<!-- Colors and visuals entries here -->
</children>
</node>
</children>
</node>
</region>
</save>
This is the file that defines some basic information about your race, and also assigns it visuals for use in Character Creation.
<?xml version="1.0" encoding="utf-8"?>
<save>
<version major="4" minor="0" revision="9" build="328" lslib_meta="v1,bswap_guids" />
<region id="Templates"> <!-- The file that sets up the Root Templates for each race/subrace/bodytype combination. -->
<node id="Templates">
<children>
<node id="GameObjects"> <!-- Female -->
<attribute id="MapKey" type="FixedString" value="7f52aa3a-40cf-4f75-b190-e773726a8939" /> <!-- UUID that tells the game this is its own unique object. Regenerate this before publishing the mod! -->
<attribute id="Name" type="LSString" value="Race_Female_Player" /> <!-- Internal name for race, does not affect anything in-game. -->
<attribute id="Type" type="FixedString" value="character" /> <!-- Tells the game that this is a Character root template. -->
<attribute id="ParentTemplateId" type="FixedString" value="e87dd6f0-22f4-4cd5-914f-adddd2595941" /> <!-- The parent template for your race. Choosing the race that is most similar to your custom race is a safe bet. -->
<attribute id="SpellSet" type="FixedString" value="CommonPlayerActions" /> <!-- Gives your race common player actions as options -->
<attribute id="CharacterVisualResourceID" type="FixedString" value="c6e16e66-2313-4a49-b0e7-1e38e7f25987" /> <!-- Tells the game what CharacterVisuals entry to use for the race. -->
<attribute id="Race" type="guid" value="3328d981-bf97-4e50-8961-fef8cd80c67e" /> <!-- The Unique Race UUID from races.lsx -->
<children>
<node id="Tags"> <!-- Add any tags you want here, including custom tags. -->
<children>
<node id="Tag">
<attribute id="Object" type="guid" value="00000000-0000-0000-0000-000000000000" />
</node>
</children>
</node>
<node id="GameMaster" />
<node id="LocomotionParams" />
</children>
</node>
<node id="GameObjects"> <!-- Male -->
<attribute id="MapKey" type="FixedString" value="5dd3feb0-89e5-44e9-9467-5d362b556763" /> <!-- UUID that tells the game this is its own unique object. Regenerate this before publishing the mod! -->
<attribute id="Name" type="LSString" value="Race_Male_Player" /> <!-- Internal name for race, does not affect anything in-game. -->
<attribute id="Type" type="FixedString" value="character" /> <!-- Tells the game that this is a Character root template. -->
<attribute id="ParentTemplateId" type="FixedString" value="acd7060a-43bd-4dc9-b050-9d9b2cf7b7df" /> <!-- The parent template for your race. Choosing the race that is most similar to your custom race is a safe bet. -->
<attribute id="SpellSet" type="FixedString" value="CommonPlayerActions" /> <!-- Gives your race common player actions as options -->
<attribute id="CharacterVisualResourceID" type="FixedString" value="48c09f41-f9db-4ad6-8aec-4db6482294fa" /> <!-- Tells the game what CharacterVisuals entry to use for the race. -->
<attribute id="Race" type="guid" value="3328d981-bf97-4e50-8961-fef8cd80c67e" /> <!-- The Unique Race UUID from races.lsx -->
<children>
<node id="Tags"> <!-- Add any tags you want here, including custom tags. -->
<children>
<node id="Tag">
<attribute id="Object" type="guid" value="00000000-0000-0000-0000-000000000000" />
</node>
</children>
</node>
<node id="GameMaster" />
<node id="LocomotionParams" />
</children>
</node>
</children>
</node>
</region>
</save>
This is the file that handles the RootTemplates for your race, which is a template that brings information from most of the other files together into one neat template package.
After you've gone through and edited all the files to match your new race, stop and test in game! Make sure everything works before continuing to the add-ons. If your game crashes upon load or upon selecting the race, some of the UUIDs that need to match probably don't match.
Let's say you want to add a subrace, or more than one subrace, to your custom race. Here's how to do that.
The most important thing you'll need to add a subrace is to add another Race entry in the Races.lsx.
<node id="Race"> <!-- Sub Race -->
<attribute id="DisplayName" type="TranslatedString" handle="h687c2b71g292eg4e12gbce8g29fb2edeceeb" version="1" /> <!-- Display name for the sub race, links to Community_Race_Template.loca.xml -->
<attribute id="Description" type="TranslatedString" handle="h3ed7c5e5gb17ag4b3dg8787g9663e1129dd9" version="1" /> <!-- Description for the sub race, links to Community_Race_Template.loca.xml -->
<attribute id="DisplayTypeUUID" type="guid" value="899d275e-9893-490a-9cd5-be856794929f" /> <!-- Humanoid display type -->
<attribute id="Name" type="FixedString" value="Community_SubRace" /> <!-- Internal name for sub race, doesn't affect anything in-game -->
<attribute id="ParentGuid" type="guid" value="3328d981-bf97-4e50-8961-fef8cd80c67e" /> <!-- Custom race Parent ID, this connects the entry to the original custom race entry above -->
<attribute id="ProgressionTableUUID" type="guid" value="ace6567b-ae51-474b-8643-136d0c1246a1" /> <!-- Sub Race Progression table, regenerate before releasing mod! -->
<attribute id="RaceEquipment" type="FixedString" value="EQ_Underwear_Humans"/> <!-- Default underwear for the sub race -->
<attribute id="RaceSoundSwitch" type="FixedString" value="Human" /> <!-- Sound made when selecting the sub race -->
<attribute id="UUID" type="guid" value="728faa82-273a-4dd1-a832-f776dbe331b7" /> <!-- Unique Sub Race UUID, regenerate before releasing mod! -->
</node>
Add one of these Race entries under your original Race entry for every subrace you want to make. Make sure the ParentGuid is set to the UUID for your original race, which will tie it to your original Race and inherit its colors and visuals entries.
You'll need to create new entries in your loca.xml file for the DisplayName and Description, and plug their handles into this Race node. If you don't do that, your race will show as Not Found.
You'll also need to create new root templates for each of the bodytypes for your subrace.
<node id="GameObjects"> <!-- Sub Race Female -->
<attribute id="MapKey" type="FixedString" value="5f1f84ac-1eae-415f-990c-efd34f3d95ef" /> <!-- UUID that tells the game this is its own unique object. Regenerate this before publishing the mod! -->
<attribute id="Name" type="LSString" value="SubRace_Female_Player" /> <!-- Internal name for race, does not affect anything in-game. -->
<attribute id="Type" type="FixedString" value="character" /> <!-- Tells the game that this is a Character root template. -->
<attribute id="ParentTemplateId" type="FixedString" value="7f52aa3a-40cf-4f75-b190-e773726a8939" /> <!-- The UUID for your original female race root template. -->
<attribute id="SpellSet" type="FixedString" value="CommonPlayerActions" /> <!-- Gives your race common player actions as options -->
<attribute id="CharacterVisualResourceID" type="FixedString" value="c6e16e66-2313-4a49-b0e7-1e38e7f25987" /> <!-- Tells the game what CharacterVisuals entry to use for the race. -->
<attribute id="Race" type="guid" value="728faa82-273a-4dd1-a832-f776dbe331b7" /> <!-- The Unique Sub Race UUID from races.lsx -->
<children>
<node id="Tags"> <!-- Add any tags you want here, including custom tags. -->
<children>
<node id="Tag">
<attribute id="Object" type="guid" value="00000000-0000-0000-0000-000000000000" />
</node>
</children>
</node>
<node id="GameMaster" />
<node id="LocomotionParams" />
</children>
</node>
<node id="GameObjects"> <!-- Sub Race Male -->
<attribute id="MapKey" type="FixedString" value="046a4c5e-060f-4221-a783-4750871da873" /> <!-- UUID that tells the game this is its own unique object. Regenerate this before publishing the mod! -->
<attribute id="Name" type="LSString" value="SubRace_Male_Player" /> <!-- Internal name for race, does not affect anything in-game. -->
<attribute id="Type" type="FixedString" value="character" /> <!-- Tells the game that this is a Character root template. -->
<attribute id="ParentTemplateId" type="FixedString" value="5dd3feb0-89e5-44e9-9467-5d362b556763" /> <!-- The UUID for your original male race root template. -->
<attribute id="SpellSet" type="FixedString" value="CommonPlayerActions" /> <!-- Gives your race common player actions as options -->
<attribute id="CharacterVisualResourceID" type="FixedString" value="48c09f41-f9db-4ad6-8aec-4db6482294fa" /> <!-- Tells the game what CharacterVisuals entry to use for the race. -->
<attribute id="Race" type="guid" value="728faa82-273a-4dd1-a832-f776dbe331b7" /> <!-- The Unique Sub Race UUID from races.lsx -->
<children>
<node id="Tags"> <!-- Add any tags you want here, including custom tags. -->
<children>
<node id="Tag">
<attribute id="Object" type="guid" value="00000000-0000-0000-0000-000000000000" />
</node>
</children>
</node>
<node id="GameMaster" />
<node id="LocomotionParams" />
</children>
</node>
Add these entries underneath your existing root templates, and make sure you change the ParentTemplateId and the Race values. (If you have multiple subraces, make a copy of these for each subrace.)
Here we'll tell the game to use your new subrace instead of the base race.
<node id="CharacterCreationPreset"> <!-- Sub Race Female Standard -->
<attribute id="BodyShape" type="uint8" value="0"/> <!-- 0 = Standard -->
<attribute id="BodyType" type="uint8" value="1"/> <!-- 1 = Female -->
<attribute id="CloseUpA" type="LSString" value="ELF_F_Camera_Closeup_A"/> <!-- Cameras for zooming in in CC -->
<attribute id="CloseUpB" type="LSString" value="ELF_F_Camera_Closeup_B"/> <!-- ^ -->
<attribute id="Overview" type="LSString" value="ELF_F_Camera_Overview_A"/> <!-- ^ -->
<attribute id="RaceUUID" type="guid" value="3328d981-bf97-4e50-8961-fef8cd80c67e"/> <!-- Race ID from races.lsx -->
<attribute id="RootTemplate" type="guid" value="5f1f84ac-1eae-415f-990c-efd34f3d95ef"/> <!-- Root template from Race_Root_Templates.lsf.lsx -->
<attribute id="SubRaceUUID" type="guid" value="728faa82-273a-4dd1-a832-f776dbe331b7"/> <!-- Subrace ID from races.lsx, 00000000-0000-0000-0000-000000000000 if no subrace -->
<attribute id="UUID" type="guid" value="04c52da3-cc33-4f63-88b4-462cdc7ebacc"/> <!-- UUID that tells the game this is its own unique object. Regenerate this before publishing the mod! -->
<attribute id="VOLinesTableUUID" type="guid" value="14df8f45-90af-4bd0-8024-42624da9976e"/> <!-- Sets the lines used when the player previews the voice in CC. Leaving it at the default is recommended. -->
</node>
<node id="CharacterCreationPreset"> <!-- Sub Race Male Standard -->
<attribute id="BodyShape" type="uint8" value="0"/> <!-- 0 = Standard -->
<attribute id="BodyType" type="uint8" value="0"/> <!-- 0 = Male -->
<attribute id="CloseUpA" type="LSString" value="ELF_M_Camera_Closeup_A"/> <!-- Cameras for zooming in in CC -->
<attribute id="CloseUpB" type="LSString" value="ELF_M_Camera_Closeup_B"/> <!-- ^ -->
<attribute id="Overview" type="LSString" value="ELF_M_Camera_Overview_A"/> <!-- ^ -->
<attribute id="RaceUUID" type="guid" value="3328d981-bf97-4e50-8961-fef8cd80c67e"/> <!-- Race ID from races.lsx -->
<attribute id="RootTemplate" type="guid" value="046a4c5e-060f-4221-a783-4750871da873"/> <!-- Root template from Race_Root_Templates.lsf.lsx -->
<attribute id="SubRaceUUID" type="guid" value="728faa82-273a-4dd1-a832-f776dbe331b7"/> <!-- Subrace ID from races.lsx, 00000000-0000-0000-0000-000000000000 if no subrace -->
<attribute id="UUID" type="guid" value="54a734e9-462a-480f-ab82-700a62a59142"/> <!-- UUID that tells the game this is its own unique object. Regenerate this before publishing the mod! -->
<attribute id="VOLinesTableUUID" type="guid" value="14df8f45-90af-4bd0-8024-42624da9976e"/> <!-- Sets the lines used when the player previews the voice in CC. Leaving it at the default is recommended. -->
</node>
The main change here is plugging the subrace UUID into the SubRaceUUID line and your new root templates into the RootTemplate line. You do not need to add new entries, you can simply use the ones that already exist! (However, if you were to have multiple subraces, you would need to add another copy of these nodes for each subrace.)
Now, stop and test the mod. You should see your subrace(s) appear in CC!