Using SQLite as Data Store In Unreal

We are researching for the best way to store dialogue data with Unreal.
The default approach for storing data in Unreal seems to be DataTable, which can be created by importing CSV file. However dialogue seems to be relational data, so we are wondering if the embedded databases like SQLite is a good way for storing data in Unreal.

##Compiling SQLite as Static Library

As I was a desktop app developer, the first thing that comes to my mind is SQLite. The common way to include SQLite is by referencing it as static library. As there is no downloadable .lib, you will need to download the source code from https://www.sqlite.org.

If we compile the source code directly, it will seem to work. However once we try to execute SQLIte function in our project, we get "error C4703: potentially uninitialized local pointer variable used".
Thanks to this SO post, I managed to solve the issue.

    #pragma warning ( disable : 4703 )   

Basically, we need to add the above line in sqlite.c

Including SQLite in Unreal Build System

First we will need to include header and .lib file in code directory.
For the time being, we use this directory structure

Root Project
    ...
    Third Party
        sqlite3
            Includes
                sqlite3.h
            Libs
                sqlite3-x64.lib
                sqlite3-x32.lib
    ...

Unreal uses Unreal Build Tools (UBT) for managing the build process.
UBT itself is C# based, and we will need to do build config in C#.
In every module, we will find module rules files, which use ModuleName.Build.cs as file name convention. We need to inform module rule that we will need to load SQLite

public MyProjectName(TargetInfo target)
{
    ....
    LoadSqlite(target);
}

private string ModulePath
{
    get 
    { 
		return ModuleDirectory;
	}
}

private string ThirdPartyPath
{
    get { return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); }
}

public bool LoadSqlite(TargetInfo Target)
{
    bool isLibrarySupported = false;

    if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
    {
        isLibrarySupported = true;
        string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "x64" : "x86";
        string LibrariesPath = Path.Combine(ThirdPartyPath, "sqlite3", "Libs");
        PublicAdditionalLibraries.Add(Path.Combine(LibrariesPath, "sqlite3-"+PlatformString+".lib"));
    }

    if (isLibrarySupported)
    {
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "sqlite3", "Includes"));
    }

    return isLibrarySupported;
}

The above code is based on Unreal wiki, adapted to version 4.12.

Packaging

One thing to note, is that database file need to be copied into package folder, and not included in PAK file. This can be done via specifying "Additional non-asset directories to copy" in packaging settings.

Conclusion

To be honest, we are still not 100% sure if we want to use SQLite. In our plan, we will just do read operation, so there won't be any lock issue. However SQLite is platform dependent, and we don't know if the code will be 100% compatible if we run it in other environment, like game consoles. For now, we will just refactor, so we can fallback to use DataTable if SQLite is not supported.