-
Notifications
You must be signed in to change notification settings - Fork 0
3. MultiEffectInfos
- MultiEffectInfos Defined
- MEI Setup
- Generating UUIDs
- Attribute ID Definitions
- EffectResourceGuid
- Target Bones
- Folder Structure
Alrighty! Now we've reached the point of basic levels of crafting our own visual effects. MultiEffectInfos, or MEI's for short! This particular step is an easy one, but it can throw you off if you're not prepared. There's Good news, great news and Bad news, sort of:
If your goal is merely to mix and match previous effects without getting too complicated, this is the place to do it. The same can be said for the RootTemplates, but we'll discuss that later.
These effects can be very particular about the TargetBone
placements.
I have already previously released a MEI guide on nexus, with a brief tutorial and templates for free use. You can find that here:
Now that we have access to the MEI, we can see how they're set up. Since we were using Black Hole as our base earlier, you should have a file that looks like this
<?xml version="1.0" encoding="utf-8"?>
<save>
<version major="4" minor="0" revision="9" build="320" lslib_meta="v1,bswap_guids" />
<region id="MultiEffectInfos">
<node id="MultiEffectInfos">
<attribute id="UUID" type="guid" value="94280a3f-4d08-453d-be6a-1a3282d46db1" />
<attribute id="Name" type="LSString" value="TAD_BlackHole_PositionEffect" />
<children>
<node id="EffectInfo">
<attribute id="UUID" type="guid" value="00faf96a-b8d6-4335-8304-b38315dee369" />
<attribute id="EffectResourceGuid" type="guid" value="dfa88d8b-b79a-27ca-2cc2-0f48830505e4" />
<attribute id="DetachSource" type="bool" value="False" />
<attribute id="DetachTarget" type="bool" value="True" />
<attribute id="KeepRotation" type="bool" value="False" />
<attribute id="UseOrientDirection" type="bool" value="False" />
<attribute id="UseDistance" type="bool" value="False" />
<attribute id="UseScaleOverride" type="bool" value="False" />
<attribute id="KeepScale" type="bool" value="True" />
<attribute id="MainHand" type="bool" value="False" />
<attribute id="OffHand" type="bool" value="False" />
<attribute id="MinDistance" type="float" value="0" />
<attribute id="MaxDistance" type="float" value="0" />
<attribute id="BindSourceTo" type="FixedString" value="SourceEntity" />
<attribute id="BindTargetTo" type="FixedString" value="TargetEntity" />
<attribute id="Pivot" type="FixedString" value="Target" />
<attribute id="DamageType" type="uint32" value="0" />
<attribute id="VerbalIntent" type="uint32" value="0" />
<attribute id="StartTextKey" type="LSString" value="VFX_Cast_01" />
<attribute id="Enabled" type="bool" value="True" />
</node>
<node id="EffectInfo">
<attribute id="UUID" type="guid" value="f7492887-557d-4e49-a3c7-f4b8cf860b63" />
<attribute id="EffectResourceGuid" type="guid" value="24161a33-9ef2-5220-79d8-4ac6c5fb4a14" />
<attribute id="DetachSource" type="bool" value="False" />
<attribute id="DetachTarget" type="bool" value="True" />
<attribute id="KeepRotation" type="bool" value="False" />
<attribute id="UseOrientDirection" type="bool" value="False" />
<attribute id="UseDistance" type="bool" value="False" />
<attribute id="UseScaleOverride" type="bool" value="False" />
<attribute id="KeepScale" type="bool" value="True" />
<attribute id="MainHand" type="bool" value="False" />
<attribute id="OffHand" type="bool" value="False" />
<attribute id="MinDistance" type="float" value="0" />
<attribute id="MaxDistance" type="float" value="0" />
<attribute id="BindSourceTo" type="FixedString" value="SourceEntity" />
<attribute id="BindTargetTo" type="FixedString" value="TargetEntity" />
<attribute id="Pivot" type="FixedString" value="Target" />
<attribute id="DamageType" type="uint32" value="0" />
<attribute id="VerbalIntent" type="uint32" value="0" />
<attribute id="StartTextKey" type="LSString" value="VFX_Cast_03" />
<attribute id="Enabled" type="bool" value="True" />
</node>
</children>
</node>
</region>
</save>
In the case of Black Hole, it has no targetbones to worry about, which probably isn't that helpful for the sake of this tutorial, but we'll get there in the end. The first thing you want to notice is that it is in XML format. This is a requirement if you want them to function. Another requirement, depending on the tool you use to pack your mod, is that they are saved as :
.lsf
This is because if you are packing your mod contents via lslib, you will need to manually pack all of your files.
or
lsf.lsx
This is because if packing with BG3-Modders-Multitool, it has a built in converter that when you pack the mod folder as a whole, it will automatically convert lsf.lsx
to .lsf
.
Now, before we discuss the attribute id
s, I want to put out the top of the MEI.
<?xml version="1.0" encoding="utf-8"?>
<save>
<version major="4" minor="0" revision="9" build="320" lslib_meta="v1,bswap_guids" />
<region id="MultiEffectInfos">
<node id="MultiEffectInfos">
The first line <?xml version="1.0" encoding="utf-8"?>
defines to the text editor the language used for the form.
The second line <save>
is the opening block of any XML, followed by the <version major="4" minor="0" revision="9" build="320" lslib_meta="v1,bswap_guids" />
. The numbers in the major, minor, revision, and build aren't important, as long as the major is 1 or higher.
The next line <region id="MultiEffectInfos">
is our region id. This tells the game what the entire block will focus on. Unlike Merged files, you won't see a region id besides MultiEffectInfos
. The same will apply to the <node id="MultiEffectInfos">
.
Let's take a look at the attribute ids and define, to the best of my ability, what they mean and do. Our first culprit is:
Our first Attribute ID
<attribute id="UUID" type="guid" value="94280a3f-4d08-453d-be6a-1a3282d46db1" />
is the unique identifier. That's the one you'd find in the Spell attributes such as data "PositionEffect" "94280a3f-4d08-453d-be6a-1a3282d46db1"
for a spell. If you want to add or make any changes to this, first you will need to change this value to a new, unique UUID, which will later be put in that same, aforementioned effect data. The most simple way to do so is to use BG3-Modders-Multitool to generate a new, unique UUID, by clicking the Generate button, as such:
Make sure the Handle Checkbox is unchecked, like so:
After you have clicked Generate, it should look something like this, only with a different UUID:
Once you have your new UUID, you will replace the value attribute:
From
<attribute id="UUID" type="guid" value="94280a3f-4d08-453d-be6a-1a3282d46db1" />
To
<attribute id="UUID" type="guid" value="186d5709-de2a-4738-9b08-30065f17800e" />
Only with your new UUID instead of this one specifically. You may then feel free to change the value of <attribute id="Name" type="LSString" value="TAD_BlackHole_PositionEffect" />
to whatever you want.
Your next step will be to take the UUID of the <node id="EffectComponent">
found here:
<attribute id="UUID" type="guid" value="00faf96a-b8d6-4335-8304-b38315dee369" />
and repeat the same steps as you did with the master UUID for the MEI.
Do not replace the UUID in the EffectResourceGUID just yet.
The first thing to note about the attribute id's inside the EffectInfo
are mostly bool
(ean) values, which mean True or False. Also note, that the bool values are in relation to whatever they are attached to. So an effect, say, normally meant for the Root (or Caster Base), that gets attached to the CastFX (Often depicted as a spell casting animation before the spell trigger.), might need different boolean sets.
The attribute IDs DetachSource
and DetachTarget
are generally for determining if an effect remains attached to a specific TargetBone
. We will get into TargetBone
in a moment.
The next attribute id we'll look at is KeepRotation
. For effects that are not intended to be attached to specific things, you will want this set to True
. At least, if you don't want a specific effect rotating around every time your character moves, this tells the game to let the lsfx stick to it's initial rotation patterns.
Following up, we have UseOrientDirection
. This attribute is in relation to A) The direction your character is facing, and B) The direction the lsfx has defined for the effect components. More on that later.
The attribute ids UseDistance
and UseScaleOverride
are referencing specialized nodes inside the lsfx. The id UseDistance
determines effects changes by distance travelled, and the id UseScaleOverride
is for the size change in relation to UseDistance
scale settings, inside the lsfx.
One of the more important attribute ids is KeepScale.
This tells the game to maintain the scale to the attached TargetBone
in relation to the MEI and the lsfx.
The following attributes should often be left as is:
<attribute id="MainHand" type="bool" value="False" />
<attribute id="OffHand" type="bool" value="False" />
<attribute id="MinDistance" type="float" value="0" />
<attribute id="MaxDistance" type="float" value="0" />
<attribute id="BindSourceTo" type="FixedString" value="SourceEntity" />
<attribute id="BindTargetTo" type="FixedString" value="TargetEntity" />
<attribute id="DamageType" type="uint32" value="0" />
<attribute id="VerbalIntent" type="uint32" value="0" />
Furthuremore, the attribute id Pivot
is associated with whether or not something is a Beam Effect. This should generally be set to Target
unless the effect is a direct beam, such as Lightning Bolt or SunBeam.
One of the more unique attribute ids is StartTextKey
. It's interesting for a variety of reasons. To start, it's the only attribute id besides the MEI name that has a variety of values it could be. Not every EffectInfo
will have one of these. The purpose of this id is to schedule a trigger time. So, if you want one effect to play after another, rather than at the same time in a Prepare effect, you might place the value at "VFX_Prepare_01"
. This would tell the effect with this StartTextKey
to trigger after the first effect triggers, giving a chain reaction effect. There are a lot of StartTextKey
values, and I encourage you to look through the various MEI's to find ones that might fit your needs for an effect chain.
The next attribute id is Enabled
. It's fairly self explanatory. If set to false, that EffectInfo
will not trigger at all. This is only really useful if you are attempting to test the visuals if individual EffectInfos
without deleting an entire block.
The FINAL attribute id we'll discuss is the EffectResourceGuid
. Without this, the EffectInfo
is useless. You will find the EffectResourceGuid
in an Effects Merged VisualBanks section. With this, you can browse to your hearts content, experimenting with different VFX uuids.
Not all VFX will work simply by placing the UUID into the EffectResourceGuid
. Also, some will not work for the TargetBone
they are attached to.
Now, you've seen me repeatedly mention TargetBone
without any reference. Well, it's time I cleared that up. To begin, as their name suggests, they are what an EffectInfo
is attached to. They usually look something similar to this:
<node id="EffectInfo">
<attribute id="BindSourceTo" type="FixedString" value="SourceEntity" />
<attribute id="BindTargetTo" type="FixedString" value="TargetEntity" />
<attribute id="DetachSource" type="bool" value="False" />
<attribute id="DetachTarget" type="bool" value="False" />
<attribute id="EffectResourceGuid" type="guid" value="50678fd2-db36-ee2e-89a8-672f88985f52" />
<attribute id="Enabled" type="bool" value="True" />
<attribute id="KeepRotation" type="bool" value="False" />
<attribute id="KeepScale" type="bool" value="False" />
<attribute id="MainHand" type="bool" value="False" />
<attribute id="MaxDistance" type="float" value="0" />
<attribute id="MinDistance" type="float" value="0" />
<attribute id="OffHand" type="bool" value="False" />
<attribute id="Pivot" type="FixedString" value="Target" />
<attribute id="UUID" type="guid" value="a0d59380-583d-4f20-8b7c-83cae56b14b9" />
<attribute id="UseDistance" type="bool" value="False" />
<attribute id="UseOrientDirection" type="bool" value="False" />
<attribute id="UseScaleOverride" type="bool" value="False" />
<children>
<node id="TargetBone">
<attribute id="Value" type="LSString" value="Dummy_OverheadFX" />
</node>
</children>
</node>
As you can see, there is a new bit of information called <node id="TargetBone">
followed by <attribute id="Value" type="LSString" value="Dummy_OverheadFX" />
. In this case, the visual effect would be attached just over the head.
There are a large quantity of TargetBone
(s) to choose from, giving you endless possibilities when creating visual effects. There is also a node id called SourceBone
, but this is exclusively for an effect that departs its source, in a sense. Usually projectiles and beams count here. In some cases, you'll also come across this:
<children>
<node id="TargetBone">
<attribute id="Value" type="LSString" value="Dummy_EyeFX_01" />
</node>
<node id="TargetSkeletonSlot">
<attributeid="Value" type="LSString" value="1">
</node>>
</children>
This particular node ID is generally reserved for Eye sockets, and other special occasions. Some commonly used TargetBones
and their locations are listed below:
- Dummy_CastFX: Just in Front of the Character
- Dummy_BodyFX: The whole body
- Dummy_Root: The base of the character, or ground.
- Dummy_FX: A wieldable object, often defined by tags.
There are many more, too many to list here, even. Again, I encourage you to explore those MEI's and find those effects that suit you.
Make sure, once you are finished, that all of your tags are closed properly. Any Tag ending in />
is self closed, so you do not need to worry about it. However, any tag that only has <>
without a /
, need to be closed manually, at the same indent level as the tag it's closing. The way to close the tag is `'. Make sure the tag id name matches the id tag it's closing.
Make sure when you save the file, to save the extension in the following manner:
-
.lsf.lsx
if using BG3-Modders-Multitool -
.lsx
if using lslib and convert it to.lsf
with lslib LSF/LSX Converter.
The File name itself does not matter.
The Folder structure you want for your MEIs is as follows:
Now, as we have learned MEI's can do a lot, and lead to a lot interesting results. However, they are limited in that there are a few things they cannot do, at least not effectively. That's where RootTemplates come in.
- Overview
- Sample Projects
- Action Resources
- Spells
- Passives
- Statuses
- Items
- Races
- Classes
- Scripts
- Visual Resources
Setting up a Development Environment (BEING REWRITTEN)
- A Modder's Guide to Git
- Recommended/Required Tools
- Creating Your Folder Structure
- Working with the Repo
- How to Use the Multitool
- Class Descriptions
- Ability Distribution Presets
- Progressions
- Localization
- Abilities, Passives, and Spells
- Passive and Spell Lists
- Custom Equipment
- Class Icons
- Skill Icons (TODO)
- Handling Subclasses (TODO)
- Race Entry
- Root Templates
- Character Visuals
- Character Creation
- Localization
- Racial Feats
- Racial Progressions
- Tags
- Custom Icons