Home

Assets, DataTables & Distribution

This page covers adding icons and assets to your mod, the DataTable merging system, localisation, packaging mods for distribution, and debugging.


DataTable Merging System#

UGameDataSubsystem merges DataTables from directories at startup. Each DataTable directory can contain multiple .uasset DataTable files -- all rows are merged into a single runtime table. Mods add new rows or override existing ones by placing DataTables in the correct directories within their Content/ folder.

How It Works

  1. At startup, the subsystem scans the base game's DataTable directories.
  2. It then scans each enabled mod's Content/ directory for matching subdirectories.
  3. All rows from all tables are merged. If two rows have the same key, the mod with the higher load order wins.
  4. The merged table is used at runtime for all icon lookups and data queries.

Merged DataTable Reference

Table NameRow StructDirectoryPurposeConceptIconsFConceptIconDataContent/Data/ConceptIcons/UI concept icons (gold, food, etc.)TraitIconsFTraitIconDataContent/Data/TraitIcons/Character trait iconsPolicyIconsFTraitIconDataContent/Data/PolicyIcons/Policy slider iconsEdictIconsFTraitIconDataContent/Data/EdictIcons/Edict action iconsInteractionIconsFInteractionIconDataContent/Data/InteractionIcons/Person interaction iconsDiplomacyIconsFConceptIconDataContent/Data/DiplomacyIcons/Diplomacy interaction iconsBattleActionIconsFTraitIconDataContent/Data/BattleActionIcons/Battle action iconsUnitTypeIconsFTraitIconDataContent/Data/UnitTypeIcons/Unit type category iconsCultureIconsFTraitIconDataContent/Data/CultureIcons/Culture iconsReligionIconsFTraitIconDataContent/Data/ReligionIcons/Religion iconsPowerBlocIconsFTraitIconDataContent/Data/PowerBlocIcons/Power bloc iconsDiplomaticNotificationIconsFDiplomaticNotificationIconDataContent/Data/DiplomaticNotificationIcons/Diplomatic notification iconsFactionFlagsFFactionFlagDataContent/Data/FactionFlags/Faction emblems and flagsResourcesFResourceTypeDataContent/Data/Resources/Resource type definitionsGlossaryFGlossaryTableRowContent/Data/Glossary/Glossary term definitionsEventTopicsFEventTopicContent/Data/EventTopics/LLM event topic promptsEventImagesFEventImageDataContent/Data/EventImages/Event artwork mappingEpithetsFEpithetDefinitionContent/Data/Epithets/Character epithet definitionsSettlementEffectsFSettlementEffectAssetDataContent/Data/SettlementEffects/Settlement effect icon/art mappingWarningIconsFWarningIconDataContent/Data/WarningIcons/Warning notification iconsLoadingTipsFLoadingTipDataContent/Data/LoadingTips/Loading screen tips

Adding Icons for Your Content#

Most content types reference icons through a key (e.g., IconKey = n"MyTrait"). The key is looked up in the appropriate merged DataTable. To add icons for your mod content:

Step 1: Create a CSV

Create a CSV file for the appropriate icon table. The format depends on the row struct.

FTraitIconData format (used by TraitIcons, PolicyIcons, EdictIcons, BattleActionIcons, UnitTypeIcons, CultureIcons, ReligionIcons, PowerBlocIcons):

csv
---IconIconTint
MyTrait/Game/MyMod/Icons/T_MyTrait.T_MyTrait(R=1.0,G=1.0,B=1.0,A=1.0)
MyOtherTrait/Game/MyMod/Icons/T_MyOtherTrait.T_MyOtherTrait
ColumnDescription---Row name (must match your IconKey).IconSoft reference path to the texture asset.IconTintOptional FLinearColor tint. Empty string = white/no tint.

FConceptIconData format (used by ConceptIcons, DiplomacyIcons):

csv
---IconIconTint
MyDiplomacyAction/Game/MyMod/Icons/T_MyAction.T_MyAction(R=1.0,G=1.0,B=1.0,A=1.0)

Same format as FTraitIconData.

FInteractionIconData format (used by InteractionIcons):

csv
---Icon
MyInteraction/Game/MyMod/Icons/T_MyInteraction.T_MyInteraction
ColumnDescription---Row name (must match your IconKey).IconSoft reference path to the texture asset.

Step 2: Import as DataTable

Import the CSV into the Unreal Editor as a DataTable using the appropriate row struct. Place the resulting .uasset in the correct directory under your mod's Content/Data/ folder.

For example, to add trait icons:

Mods/MyMod/Content/Data/TraitIcons/MyModTraitIcons.csv
Mods/MyMod/Content/Data/TraitIcons/MyModTraitIcons.uasset

Step 3: Reference in Your Code

Set the IconKey property on your content class to match the row name:

angelscript
default IconKey = n"MyTrait";

Localisation#

All user-facing text in mods should use the localisation system for future translation support.

PO File Format

Localisation strings are stored in PO (Portable Object) files. The game's PO file is at Content/Localization/Game/en/Game.po.

Each entry follows this format:

po
#: Namespace,Key
msgctxt "Namespace,Key"
msgid ""
msgstr "The actual text displayed to the player"
  • Namespace: Use your mod ID (e.g., MyMod).
  • Key: A unique identifier within the namespace (e.g., Stoic_Name).
  • msgid is always empty (the engine uses msgctxt for lookups).
  • msgstr contains the actual translated text.

Example Entries

po
#: MyMod,Stoic_Name
msgctxt "MyMod,Stoic_Name"
msgid ""
msgstr "Stoic"

#: MyMod,Stoic_Description
msgctxt "MyMod,Stoic_Description"
msgid ""
msgstr "This character maintains composure under pressure, earning respect through steady governance."

#: MyMod,Granary_Effects
msgctxt "MyMod,Granary_Effects"
msgid ""
msgstr "+{Bonus}% food production"

Referencing in Code

angelscript
// Basic usage (returns FText)
Localization::GetText("MyMod", "Stoic_Name")

// Convert to FString for string operations
Localization::GetText("MyMod", "Stoic_Description").ToString()

// Dynamic text with placeholder substitution
Localization::GetText("MyMod", "Granary_Effects").ToString().Replace("{Bonus}", "" + Bonus)

Namespace Conventions

NamespaceUsageYour mod IDAll mod-specific stringsTraitsBase game trait stringsBuildingsBase game building stringsInteractionsBase game interaction stringsEventsBase game event stringsUnitsBase game unit strings

Current Limitation

The mod loader does not yet automatically merge PO files from mods. For now, mod strings must be added to the main Game.po file located at Content/Localization/Game/en/Game.po within the game's installation directory. A future update will add automatic PO merging so mods can ship their own localisation files.

As a workaround, you can include a PO file in your mod with instructions for players to append it to the game's Game.po. After editing the PO file, players will need to recompile localisation using the game's built-in localisation tools.


PAK Packaging#

For distribution, mods should be packaged as PAK files. PAK files are Unreal Engine's compressed archive format.

Creating a PAK File

  1. Prepare your content directory with all assets (DataTables, textures, etc.) using the correct content path structure.

  2. Create a response file listing the files to include. The response file is a text file where each line maps a source file to its mount point:

    "C:\Path\To\MyMod\Content\Data\TraitIcons\MyIcons.uasset" "../../../FallOfAnEmpire/Content/Data/TraitIcons/MyIcons.uasset"
    "C:\Path\To\MyMod\Content\Icons\T_MyTrait.uasset" "../../../FallOfAnEmpire/Content/Icons/T_MyTrait.uasset"
  3. Run UnrealPak (found in any Unreal Engine 4 installation under Engine/Binaries/Win64/):

    terminal
    UnrealPak.exe "C:\Path\To\Output\my_mod.pak" -Create="C:\Path\To\response.txt"
  4. Place the PAK file in your mod's root directory:

    Mods/MyMod/my_mod.pak

PAK File Naming

Name the PAK file to match your mod ID: my_mod.pak. The mod loader discovers and mounts PAK files automatically.

Load Order and Priority

When multiple mods (or the base game) provide the same asset path, the mod with the higher load order wins. This allows mods to override base game assets.

PrioritySourceHighestMods with higher load order valuesMods with lower load order valuesLowestBase game (load order 0)

Within the same load order, mods are sorted alphabetically by ID.


Overriding Base Game Content#

Overriding Classes

If your mod defines a class with the same name as a base game class (same parent), the base game class is replaced. This is an advanced technique -- prefer creating new content with unique names.

Overriding DataTable Rows

Add a DataTable row with the same row name as an existing base game row. Your mod's row replaces the base game row at merge time.

Overriding Assets

Package a PAK file with an asset at the same content path as a base game asset. The mod's version replaces the base game version.


Save Compatibility#

ChangeSafe?NotesAdding new content (traits, buildings, etc.)YesNew classes are simply added to registries.Changing property values (costs, stats)YesCDO values are re-evaluated each launch.Renaming a classNoReferences in saves use class names. Renamed classes appear as missing.Removing content that exists in savesNoCharacters with removed traits, settlements with removed buildings, etc., will have issues.Adding mod to existing saveYesNew content becomes available.Removing mod from save that uses its contentNoMissing class warnings.

The game records which mods were active when a save was created. Loading a save with mismatched mods shows a warning to the player.


Extensible vs. Hardcoded Values#

Some game systems use FName identifiers that mods can freely extend. Others use C++ enums that are fixed.

Extensible (FName-based)

SystemPropertyExample ValuesCulture groupsUCulture::Groupn"Rephsian", n"Neutarnic", or any custom FNameReligion groupsUReligion::ReligionGroupn"Borgutian", n"Pagan", n"Mystery", or any custom FNameCourt positionsUFactionCourtComponent keysn"MagisterMilitum", or any custom FNameResource typesResource FName keysn"Iron", n"Wood", or any custom FName

Hardcoded (Enum-based)

SystemEnumValuesCharacter statsEPersonStatisticTactics, Authority, Cunning, Governance, Loyalty, ConstitutionUnit typesEArmyUnitTypeInfantry, Ranged, Cavalry, Siege, SpecialUnit tiersEMilitaryUnitTierTier1 through Tier5Building typesEBuildingTypeMilitary, Wall, Other, NavalBuilding categoriesEBuildingCategoryEconomic, Military, Infrastructure, Cultural, Defensive, Naval, Administrative, OtherInteraction difficultyEInteractionDifficultyVeryEasy, Easy, Medium, Hard, VeryHardPerson interaction categoryEPersonInteractionCategoryDiplomacy, Intrigue, Personal, Military, Economic, Marriage, Family

Hardcoded enums cannot be extended by mods. You must work within the existing values.


Debugging#

Log Files

The game writes logs to Saved/Logs/FallOfAnEmpire.log. Relevant log categories:

CategoryWhat It ShowsLogModLoadingMod discovery, PAK mounting, script registration.LogGameDataClass discovery counts, DataTable merging.LogAngelscriptScript compilation, errors, warnings.

Common Errors

ErrorCauseFixFailed to compile moduleAngelScript syntax errorCheck the log for the exact line number and error message.Discovered 0 X classesNo classes found for a typeVerify UCLASS() is present and the class extends the correct base type.Missing row in DataTableIconKey does not match any rowCheck that your CSV row name matches the IconKey value exactly.Failed to mount PAKInvalid PAK fileRecreate the PAK with correct response file paths.Mod not discoveredMissing or invalid mod.jsonEnsure the file is valid JSON and the id field is present.Dependency not foundRequired mod is not installedInstall the required mod or remove it from dependencies.

ModConfig.json

User mod preferences (enabled/disabled state, load order overrides) are stored in Saved/ModConfig.json. Delete this file to reset all mod preferences to defaults.


Distribution Checklist#

Before distributing your mod:

  1. Test with a clean install -- Disable all other mods and verify yours works independently.
  2. Verify save compatibility -- Start a new game, play for a while, save, reload, and verify no warnings.
  3. Check log for errors -- Ensure no warnings or errors from your mod in the log file.
  4. Include a README -- Document what the mod does, any known issues, and compatibility notes.
  5. Set load order appropriately -- Use 100 for standard mods, higher for patches/overrides.
  6. List dependencies -- If your mod requires another mod, list it in mod.json dependencies.

Distribution Package Structure

File Structure
MyMod
mod.json
Script
(your .as files)
Content# Loose assets (for development)
Data
my_mod.pak# Packaged assets (for distribution)

For script-only mods (no custom assets), the PAK file is optional. Script files are loaded directly from the Script/ directory.


Next Steps#