Art Assets in Civilization 6: A Modding Guide

Deliverator

Graphical Hackificator
Joined
Feb 12, 2008
Messages
4,806
Location
London, UK
Introductory Note

This post is more of an architectural overview of 3D Art in Civilization VI. It also covers 2D textures. If you want step-by-step tutorials for particular tasks then you can follow one the following guides:

Leugi's Civ 6 Unit Asset Tutorials - Level 1
Introduces the process of unit asset previewing, tints, and creating artdefines.

Leugi's Civ 6 Unit Asset Tutorials - Level 2
Introduces creating custom assets, changing the animations, adding xlps, icons and mounted units.

Integrate a New 3D Model as a Unit by ShiroToraRyu
A step by step Tutorial on how to integrate a Unit 3D Model into the game as a new custom Unit with unique 3D Art.

Make a Custom World Wonder Model for Civ VI by ShiroToraRyu

Integrate a completed 3D Model from Blender to Civilization VI as a new custom Wonder.

Beginner's Guide To 3D Art Assets - Buildings by esosorcdc
This guide is a step-by-step tutorial on creating and implementing 3D art for buildings.

Re-texturing 3D Assets by ChimpanG
Covers the basics of re-texturing existing assets.

Re-texturing Visual Effects (VFX) by Deliverator
Covers re-skinning visual effects

How to use the in-game console to reload Artdef files etc



Background for Civ 5 Modders

Civ 6 uses an updated version of the Granny engine that was used in Civ 5. The .fgx files used in Civ 6 are equivalent to the .gr2 files used in Civ 5 and the process for creating and editing them pretty much the same. Instead of Granny Viewer there is FGX Viewer which looks the same and works in the same way. Instead of the Nexus Buddy 2 tool for working with Civ 5 .gr2 files there is CivNexus6 for working with .fgx files. The Blender scripts pack containing scripts for import/export is available.

Major differences between Civ 5 and Civ 6:

1. The .fgx 3D model files cannot be used directly in a mod as was the case with Civ 5 .gr2 files - they need to be "cooked" into .blp (Binary Library Package) files.
2. Rather than Materials and Textures being specified inside the .gr2 file, they are specified by the .mtl (Material metadata file) and .tex (Texture metadata file) along with the .dds texture images. Everything is then cooked into .blp files by the asset cooking process.

Under the hood, the format of skeletons and animations seems to be the same between Civ 5 .gr2 and Civ 6 .fgx however meshes do need to be converted. See here for a tutorial on how to update Civ 5 / Civ BE 3D graphics for Civ 6.


Tools

From Sid Meier's Civilization VI SDK:
ModBuddy - This tool is for assembling and building your mods.
Asset Editor - This tool is launched from within ModBuddy and is used to create, import and edit different files.

Useful information on the Mod Tools from the developer who worked on them can be read here.

For 3D:
CivNexus6 and Blender. You can use paid-for options but you'd still need to go via Blender to use CivNexus6.

For working with 2D textures:
Photoshop: Use .DDS plugin and export your .DDS Uncompressed.

Gimp 2: Use .DDS plugin and use Export as ABGR8 format, .DDS with Compression=None.

Paint.NET: It can only open some vanilla .dds files directly (generally albedo and normal maps), for the rest (AO, metalness, gloss, tint) you need to use Gimp 2 then you can copy/paste or save to PNG/DDS. For saving DDS from Paint.NET use the B8G8R8A8 format. Still my most used art package for modding!

Some .dds textures can only be opened with Gimp 2 and the .DDS plugin linked above - even Photoshop doesn't handle them all properly.


Walkthrough - NewUserTest Example ModBuddy Project


In classic "Here's one I made earlier!" fashion the best initiation is probably a walkthrough of an example Modbuddy project. I'll use this to introduce the (many) different file types and their role in making new 3D assets.

Download the example ModBuddy project here.

1. Install the Sid Meier's Civilization VI SDK and Sid Meier's Civilization VI SDK Assets.
2. Unzip the downloaded example and copy the outer "NewUnitTest" folder to "My Documents\Firaxis ModBuddy\Civilization VI" folder. This is a key location as this is where your Modbuddy projects are kept.
3. Launch ModBuddy.
4. Open "NewUnitTest.civ6sln". This will open the example project.


The example is a new T-34 tank unit model. Although the information here is for a new unit, the information should be relevant for other model types (Improvements, Wonders, Resources, Leaders, etc). Eventually I will try and create an example ModBuddy for each type.

Other 3D Art Examples:
Moar Units Art Cooker Project


Filetypes


Here is a brief guide to the different filetypes that can be used to create new art assets in ModBuddy:

Civ 6 Graphical Asset ERD - Page 1.png


Assets (.ast files)

These are the metadata files for any kind of 3D asset. The name of these is referenced by .xlp (XML Library Package definition) for cooking into .blp library files.

In the case of Units the .ast file is where everything is pulled together before cooking - Geometries, Materials and Animations etc.

It is possible to do some cool things just by making a copy of a vanilla .ast file and then editing it. For example, because the naming of all the human skeletons used by the different Armor .fgx files is consistent (unlike in Civ 4/5!). I can combine a particular Armor with a different human animation set to the one it is associated with in the game. See here for an example of combining Archer animations with a Crossbowman Armor.

In the case of the T-34 example the T34_Tank.ast file was made in the following way:
1) Make a copy of the TankA.ast file from the pantry and copy it to within the ModBuddy project Assets folder. Rename it to T34_Tank.ast.
2) Inside ModBuddy, right-click in the Solution Explorer and select Add > Existing Item... then pick the T34_Tank.ast file. The Assets folder should be created automatically in ModBuddy so no need to create it manually.
3) Edit m_Name text field to match the name of the file without the extension "T34_Tank".
4) Then replace the m_Geometry entry with the data from my new model - see Geometries section below:

Code:
<m_GeometrySet>
    <m_ModelInstances>
        <Element>
            <m_Name text="Root"/> <!-- the Model name -->
            <m_GeoName text="T34_Tank"/> <!-- the name of the corresponding Geometry metadata (.geo file) -->
            <m_GroupStates>
                <Element>
                    <m_Values>
                        <m_Values>
                            <Element class="AssetObjects::ObjectValue">
                                <m_ObjectName text="T34_Material"/>       <!-- the name of the Material metadata (.mtl file) to use to skin this model.
                                <m_eObjectType>MATERIAL</m_eObjectType>
                                <m_ParamName text="Material"/>
                            </Element>
                        </m_Values>
                    </m_Values>
                    <m_GroupName text="T34_Material"/> <!-- The name of the Material that the Mesh is bound to inside the .fgx - can use FGX Viewer/CivNexus6 to view this. -->
                    <m_MeshName text="T34"/> <!-- The name of the Mesh inside the .fgx -->
                    <m_StateName text="Default"/>
                </Element>
            </m_GroupStates>
        </Element>
    </m_ModelInstances>
</m_GeometrySet>

Everything else defined in the .ast file (which Animations to use, Sound and Visual FX, etc) remain the same as for the original TankA.ast. (There's one exception to this - I attached the muzzle flash to a new bone FX_Bone_Muzzle.002 instead of FX_Bone_Muzzle).

Super-helpfully the Asset Editor has a Asset Previewer facility so you can see how your Asset will render in game:

astv2.jpg


You can also test attaching other assets (e.g. Weapons, Bodies, Helmets) to Attachment Points. (Thanks to @sukritact for the tip off)



On Reskinning: If I wasn't bringing in a new model but just wanted to reskin a vanilla unit I would need to edit even less. The only thing I'd need to edit would be point to my new Material (.mtl) file. For example to reskin the Tank I would simply edit the Material for the Tank_AShape mesh like this:

Code:
...
<Element>
    <m_Values>
        <m_Values>
            <Element class="AssetObjects::ObjectValue">
                <m_ObjectName text="MyLovelyNewTankMaterial"/>    <!- point to my new Material metadata (.mtl file)
                <m_eObjectType>MATERIAL</m_eObjectType>
                <m_ParamName text="Material"/>
            </Element>
        </m_Values>
    </m_Values>
    <m_GroupName text="MaterialFBXASC032FBXASC035292"/>
    <m_MeshName text="Tank_AShape"/>
    <m_StateName text="Default"/>
</Element>
...


Materials (.mtl files) and Textures (.tex) files

You can think of the Material as the skin of a model. The Material consists of multiple layers each of which affect how the model appears in game. The Material metadata file (.mtl file) points to multiple Texture metadata files (.tex files). Each .tex file is paired with a .dds file containing the actual texture 2D image.

@sukritact has written a much better explanation of the different texture types here. I recommend reading over that first!

For a Unit I need to implement six texture layers:

----

BaseColor

This is the base color skin of your model. If you are making a new skin rather than using an existing .dds, I would advise saving your .dds uncompressed with mipmaps - Kaiser algorithm seems to give good results.

To create a new .tex/.dds pair out of your source .dds you will need to use the Asset Editor.

1) Lauch the Asset Editor from the Tools menu in ModBuddy.
2) Create a new document using either File > New or Ctrl-N or the document icon in the top left corner.
3) Pick "Texture"
4) Enter a sensible name for your texture for example "T34_Base_Texture"
5) Pick the Class Name "Generic_BaseColor" - this is the type of texture you want to make.
5) To the left of Source File Path navigate to your source .dds and select it.
6) Save using Ctrl-S or the disk icon. This will create both the .tex Texture metadata file and an amended copy of your .dds file within the ModBuddy projects Textures folder.

Normal (can be defaulted to 4x4 image of RGB(128,128,255))

The Normal texture is basically a way of adding more 3D detail to model using a 2D image file. This Normal Map Online web application is great tool both for understanding how Normal maps and creating them from greyscale images.

A RGB value of (128,128,255) corresponds to flat, so if you don't want to bother actively using this layer you can just create a 4x4 image of this color and save to .dds (4x4 is the smallest size a .dds file can be and can be used for any single color textures to save filesize). Once you have your flatNormal_4x4.dds saved you can create your .tex and .dds pairing as before using the Asset Editor this time selecting the Class Type "Generic_Normal".

If you want to make a proper Normal texture then you can generate a crude one by like this:

1) Greyscale your base texture.
2) Smooth out any rough looking areas that you don't want to appear bumpy or paint over them with (128,128,128) grey.
3) Use the Normal Map Online tool to generate your Normal texture file before saving it as a .dds.
4) Create your .tex and .dds pairing as before using the Asset Editor this time selecting the Class Type "Generic_Normal".


AO (can be defaulted to a 4x4 image of white)

The Ambient Occlusion (AO) texture is a method to approximate how bright light should be shining on any specific part of a surface, based on the light and its environment (says the internet!). Essentially this is the shading layer - shading should really be left out of the base layer.

Although this can be defaulted to all white. Blender does have the in-built facility for baking 2D AO textures from 3D models which I've had some success with. (More later)


Metalness (can be defaulted to a 4x4 image of black)

The Metalness affects how reflections look on the reflective parts of the model. In the real world reflections in metal are more clear and sharp than reflections in other surfaces such as paint, wood, etc. Apparently the metal map should either use black or white - white for metal parts, black for non-metal parts. Grey areas are not advised. I haven't really played with this much yet but I guess it would only be used for naked steel and the like. Even for painted metal you wouldn't use this.

Glossiness (can be defaulted to a 4x4 image of black)

The Glossiness affects how reflective of lighting the different parts of the model are - white for completely reflective and black for completely non-reflective.

TintMask (can be defaulted to a 4x4 image of black)

The TintMask controls how much of the base Tint color shows through the base layer. You can think of it like an alpha mask where white=transparent and black=opaque. Using this you can make parts of your mesh re-colorable using the Tint colors in Units.artdef.


By the time you've made all the Textures you would have 12 files - one .tex and one corresponding .dds for each of the six Textures.

The Material file (.mtl file) can then be made to bring all these together. You can either make this using the Asset Editor or by making a copy of one of the vanilla .mtl files from the pantry.

Bear in mind that once you've made a .tex/.dds pair for Texture that can be reused in as many different materials as you like - especially useful for re-using black/white/flatNormal 4x4 textures.

----

Geometries (.geo files)

The .fgx model and .geo Geometry metadata file can both be made using CivNexus6. You can add them into your mod using Add > Existing Item.

For Units people will mostly be rigging new meshes to existing skeletons/animations as with Civ 5/Civ 4.

The high level process for this is:
1) Load the model you want to base your new Unit on into CivNexus6.
2) Export the model to .nb2 format.
3) Load the model into Blender using the scripts.
4) Do whatever modelling (mesh import and adjustment) and rigging (assigning the vertices of the mesh to bone weights via vertex groups) you need to do in Blender. *
5) Export to .cn6 format.
6) Either
(a) use Import to import your .cn6 file then Save to create your .fgx.
(b) make a copy of original source .fgx with a new name and then use Overwrite to replace all the mesh data in the .fbx with the mesh data from your .cn6 file. All skeleton data will be left intact.
7. You may need to rename, add, delete and/or reassign your Materials to Meshes inside CivNexus6. These names are referenced from within your .ast and .geo file.

You can create your Geometry metadata .geo file using the Save Geometry (.geo) file in the Additional Actions tab.

* For Blender tutorials, YouTube is your friend.
If you want to copy the bone weights/vertex groups (aka rigging) from one mesh to another (useful for e.g. human units) you can use the Transfer Weights method described in Wolfdog's tutorial here - note: only Steps 3 and 5-8 of that tutorial are relevant (unless you're importing Civ 4 meshes to Civ 6!).

If your model is relatively simple (.e.g. a tank or plane) then you can assign parts of the mesh to different bone vertex groups manually. Weight Paint mode in Blender can be really useful for checking the weights of vanilla models and for identifying any issues with weights in general.


XLPs (.xlp files)

You can think of the .xlp files as the XML Library Package definitions of which Assets (.ast) get cooked into which .blp (Binary Library Package) files.

The key elements of the .xlp files are explained below:
Code:
    <m_ClassName text="Unit"/> <!-- type of Asset to go in this library package -->
    <m_PackageName text="units/units"/> <!-- name of resulting .blp package file -->
    <m_Entries>
        <Element>
            <m_EntryID text="T34_Tank"/> <!-- The entry to be referenced from .artdefs -->
            <m_ObjectName text="T34_Tank"/> <!-- Refers to Asset .ast file -->
        </Element>
    </m_Entries>


ArtDefs (.artdef files)

The .artdef files define various different aspects of how different graphics appear in the game.

For Units see the Rough Guide to Units.artdef as a starter. For Landmarks (Improvements, Buildings, Districts etc) there is some information in this thread.

Also see here for a guide on setting up Units ArtDefs using the Asset Editor itself: Mix and Match post.

Within the Units .artdef schema there is a collection call UnitAttachmentBins that links between the UnitMemberTypes (individual unit model definitions) and the attachment 3D object entries inside the .blp.

In our T-34 example the UnitAttachmentBins entry is as follows:

Code:
<Element>
                <m_Fields>
                    <m_Values/>
                </m_Fields>
                <m_ChildCollections>
                    <Element>
                        <m_CollectionName text="Groups"/>
                        <m_ReplaceMergedCollectionElements>false</m_ReplaceMergedCollectionElements>
                        <Element>
                            <m_Fields>
                                <m_Values/>
                            </m_Fields>
                            <m_ChildCollections>
                                <Element>
                                    <m_CollectionName text="Cultures"/>
                                    <m_ReplaceMergedCollectionElements>false</m_ReplaceMergedCollectionElements>
                                    <Element>
                                        <m_Fields>
                                            <m_Values>
                                                <Element class="AssetObjects::ArtDefReferenceValue">
                                                    <m_ElementName text=""/>
                                                    <m_RootCollectionName text="UnitTintTypes"/>
                                                    <m_ArtDefPath text=""/>
                                                    <m_CollectionIsLocked>true</m_CollectionIsLocked>
                                                    <m_TemplateName text=""/>
                                                    <m_ParamName text="Tint"/>
                                                </Element>
                                            </m_Values>
                                        </m_Fields>
                                        <m_ChildCollections>
                                            <Element>
                                                <m_CollectionName text="Assets"/>
                                                <m_ReplaceMergedCollectionElements>false</m_ReplaceMergedCollectionElements>
                                                <Element>
                                                    <m_Fields>
                                                        <m_Values>
                                                            <Element class="AssetObjects::BLPEntryValue">
                                                                <m_EntryName text="T34_Tank"/> <!-- The Entry name of the asset in the .blp -->
                                                                <m_XLPClass text="Unit"/>
                                                                <m_XLPPath text="Units.xlp"/>
                                                                <m_BLPPackage text="units/units"/>
                                                                <m_LibraryName text="Unit"/>
                                                                <m_ParamName text="Asset"/>
                                                            </Element>
                                                            <Element class="AssetObjects::FloatValue">
                                                                <m_fValue>1.000000</m_fValue>
                                                                <m_ParamName text="Scale"/>
                                                            </Element>
                                                        </m_Values>
                                                    </m_Fields>
                                                    <m_ChildCollections/>
                                                    <m_Name text="T34_Tank"/> <!-- The name of the specific Binary Asset - this can be used to reference this specific item from the UnitMemberTypes -->
                                                    <m_AppendMergedParameterCollections>false</m_AppendMergedParameterCollections>
                                                </Element>
                                            </Element>
                                        </m_ChildCollections>
                                        <m_Name text="Any"/> <!-- This is the cultural variation e.g. NorthernEuropean, SouthAfrican, Mediterranean, etc... - use "Any" if there will be no cultural variations-->
                                        <m_AppendMergedParameterCollections>false</m_AppendMergedParameterCollections>
                                    </Element>
                                </Element>
                            </m_ChildCollections>
                            <m_Name text="T34_Tank"/>  <!-- This should correspond to the specific type of object -->
                            <m_AppendMergedParameterCollections>false</m_AppendMergedParameterCollections>
                        </Element>
                    </Element>
                </m_ChildCollections>
                <m_Name text="Vehicle"/>   <!-- Category of Attachment asset. This can be anything e.g. Armor, Shields, Swords, FantasticBeasts, Guns, etc... -->
                <m_AppendMergedParameterCollections>false</m_AppendMergedParameterCollections>
            </Element>

I reference my UnitAttachmentBins entry from UnitMemberTypes like this:
Code:
<Element>
        <m_CollectionName text="Bins"/>
        <Element>
            <m_Fields>
                <m_Values/>
            </m_Fields>
            <m_ChildCollections/>
            <m_Name text="Vehicles/T34_Tank"/>
            <m_AppendMergedParameterCollections>false</m_AppendMergedParameterCollections>
        </Element>
    </Element>

Note: The full path Vehicles/T34_Tank/Any/T34_Tank would also work - but that is longer and wouldn't allow for cultural variations on my Attachment should I add them later.


Mod.Art.xml

I'd highly recommend that you use the Mod.Art.xml Generator here as a final step once you are done creating your .artdef and .blp files.

Mod.Art.Xml is a file that tells the cooker which systems need to use which .artdef files and .xlp files. For now you have to hand-edit it to add the references.

For the T-34 Unit example the important entries are:

1) The references to our ArtDef files Units.artdef and Unit_Bins.artdef:
Code:
        <Element>
            <consumerName text="Units"/>
            <relativeArtDefPaths>
                <Element text="Units.artdef" />     <!-- ArtDef reference -->
                <Element text="Unit_Bins.artdef" />     <!-- ArtDef reference -->
            </relativeArtDefPaths>
            <libraryDependencies>
                <Element text="Unit"/>
                <Element text="VFX"/>
                <Element text="Light"/>
            </libraryDependencies>
            <loadsLibraries>true</loadsLibraries>
        </Element>

2) The reference to the new .blp file that will be generated from your .xlp specification:
Code:
<Element>
            <libraryName text="Unit"/>
            <relativePackagePaths>
                <Element text="units/units.blp"/> <!-- .blp name -->
            </relativePackagePaths>
        </Element>



When your mod includes any .artdef files or .xlp files, the build process creates a .dep file. This is the file you need to reference in your <UpdateArt> .modinfo action. But! this file is generated at build time. So what you want to use instead is (Mod Art Dependency File) which is just a way of telling ModBuddy to fill in the blank later with the generated .dep file.


Other Filetypes

Animations (.anm files)
The metadata file for an .fgx animation file. These can be generated using CivNexus6.

Behaviors (.bhv files)
Collects together sets of animations, sound and visual fx timelines for reuse between multiple Units. e.g. SingleBiped_Deaths.bhv is reused in many Unit .ast files.

Sometimes you can see the animation/sound/effects setup in the .ast files or sometimes the three are grouped together in Behaviour files e.g. Archer.bhv for re-use.

The three important collections are:

m_animationBindings (defines which .anm asset with associated .fgx animation to use for each event slot - no more need to deal with animation codes which is nice!)
Code:
<m_animationBindings>
                <m_Bindings>
                    <Element>
                        <m_SlotName text="ATTACK_A"/>
                        <m_AnimationName text="Archer_FireArrowStraightA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="BACKWARD_A"/>
                        <m_AnimationName text="UnitMedium_StrafeBack_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="FORWARD_A"/>
                        <m_AnimationName text="UnitMedium_StrafeFwd_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="REACT_A"/>
                        <m_AnimationName text="Archer_FireArrowThenSwingBowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="RUN_A"/>
                        <m_AnimationName text="UnitMedium_Run_BowAndArrowA"/>
                    </Element>
...
I haven't really seen any transitions defined so hopefully the engine handles them automatically?

m_timelineBindings (Just maps event slots to timelines):
Code:
<m_timelineBindings>
                <m_Bindings>
                    <Element>
                        <m_SlotName text="ATTACK_A"/>
                        <m_TimelineName text="ATTACK_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="RUN_A"/>
                        <m_TimelineName text="RUN_A"/>
                    </Element>
                    ......

m_timelines (associate Sound FX and Visual FX with an event code, the m_AnimationName here needs to matched the name of the .anm file).
Code:
<m_timelines>
                <m_Timelines>
                    <Element>
                        <m_Name text="ATTACK_A"/>
                        <m_Description text=""/>
                        <m_AnimationName text="Archer_FireArrowStraightA"/>
                        <m_fDuration>0.000000</m_fDuration>
                        <m_Triggers>
                            <Element>
                                <m_eType>ACTION</m_eType>
                                <m_Name text="1"/>
                                <m_Description text=""/>
                                <m_FXName text="END"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>1.699659</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            ......
                        </m_Triggers>
                    </Element>


The Pantry
All the asset files (.ast, .geo, .mtl, .tex, .anm, etc) in the Dev Assets pantry can be used as if they were part of your mod.


What files are needed for the mod to work?

ModBuddy builds out many folders that aren't actually needed for the mod to work. You can delete any art-related folders and contents apart from:
* .modinfo and .dep files
* the Platforms folder that contains all the cooked .blp files
* the ArtDefs folder that contains all the art metadata and references

The following folders can be deleted from your built-out mod folder after the build - the game doesn't actually need them to run the mod:
* Animations
* Assets
* Behaviours
* Geometries
* Materials
* Textures
* XLPs
 
Last edited:
Awesome! My contributions may be somewhat limited until the prospect of adding custom animations comes into play, though. Do you see it as possible in the near future?

It's possible... but I haven't done any proper testing with the .fbx import functionality. Animations extract OK into Blender via .na2 but I haven't investigated the other half of the round-trip yet.
 
Last edited:
Awesome! My contributions may be somewhat limited until the prospect of adding custom animations comes into play, though. Do you see it as possible in the near future?

So... funny thing here. I've made a discovery. It turns out the structure of skeletons and animations is the same between Civ 5 .gr2 and Civ 6 .fgx. The only thing that has changed format are the meshes.

I can actually load a Civ .gr2 made using Nexus Buddy 2 into CivNexus6, do a .br2 overwrite to get the mesh data in and I have a Civ 6 .fgx that will work with the Civ 5 .gr2 animations *unchanged*. This means the custom animated units from Civ 5 can be updated for Civ 6 quite easily.

dragon_fgxviewer.jpg
 
So... funny thing here. I've made a discovery. It turns out the structure of skeletons and animations is the same between Civ 5 .gr2 and Civ 6 .fgx. The only thing that has changed format are the meshes.

I can actually load a Civ .gr2 made using Nexus Buddy 2 into CivNexus6, do a .br2 overwrite to get the mesh data in and I have a Civ 6 .fgx that will work with the Civ 5 .gr2 animations *unchanged*. This means the custom animated units from Civ 5 can be updated for Civ 6 quite easily.


Oh...that...is...AWESOME!!! Excellent discovery! Looks like I have a lot of work to do.... :lol:
 
I have to say Deliverator, I never did any 3D art stuff before and only made maps for civ 5. I have done a lot more in depth modding for civ 6 and even added a new sea resource but still no 3D stuff. Watching you work through this stuff is just so inspiring, seriously this stuff is amazing, I just wish I had only half your talent, thank you.
 
I'm attempting to do use the crossbowman armour with spearman animations. I'm copy and pasting the spearman asset into my project and then using the crossbowman geometry entry. Similiar to how you did the longbowman.

But every time i try to open the asset editor it crashes. I can delete the fyrd_armorA.ast to fix it but any attempt i make at creating a new .ast even inside the asset editor will cause this crash.

Code:
System.Exception: System.AggregateException: One or more errors occurred. ---> System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.Collections.Concurrent.ConcurrentDictionary`2.get_Item(TKey key)
   at DatabaseWrapper.WorkspaceDependencyBase.AddEntityStatsAndTags(IInstanceEntity entity, IDatabaseDependencies workspaceDependencies, String depotRootedPath)
   at DatabaseWrapper.WorkspaceDependencyBase.<>c__DisplayClass25_0.<AddEntityDependencies>b__0(InstanceType it, String name)
   at Firaxis.CivTech.AssetObjects.InstanceEntity.CrawlDependencies(Action`2 pmAction)
   at DatabaseWrapper.WorkspaceDependencyBase.AddEntityDependencies(IInstanceEntity entity, ISet`1 entityDependencies, IInstanceSet instSet, IDatabaseDependencies workspaceDependencies)
   at DatabaseWrapper.WorkspaceDependencyBase.<>c__DisplayClass25_0.<AddEntityDependencies>b__0(InstanceType it, String name)
   at Firaxis.CivTech.AssetObjects.InstanceEntity.CrawlDependencies(Action`2 pmAction)
   at DatabaseWrapper.WorkspaceDependencyBase.AddEntityDependencies(IInstanceEntity entity, ISet`1 entityDependencies, IInstanceSet instSet, IDatabaseDependencies workspaceDependencies)
   at DatabaseWrapper.WorkspaceDependencyBase.AddEntityDependencies(InstanceType insType, String insPath, IInstanceSet instSet, IDatabaseDependencies workspaceDependencies)
   at DatabaseWrapper.WorkspaceDependencyBuilder.<>c__DisplayClass1_1.<BuildFromWorkspace>b__2(String file)
   at Firaxis.Collections.IEnumerableExtensions.ForEach[T](IEnumerable`1 list, Action`1 action)
   at DatabaseWrapper.WorkspaceDependencyBuilder.<>c__DisplayClass1_2.<BuildFromWorkspace>b__1(InstanceType insType)
   at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object )
   --- End of inner exception stack trace ---
   at AssetEditor.Program.Main(String[] args)
---> (Inner Exception #0) System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.Collections.Concurrent.ConcurrentDictionary`2.get_Item(TKey key)
   at DatabaseWrapper.WorkspaceDependencyBase.AddEntityStatsAndTags(IInstanceEntity entity, IDatabaseDependencies workspaceDependencies, String depotRootedPath)
   at DatabaseWrapper.WorkspaceDependencyBase.<>c__DisplayClass25_0.<AddEntityDependencies>b__0(InstanceType it, String name)
   at Firaxis.CivTech.AssetObjects.InstanceEntity.CrawlDependencies(Action`2 pmAction)
   at DatabaseWrapper.WorkspaceDependencyBase.AddEntityDependencies(IInstanceEntity entity, ISet`1 entityDependencies, IInstanceSet instSet, IDatabaseDependencies workspaceDependencies)
   at DatabaseWrapper.WorkspaceDependencyBase.<>c__DisplayClass25_0.<AddEntityDependencies>b__0(InstanceType it, String name)
   at Firaxis.CivTech.AssetObjects.InstanceEntity.CrawlDependencies(Action`2 pmAction)
   at DatabaseWrapper.WorkspaceDependencyBase.AddEntityDependencies(IInstanceEntity entity, ISet`1 entityDependencies, IInstanceSet instSet, IDatabaseDependencies workspaceDependencies)
   at DatabaseWrapper.WorkspaceDependencyBase.AddEntityDependencies(InstanceType insType, String insPath, IInstanceSet instSet, IDatabaseDependencies workspaceDependencies)
   at DatabaseWrapper.WorkspaceDependencyBuilder.<>c__DisplayClass1_1.<BuildFromWorkspace>b__2(String file)
   at Firaxis.Collections.IEnumerableExtensions.ForEach[T](IEnumerable`1 list, Action`1 action)
   at DatabaseWrapper.WorkspaceDependencyBuilder.<>c__DisplayClass1_2.<BuildFromWorkspace>b__1(InstanceType insType)
   at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object )<---
 
I'm attempting to do use the crossbowman armour with spearman animations. I'm copy and pasting the spearman asset into my project and then using the crossbowman geometry entry. Similiar to how you did the longbowman.

But every time i try to open the asset editor it crashes. I can delete the fyrd_armorA.ast to fix it but any attempt i make at creating a new .ast even inside the asset editor will cause this crash.

As the opening post says:
Note: The Asset Editor has a bug where it won't open if your ModBuddy project contains any custom .ast files. I have been working around this by running two copies of the ModBuddy application and using one for running the Asset Editor and one for assembling/building my mod and cooking my art assets. You can copy any files created in one project to the other project and then use Add > Existing Item to add then into your assembly/build mod e.g. copy the .tex and .dds files from "My Documents\Firaxis ModBuddy\Civilization VI\AssetEditorMod\Textures" to "My Documents\Firaxis ModBuddy\Civilization VI\NewUnitTest\Textures" and then Add into NewUnitTest.
 
Close but not quite there with importing custom animations. Rotation problems...

when_animation_goes_wrong.jpg
 
It looks like .gr2 animations from Civ 5 work just fine - see converted Mammoth below. All had to do what rename them to .fgx and generate the .anm metadata files which will be possible in the next version of CivNexus6. The issues I was having with the Flying Dragon above were because that was made in a messy way. Anyway this opens things up because it means it should be possible to port Civ 5 and Civ Beyond Earth models into Civ 6 without any Blender work (once I add a BR2 export facility to Nexus Buddy 2). :D

mammoth_test.jpg
 
It looks like .gr2 animations from Civ 5 work just fine - see converted Mammoth below. All had to do what rename them to .fgx and generate the .anm metadata files which will be possible in the next version of CivNexus6. The issues I was having with the Flying Dragon above were because that was made in a messy way. Anyway this opens things up because it means it should be possible to port Civ 5 and Civ Beyond Earth models into Civ 6 without any Blender work (once I add a BR2 export facility to Nexus Buddy 2). :D



That is brilliant! So it looks like all of the hard work is done from the CiV conversion process. If that is the case, I will probably continue to develop custom animations in CiV and then directly import them to Civ VI. That way, CiV modders will be able to use them as well. Great discovery, Deliverator!
 
That is brilliant! So it looks like all of the hard work is done from the CiV conversion process. If that is the case, I will probably continue to develop custom animations in CiV and then directly import them to Civ VI. That way, CiV modders will be able to use them as well. Great discovery, Deliverator!

Yes, in fact it looks like the Civ 5 method using Blender 2.49, FBX and Nexus Buddy 2 is going to be the only way of getting custom animations into Civ 6 - so far the FBX import for Civ 6 seems useless.
 
How please? I don't see any options when I click "Save as…" in Paint.net.

After you select the DDS format you should another screen "Save Configuration" - the specific DDS format is in the dropdown under Settings.
 
Deliverator, have you had an opportunity to study the Civ VI animations? Are they similar to CiV animations with respect to idle transitions, etc.? CiV base anims were far different from Civ IV, which is why converted customs often appeared "clunky" in the game (i.e., they had no transition animations and the sounds/effects often didn't synchronize when assigned an event code). How does Civ VI compare to CiV with respect to how the animation transitions, sounds, and effects operate? Or, more simply, if I can fix a Civ IV unit custom animation set to where it transitions perfectly in CiV, would they convert to Civ VI more or less seamlessly?
 
Deliverator, have you had an opportunity to study the Civ VI animations? Are they similar to CiV animations with respect to idle transitions, etc.? CiV base anims were far different from Civ IV, which is why converted customs often appeared "clunky" in the game (i.e., they had no transition animations and the sounds/effects often didn't synchronize when assigned an event code). How does Civ VI compare to CiV with respect to how the animation transitions, sounds, and effects operate? Or, more simply, if I can fix a Civ IV unit custom animation set to where it transitions perfectly in CiV, would they convert to Civ VI more or less seamlessly?

I've just started playing with the animation set up. You can see the animation/sound/effects setup in the .ast files or sometimes the three are grouped together in Behaviour files e.g. Archer.bhv for re-use.

The three important collections are:

m_animationBindings (defines which .anm asset with associated .fgx animation to use for each event slot - no more need to deal with animation codes which is nice!)
Code:
<m_animationBindings>
                <m_Bindings>
                    <Element>
                        <m_SlotName text="ATTACK_A"/>
                        <m_AnimationName text="Archer_FireArrowStraightA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="BACKWARD_A"/>
                        <m_AnimationName text="UnitMedium_StrafeBack_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="FORWARD_A"/>
                        <m_AnimationName text="UnitMedium_StrafeFwd_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="REACT_A"/>
                        <m_AnimationName text="Archer_FireArrowThenSwingBowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="RUN_A"/>
                        <m_AnimationName text="UnitMedium_Run_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="RUN_COMBAT"/>
                        <m_AnimationName text="UnitMedium_RunCombat_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="IDLE_A"/>
                        <m_AnimationName text="Archer_StandingIdleA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="IDLE_B"/>
                        <m_AnimationName text="Archer_StandingIdleB"/>
                    </Element>
...
I haven't really seen any transitions defined so hopefully the engine handles them automatically?

m_timelineBindings (Just maps event slots to timelines):
Code:
<m_timelineBindings>
                <m_Bindings>
                    <Element>
                        <m_SlotName text="ATTACK_A"/>
                        <m_TimelineName text="ATTACK_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="RUN_A"/>
                        <m_TimelineName text="RUN_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="FORWARD_A"/>
                        <m_TimelineName text="FORWARD_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="BACKWARD_A"/>
                        <m_TimelineName text="BACKWARD_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="IDLE_A"/>
                        <m_TimelineName text="IDLE_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="IDLE_B"/>
                        <m_TimelineName text="IDLE_B"/>
                    </Element>

m_timelines (associate Sound FX and Visual FX with an event code).
Code:
<m_timelines>
                <m_Timelines>
                    <Element>
                        <m_Name text="ATTACK_A"/>
                        <m_Description text=""/>
                        <m_AnimationName text="Archer_FireArrowStraightA"/>
                        <m_fDuration>0.000000</m_fDuration>
                        <m_Triggers>
                            <Element>
                                <m_eType>ACTION</m_eType>
                                <m_Name text="1"/>
                                <m_Description text=""/>
                                <m_FXName text="END"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>1.699659</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>TRANSFER</m_eType>
                                <m_Name text="2"/>
                                <m_Description text=""/>
                                <m_FXName text="3"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>0.803650</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>ASSET_FX</m_eType>
                                <m_Name text="3"/>
                                <m_Description text=""/>
                                <m_FXName text="FX_Archer_Arrow_Trail"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text="WeaponPrimary"/>
                                <m_fStartTime>0.802531</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="13"/>
                                <m_Description text=""/>
                                <m_FXName text="ArcherBowDraw"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>0.088889</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="14"/>
                                <m_Description text=""/>
                                <m_FXName text="ArcherBowFire"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>0.687037</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="15"/>
                                <m_Description text=""/>
                                <m_FXName text="ArcherBowLoad"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>1.331485</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="38"/>
                                <m_Description text=""/>
                                <m_FXName text="Foley_Armor_Short"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>1.210590</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="39"/>
                                <m_Description text=""/>
                                <m_FXName text="Foley_Armor_Short"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>0.226550</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                        </m_Triggers>
                    </Element>
 
I've just started playing with the animation set up. You can see the animation/sound/effects setup in the .ast files or sometimes the three are grouped together in Behaviour files e.g. Archer.bhv for re-use.

Spoiler :
The three important collections are:

m_animationBindings (defines which .anm asset with associated .fgx animation to use for each event slot - no more need to deal with animation codes which is nice!)
Code:
<m_animationBindings>
                <m_Bindings>
                    <Element>
                        <m_SlotName text="ATTACK_A"/>
                        <m_AnimationName text="Archer_FireArrowStraightA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="BACKWARD_A"/>
                        <m_AnimationName text="UnitMedium_StrafeBack_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="FORWARD_A"/>
                        <m_AnimationName text="UnitMedium_StrafeFwd_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="REACT_A"/>
                        <m_AnimationName text="Archer_FireArrowThenSwingBowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="RUN_A"/>
                        <m_AnimationName text="UnitMedium_Run_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="RUN_COMBAT"/>
                        <m_AnimationName text="UnitMedium_RunCombat_BowAndArrowA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="IDLE_A"/>
                        <m_AnimationName text="Archer_StandingIdleA"/>
                    </Element>
                    <Element>
                        <m_SlotName text="IDLE_B"/>
                        <m_AnimationName text="Archer_StandingIdleB"/>
                    </Element>
...
I haven't really seen any transitions defined so hopefully the engine handles them automatically?

m_timelineBindings (Just maps event slots to timelines):
Code:
<m_timelineBindings>
                <m_Bindings>
                    <Element>
                        <m_SlotName text="ATTACK_A"/>
                        <m_TimelineName text="ATTACK_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="RUN_A"/>
                        <m_TimelineName text="RUN_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="FORWARD_A"/>
                        <m_TimelineName text="FORWARD_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="BACKWARD_A"/>
                        <m_TimelineName text="BACKWARD_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="IDLE_A"/>
                        <m_TimelineName text="IDLE_A"/>
                    </Element>
                    <Element>
                        <m_SlotName text="IDLE_B"/>
                        <m_TimelineName text="IDLE_B"/>
                    </Element>

m_timelines (associate Sound FX and Visual FX with an event code).
Code:
<m_timelines>
                <m_Timelines>
                    <Element>
                        <m_Name text="ATTACK_A"/>
                        <m_Description text=""/>
                        <m_AnimationName text="Archer_FireArrowStraightA"/>
                        <m_fDuration>0.000000</m_fDuration>
                        <m_Triggers>
                            <Element>
                                <m_eType>ACTION</m_eType>
                                <m_Name text="1"/>
                                <m_Description text=""/>
                                <m_FXName text="END"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>1.699659</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>TRANSFER</m_eType>
                                <m_Name text="2"/>
                                <m_Description text=""/>
                                <m_FXName text="3"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>0.803650</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>ASSET_FX</m_eType>
                                <m_Name text="3"/>
                                <m_Description text=""/>
                                <m_FXName text="FX_Archer_Arrow_Trail"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text="WeaponPrimary"/>
                                <m_fStartTime>0.802531</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="13"/>
                                <m_Description text=""/>
                                <m_FXName text="ArcherBowDraw"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>0.088889</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="14"/>
                                <m_Description text=""/>
                                <m_FXName text="ArcherBowFire"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>0.687037</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="15"/>
                                <m_Description text=""/>
                                <m_FXName text="ArcherBowLoad"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>1.331485</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="38"/>
                                <m_Description text=""/>
                                <m_FXName text="Foley_Armor_Short"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>1.210590</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                            <Element>
                                <m_eType>SOUND</m_eType>
                                <m_Name text="39"/>
                                <m_Description text=""/>
                                <m_FXName text="Foley_Armor_Short"/>
                                <m_CollectionName text=""/>
                                <m_AttachmentPointName text=""/>
                                <m_fStartTime>0.226550</m_fStartTime>
                                <m_fDuration>0.000000</m_fDuration>
                                <m_nTrackIndex>0</m_nTrackIndex>
                            </Element>
                        </m_Triggers>
                    </Element>

Wow, this seems much more straightforward when compared to CiV! I may have to work on a test unit to see what pitfalls might exist, if any. Thanks for the tireless effort!
 
Top Bottom