Ad placeholder

Modding:Coding An Item: Difference between revisions

Jump to navigation Jump to search
loca
No edit summary
(loca)
Line 35: Line 35:
==Meshes.lsx==
==Meshes.lsx==


We export the mesh, '''HUM_M_CLT_Headwear_Circlet_Silver_A''', we created to the MySweetMod/Generated/Public/MySweetMod/'''Assets''' Folder.  
First we export our mesh, '''HUM_M_CLT_Headwear_Circlet_Silver_A''', from Blender to the MySweetMod/Generated/Public/MySweetMod/'''Assets''' Folder.  


We now create 2 lsf.lsx for our MySweetMod\Public\MySweetMod\Content\Assets\Characters\'''[PAK]_Armor'''.
We now create 2 lsf.lsx for our MySweetMod\Public\MySweetMod\Content\Assets\Characters\'''[PAK]_Armor'''.
In these will be a visualbank (meshes),a materialbank (material) and a texturebank(textures). You can split them into or combine them all, when the multitool converts them they will all get merged together anyway. This seperation is for viewer ease as they can become very long. For our needs we are putting them into 2, a meshes and a texture/material one.
 
First, we add a meshes.lsx.
In these will be a visualbank (list of meshes),a materialbank (list of material) and a texturebank (list of textures). You can split them into their own pages or combine them all, it doesn't matter. When the multitool converts them they will all get merged together anyway. This seperation is for viewer ease as they can become very long. For our needs we are putting them into 2 lsx, a meshes and a texture/material one.
 
First, the meshes.lsx.
   <version major="4" minor="0" revision="4" build="602" />
   <version major="4" minor="0" revision="4" build="602" />
   <region id="VisualBank">
   <region id="VisualBank">
Line 65: Line 67:
  <attribute id="SoftbodyResourceID" type="FixedString" value="" />
  <attribute id="SoftbodyResourceID" type="FixedString" value="" />
  <attribute id="SourceFile" type="LSString" value="Generated/Public/MySweetMod/Assets/HUM_M_CLT_Headwear_Circlet_Silver_A.GR2" /> (Remember to set your own filepath for your meshes correctly.)
  <attribute id="SourceFile" type="LSString" value="Generated/Public/MySweetMod/Assets/HUM_M_CLT_Headwear_Circlet_Silver_A.GR2" /> (Remember to set your own filepath for your meshes correctly.)
  <attribute id="SupportsVertexColorMask" type="bool" value="False" />
  <attribute id="SupportsVertexColorMask" type="bool" value="False" /> '''You need this set to True if you want, say, pants to vanish when boots are equipped.'''
  <attribute id="Template" type="FixedString" value="Generated/Public/MySweetMod/Assets/HUM_M_CLT_Headwear_Circlet_Silver_A.Dummy_Root.0" /> (Remember to set your own filepath for your meshes correctly. Dummy Root may need to be renamed in Blender as a bone part depending on what you are making)
  <attribute id="Template" type="FixedString" value="Generated/Public/MySweetMod/Assets/HUM_M_CLT_Headwear_Circlet_Silver_A.Dummy_Root.0" /> '''(Remember to set your own filepath for your meshes correctly. Dummy Root may need to be renamed in Blender as a bone part depending on what you are making)'''
  <attribute id="_OriginalFileVersion_" type="int64" value="144115207403209020" />
  <attribute id="_OriginalFileVersion_" type="int64" value="144115207403209020" />
   
   
Line 84: Line 86:
  <node id="Objects">
  <node id="Objects">
  <attribute id="LOD" type="uint8" value="0" />  
  <attribute id="LOD" type="uint8" value="0" />  
  <attribute id="MaterialID" type="FixedString" value="06cee86f-8ca8-a19b-69ea-6fbac8b7516f" /> '''What material it links up to.'''
  <attribute id="MaterialID" type="FixedString" value="00000000000000000000004" /> '''What material it links up to.'''
  <attribute id="ObjectID" type="FixedString" value="HUM_M_CLT_Headwear_Circlet_Silver_A.HUM_M_CLT_Headwear_Circlet_Silver_A_Mesh.0" /> The .0 denotes mesh load order.
  <attribute id="ObjectID" type="FixedString" value="HUM_M_CLT_Headwear_Circlet_Silver_A.HUM_M_CLT_Headwear_Circlet_Silver_A_Mesh.0" /> The .0 denotes mesh load order.
  </node>
  </node>
Line 91: Line 93:
  <node id="Objects"> '''Extra entry for a Level of Detail mesh, which will be seen from a certain distance from the camera. In this case the LOD1.'''
  <node id="Objects"> '''Extra entry for a Level of Detail mesh, which will be seen from a certain distance from the camera. In this case the LOD1.'''
  <attribute id="LOD" type="uint8" value="1" /> '''What level of LOD it is'''
  <attribute id="LOD" type="uint8" value="1" /> '''What level of LOD it is'''
  <attribute id="MaterialID" type="FixedString" value="06cee86f-8ca8-a19b-69ea-6fbac8b7516f" />  
  <attribute id="MaterialID" type="FixedString" value="00000000000000000000004" />  
  <attribute id="ObjectID" type="FixedString" value="HUM_M_CLT_Headwear_Circlet_Silver_A.HUM_M_CLT_Headwear_Circlet_Silver_A_Mesh_LOD1.1" /> '''The .1 denotes mesh load order.'''
  <attribute id="ObjectID" type="FixedString" value="HUM_M_CLT_Headwear_Circlet_Silver_A.HUM_M_CLT_Headwear_Circlet_Silver_A_Mesh_LOD1.1" /> '''The .1 denotes mesh load order.'''
  </node>
  </node>
Line 100: Line 102:
  </node>
  </node>
And this code would stop the body's feet from loading in and clipping, ideal for boot items. See [https://bg3.wiki/wiki/Modding:VertexColorMaskSlots here for a full list of Vertex Mask Slots for the body.]
And this code would stop the body's feet from loading in and clipping, ideal for boot items. See [https://bg3.wiki/wiki/Modding:VertexColorMaskSlots here for a full list of Vertex Mask Slots for the body.]
                     
  </children>
  </children>
  </node>
  </node>
Line 112: Line 112:
==Materials and Texture .lsx==
==Materials and Texture .lsx==
Now, we move on to our materialbank.
Now, we move on to our materialbank.
I am not reproducing for length but should be easy enough to find an item's material to copy if you search the SourceFile listed.
 
I am not reproducing the entire material here, but should be easy enough to find an item material to copy if you search the SourceFile listed.
  <?xml version="1.0" encoding="utf-8"?>
  <?xml version="1.0" encoding="utf-8"?>
   <save>
   <save>
Line 121: Line 122:
     <children>
     <children>
  '''(BEGINNING OF MATERIAL)'''
  '''(BEGINNING OF MATERIAL)'''
  <node id="Resource">
  <node id="Resource">
  <attribute id="DiffusionProfileUUID" type="FixedString" value="" />
  <attribute id="DiffusionProfileUUID" type="FixedString" value="" />
Line 128: Line 131:
  <attribute id="SourceFile" type="LSString" value="Public/Shared/Assets/Materials/Characters/CHAR_BASE.lsf" />
  <attribute id="SourceFile" type="LSString" value="Public/Shared/Assets/Materials/Characters/CHAR_BASE.lsf" />
  <children>
  <children>
  <node id="ScalarParameters"> x7
  <node id="ScalarParameters"> '''x7
  (Cut for length)
  (Cut for length)'''
 
  There should be 4 Texture2DParameters in your material, for  
  There should be 4 Texture2DParameters in your material, for  
  <node id="Texture2DParameters"> NM cape
  <node id="Texture2DParameters"> NM cape
Line 139: Line 144:
  <attribute id="UniformName" type="FixedString" value="Texture2DParameter_normalmap_DefaultWrapSampler" />  These parts tells you what it is.
  <attribute id="UniformName" type="FixedString" value="Texture2DParameter_normalmap_DefaultWrapSampler" />  These parts tells you what it is.
  Look for normalmap, physicalmap, basecolor and MSKColor. We are just going to list the normalmap here.
  Look for normalmap, physicalmap, basecolor and MSKColor. We are just going to list the normalmap here.
   
   
  <node id="Vector3Parameters"> '''You can use these to set an inherent colour to your material.
  <node id="Vector3Parameters"> '''You can use these to set an inherent colour to your material.'''
  <attribute id="BaseValue" type="fvec3" value="0.7667436 0.7667436 0.7667436" />
  <attribute id="BaseValue" type="fvec3" value="0.7667436 0.7667436 0.7667436" />
  <attribute id="Enabled" type="bool" value="True" />
  <attribute id="Enabled" type="bool" value="True" />
Line 146: Line 152:
  <attribute id="GroupName" type="FixedString" value="02 Colour" />
  <attribute id="GroupName" type="FixedString" value="02 Colour" />
  <attribute id="IsColor" type="bool" value="True" />
  <attribute id="IsColor" type="bool" value="True" />
  <attribute id="ParameterName" type="FixedString" value="Metal_Primary" /><attribute id="Value" type="fvec3" value="1 1 1" />
  <attribute id="ParameterName" type="FixedString" value="Metal_Primary" /><attribute id="Value" type="fvec3" value="1 1 1" /> '''The 1 1 1 is the colour code here. You can use [https://www.nexusmods.com/baldursgate3/mods/502 BG3 Minitool] to convert a value.'''
  </node>
  </node>
  (Cut for length)
 
  '''(Cut for length)'''
  </node>
  </node>
  </children>
  </children>
Line 156: Line 163:
  </node>
  </node>
  </region>
  </region>
  (End of MaterialBank)
  '''(End of MaterialBank)'''
   
   
Now the material we have found, SourceFile "Public/Shared/Assets/Materials/Characters/CHAR_BASE.lsf" is a fairly standard shader without transparency or glowing. Materials that can be Transparent have 'Alpha' in the title. For example,  
Now the material we have found, SourceFile "Public/Shared/Assets/Materials/Characters/CHAR_BASE.lsf" is a fairly standard shader without transparency or glowing. Materials that can be Transparent have 'Alpha' in the title. For example, "Public/Shared/Assets/Materials/Characters/CHAR_BASE_AlphaTest_2S.lsf" or "CHAR_BASE_AlphaTest_2S_Dither" will enable alpha and make the mesh visible from both sides (turns off backface culling).
"Public/Shared/Assets/Materials/Characters/CHAR_BASE_AlphaTest_2S.lsf" or "CHAR_BASE_AlphaTest_2S_Dither" will enable alpha and make the mesh visible from both sides (turns off backface culling).


Materials with _VT at the end are useless to us, as they only work with virtual texture. A virtualtexture is essentially a box for textures that makes it load faster. We don't have any way of putting mods in virtualtextures ourselves so do not use those materials.
Materials with _VT at the end are useless to us, as they only work with virtual texture. A virtualtexture is essentially a box for textures that makes it load faster. We don't have any way of packing virtualtextures ourselves, so do not attempt to use those materials.




In order to make pants disappear when boots are put on, you may need to use a _Vertcut Material, such as 'Public/Shared/Assets/Materials/Characters/CHAR_BASE_VertCut.lsf', and ensure VertexMask is set to True in the mesh lsx. (As well as vertex painting the item itself the desired colour)
In order to make, say, pants disappear when boots are put on, you may need to use a _Vertcut Material, such as 'Public/Shared/Assets/Materials/Characters/CHAR_BASE_VertCut.lsf', and ensure VertexMask is set to True in the mesh lsx. (As well as vertex painting the item itself the desired colour)




Line 174: Line 180:
     <node id="Resource">
     <node id="Resource">
     <attribute id="Name" type="LSString" value="Generated/Public/MySweetMod/Assets/MSW_CoolCirclet_NM" /> The name is never referenced anywhere else but try to keep it unique.
     <attribute id="Name" type="LSString" value="Generated/Public/MySweetMod/Assets/MSW_CoolCirclet_NM" /> The name is never referenced anywhere else but try to keep it unique.
     <attribute id="ID" type="FixedString" value="00000000000000NM" /> This
     <attribute id="ID" type="FixedString" value="00000000000000NM" /> '''This links up to the node in the materialbank!'''
     <attribute id="SourceFile" type="LSString" value="Generated/Public/MySweetMod/Assets/MSW_CoolCirclet_NM.DDS" /> Capitalisation is IMPORTANT. Make sure your is not named MSW_CoolCirclet_NM.dds or it won't load.
     <attribute id="SourceFile" type="LSString" value="Generated/Public/MySweetMod/Assets/MSW_CoolCirclet_NM.DDS" /> '''Capitalisation is IMPORTANT. Make sure your texture is not named MSW_CoolCirclet_NM.dds or it won't load.'''
     <attribute id="Format" type="uint32" value="64" />  
     <attribute id="Format" type="uint32" value="64" />  
     <attribute id="Width" type="int32" value="1024" /> These dimensions don't need to be exact. I believe if it is smaller than listed, the texture will tile.
     <attribute id="Width" type="int32" value="1024" /> These dimensions don't need to be exact. I believe if it is smaller than listed, the texture will tile.
Line 209: Line 215:
  <attribute id="DisplayName" type="TranslatedString" handle="HANDLE1" version="1" /> '''Generate a handle for this in your .loca file.'''
  <attribute id="DisplayName" type="TranslatedString" handle="HANDLE1" version="1" /> '''Generate a handle for this in your .loca file.'''
  <attribute id="EquipSound" type="FixedString" value="ea27b98e-5fc0-4b0d-8602-e4a421dd481e" /> '''Not necessary but you may wish to specify one or it will use whatever default sound is in the parent template.'''
  <attribute id="EquipSound" type="FixedString" value="ea27b98e-5fc0-4b0d-8602-e4a421dd481e" /> '''Not necessary but you may wish to specify one or it will use whatever default sound is in the parent template.'''
  <attribute id="Icon" type="FixedString" value="Item_Cloth_Headwear_Circlet_Silver_A" /> '''This is a base game icon- custom icons require addition lsx and texture work'''
  <attribute id="Icon" type="FixedString" value="Item_Cloth_Headwear_Circlet_Silver_A" /> '''This is a base game icon- custom icons require addition lsx and texture work'''.
  <attribute id="LevelName" type="FixedString" value="" />
  <attribute id="LevelName" type="FixedString" value="" />
  <attribute id="MapKey" type="FixedString" value="0000000000000000000000000002" /> '''This links up to the armor.txt to form the armor.'''
  <attribute id="MapKey" type="FixedString" value="0000000000000000000000000002" /> '''This links up to the armor.txt to form the armor.'''
  <attribute id="Name" type="LSString" value="MY_COOL_NEW_CIRCLET" /> '''This links up to the armor.txt to form the armor.'''
  <attribute id="Name" type="LSString" value="MY_COOL_NEW_CIRCLET" /> '''This links up to the armor.txt to form the armor.'''
  <attribute id="ParentTemplateId" type="FixedString" value="4d2e0931-3a01-4759-834b-8ae36749daab" /> '''This tells the game roughly what kind of item it is, such as in this case a helmet. You should use the right kind for your item to avoid inherited problems.'''
  <attribute id="ParentTemplateId" type="FixedString" value="4d2e0931-3a01-4759-834b-8ae36749daab" /> '''This tells the game roughly what kind of item it is, such as in this case a helm. You should use the right kind for your item to avoid inherited problems. For example a shield will not know it is a shield without this ParentTemplate.'''
  <attribute id="PhysicsTemplate" type="FixedString" value="327039da-0827-811f-24e8-fc57e86c7ba2" />
  <attribute id="PhysicsTemplate" type="FixedString" value="327039da-0827-811f-24e8-fc57e86c7ba2" /> '''I believe similar to the above, this needs to be roughly the same type as the armour you are adding.'''
  <attribute id="Type" type="FixedString" value="item" />
  <attribute id="Type" type="FixedString" value="item" />
  <attribute id="UnequipSound" type="FixedString" value="f4c24367-83af-484e-bcc5-0438b8e64dec" />  '''Not necessary but you may wish to specify one or it will use whatever default sound is in the parent template.'''
  <attribute id="UnequipSound" type="FixedString" value="f4c24367-83af-484e-bcc5-0438b8e64dec" />  '''Not necessary but you may wish to specify one or it will use whatever default sound is in the parent template.'''
  <attribute id="VisualTemplate" type="FixedString" value="2136f57a-a35f-c2fe-69fb-29afa9ebc8db" /> This is the mesh mapkey to the LOOT model (the one that appears when you examine it, or throw the item. For a weapon, the LOOT model and the item model are the same.  
  <attribute id="VisualTemplate" type="FixedString" value="2136f57a-a35f-c2fe-69fb-29afa9ebc8db" /> '''This is the mesh mapkey to the LOOT model. The LOOT model is the one that appears when you examine it, or throw the item. For a weapon, the LOOT model and the item model are the same.'''
  <attribute id="_OriginalFileVersion_" type="int64" value="144115207403209032" />
  <attribute id="_OriginalFileVersion_" type="int64" value="144115207403209032" />
  <children>
  <children>
Line 229: Line 235:
  <node id="DreadShortHair" />
  <node id="DreadShortHair" />
  <node id="LongHair" />
  <node id="LongHair" />
  <node id="ParentRace"> '''The parentrace nodes set the item to use race-specific meshes for githyanki, Dragonborn and Tiefling.  Unless this line is added and  specified, they  will use Human Body or Strong Human Body. (Which may be fine for some races such as Tieflings.)'''
  <node id="ParentRace">  
<children>
 
<node id="Object">
'''The parentrace nodes set the item to use race-specific meshes for githyanki, Dragonborn and Tiefling.  Unless this line is added and  specified, they  will use Human Body or Strong Human Body. (Which may be fine for some races such as Tieflings.)'''
<attribute id="MapKey" type="guid" value="6503c830-9200-409a-bd26-895738587a4a" /> Tiefling Male
<children>
<attribute id="MapValue" type="guid" value="00000000-0000-0000-0000-000000000000" /> This zeroes it out.
<node id="Object">
</node>
<attribute id="MapKey" type="guid" value="6503c830-9200-409a-bd26-895738587a4a" /> Tiefling Male
  '''(Removed for length as these all follow the same format)'''
<attribute id="MapValue" type="guid" value="00000000-0000-0000-0000-000000000000" />  
</children>
 
  </node>
</node>
<node id="ShortHair" />
  '''(The other parentrace overrides all removed for length as they all follow the same format - the race UUID and the 0 mapvalue)'''
<node id="Slot">
 
<attribute id="Object" type="FixedString" value="Headwear" />
</children>
</node>
 
<node id="Slot">
 
<attribute id="Object" type="FixedString" value="Hair" />
</node>
</node>
<node id="ShortHair" />
<node id="Slot">
<attribute id="Object" type="FixedString" value="Headwear" />
</node>
      <node id="Slot">
<attribute id="Object" type="FixedString" value="Hair" />
</node>
  <node id="VisualSet">
  <node id="VisualSet">
  <attribute id="BodySetVisual" type="FixedString" value="" />
  <attribute id="BodySetVisual" type="FixedString" value="" />
  <attribute id="ShowEquipmentVisuals" type="bool" value="False" />
  <attribute id="ShowEquipmentVisuals" type="bool" value="False" />
  <children>
  <children>
<node id="MaterialOverrides"> Sets colours for this one specific
<node id="MaterialOverrides"> Sets colours for this one specific item, overriding the ones set in the material.
<attribute id="MaterialResource" type="FixedString" value="" />
<attribute id="MaterialResource" type="FixedString" value="" />
<children>
<children>
<node id="MaterialPresets" />
<node id="MaterialPresets" />
 
  '''(We can add any colour available to us (cloth, leather, accent) but this circlet is only metal 1 so we only need to list metal 1.)'''
  '''(We can add any colour available to us (cloth, leather, accent) but this circlet is only metal 1 so we only need to list metal 1.)'''
   
   
Line 267: Line 281:
  </children>
  </children>
  </node>
  </node>
  <node id="Visuals">
  <node id="Visuals">
  <children>
  <children>
Line 278: Line 294:
  </children>
  </children>
  </node>
  </node>
(Removed for length - all the other mapkeys/mapvalues of every race this item is available for)
'''(Removed for length - all the other mapkeys/mapvalues of every race this item is available for)'''
  </children>
  </children>
  </node>
  </node>
Line 295: Line 311:


==Loca==
==Loca==
Now, let's see how this links up to the localisation.
Now, let's see how this links up to the localisation. Remember to name your loca loca.xml so it converts properly.
 
You can generate a handle by ticking the Handle box next to 'GENERATE' on the Multitool. It is much like an UUID but it starts with an H.
You can generate a handle by ticking the Handle box next to 'GENERATE' on the Multitool. It is much like an UUID but it starts with an H.
The version number has to do with internal references. Just make all of yours say 1.
  <?xml version="1.0" encoding="utf-8"?><contentList>
  <?xml version="1.0" encoding="utf-8"?><contentList>
  <content contentuid="HANDLE1" version="1">Circlet</content>  
  <content contentuid="HANDLE1" version="1">Circlet</content>  
  <content contentuid="HANDLE2" version="1">My circlet is cool.</content>
  <content contentuid="HANDLE2" version="1">My circlet is cool.</content>
<content contentuid="HANDLE3" version="1">Circlet Passive</content>
<content contentuid="HANDLE4" version="1">While the wearer has Mage Armour, each successful Saving throw causes the source of the Saving Throw to take 1-4 Radiant damage.</content>
  </contentList>
  </contentList>


==Armor and Passives==
==Armor and Passives==
Meanwhile in your '''Armor.txt''', they link up like this:
Meanwhile in your '''Armor.txt''', they link up like this:
You can look at the games own armor.txt for ideas of what to put here. You can delete a lot of this, all you really need is the entry, the type, what slot it uses and the RootTemplate.
 
You can look at the games own armor.txt for ideas of what to put here. You can delete what you don't wish to add, all you really need is the entry, the type, what slot it uses and the RootTemplate.


  Armor.txt
  Armor.txt
Line 320: Line 343:
  data "MaxAmount" "1"  
  data "MaxAmount" "1"  


If adding a custom passive, your '''Passive.txt''' will look like this.
If adding a custom passive, your '''Passive.txt''' will look like this. You don't need a passive.txt at all, this is just for the ambitious.


The example passive code is borrowed from Isobel's armor.
The example passive code is borrowed from Isobel's armor.

Navigation menu