Skip to content

The editor API

The public types an editor module of yours can reach — the module, the sync service, the asset generator, their results and states, and the two commandlets.

All documentation — Extending
On this page

Everything on this page lives in the plugin’s TaleShardEditor module, which is an editor module: it is absent from a packaged game. A module of yours that uses it declares TaleShardEditor as a dependency and is itself of type Editor. For how to bind the two delegates and what to do in them, see running your own code after a sync.

Every member below is called on the game thread, and every delegate fires there.

FTaleShardEditorModule

The entry point. FTaleShardEditorModule owns the TaleShard menu, the sync window, the sync service and the asset generator, and unregisters all of them in its own ShutdownModule.

Member
static FTaleShardEditorModule* Get()The loaded module, or null when it is not loaded.
TSharedPtr<FTaleShardSyncService> GetSyncService() constThe sync service. Null outside the module’s life.
TSharedPtr<FTaleShardAssetGenerator> GetAssetGenerator() constThe asset generator. Null outside the module’s life.
static const FName SyncTabNameThe sync window’s tab id, for opening or focusing the window from your own code.

FTaleShardSyncService

FTaleShardSyncService launches the sync tool, drives it one command at a time, and turns what it wrote into the payload asset and the media. The sync tool is kept alive between runs; it is ended when the editor module shuts down, when a Play In Editor session starts, and by StopSyncProcess.

Running and cancelling

Member
bool Sync(bool bForceFull, FText& OutReason)Start a run. bForceFull downloads the whole project instead of a delta. False with a reason when the run could not start; the reason is also recorded as the last result.
bool ImportFromDirectory(const FString& SourceDir, FText& OutReason)Run a full sync from a sync output directory already on disk — no server, no API key, no sync tool. The directory is copied, never modified; one that contains the output directory is refused. The run finishes before this returns; the generation it triggers finishes when the asset generator says so.
bool Cancel(FText& OutReason)Cancel the running sync by ending the sync tool. False with a reason when nothing is running.
void StopSyncProcess()End the sync tool and say what happened. A run in flight is failed first.
bool ResetSyncState(FText& OutReason)Throw away everything the sync tool remembers, so the next sync downloads the whole project.
bool ClearGeneratedCode(FText& OutReason)Delete the generated C++ folder. The next sync regenerates it, and the project must be rebuilt.

A run is refused, with a reason, when a sync is already running, when a setting is wrong, when the sync tool cannot be found, or during Play In Editor. A run that fails writes nothing half-way: the payload asset is replaced only by a payload that parsed.

Reading its state

Member
ETaleShardSyncState GetState() constWhere the service is — see below.
bool IsSyncing() constAny state but Idle.
const FTaleShardSyncProgress& GetProgress() constThe running sync’s progress.
const TOptional<FTaleShardSyncResult>& GetLastResult() constThe last run’s result, refusals included. Unset before the first run.
TArray<FString> ValidationErrors() constWhat stops a sync from starting. Empty when one may start.
TArray<FString> ValidationWarnings() constConfigurations that work but cost something. The sync may still start.
FOnTaleShardSyncFinished& OnSyncFinished()Fires once per run, with its FTaleShardSyncResult, whether it succeeded or not.
FOnTaleShardSyncStateChanged& OnStateChanged()Fires when the state, the progress or the last result changes. No parameters — read the getters.

Where things are

All static, so they answer without a run.

MemberReturns
StateDirectory()The sync tool’s persistent state: the project’s Saved/TaleShard/SyncState folder.
OutputDirectory()Where each run’s output is written: the project’s Saved/TaleShard/Sync folder.
GeneratedSourceDirectory()Where generated C++ goes, under the primary game module’s source. Empty when the setting is not a plain relative folder.
PrimaryGameModuleName()The project’s primary game module, from the project descriptor; the project name when it names none.
PayloadPackagePath()The content folder the payload asset lives in.
PayloadAssetName()The payload asset’s name.
PluginVersion()The plugin’s version, from its descriptor.
IsSafeRelativeFolder(Value)Whether a setting value is a plain folder path — no drive, no leading slash, no parent segment.

ETaleShardSyncState

Value
IdleNothing is running.
StartingThe sync tool was launched and its ready line is awaited. A sync tool that never answers fails the run after 30 seconds.
SyncingA command was sent and its result is awaited.
CancellingThe user cancelled and the sync tool’s exit is awaited.

FTaleShardSyncProgress

Fraction (0 to 1) · Phase · Message.

FTaleShardSyncResult

What one run did. HasErrors() is true when any diagnostic is an error, and a run with one is a failed run.

Field
bSuccessNo failure message, no error-level diagnostic, not cancelled.
bUpToDateThe project had not changed since the last sync. The payload asset was still refreshed.
bFullSyncThe run downloaded the whole project rather than a delta.
bCancelledThe user cancelled it.
ErrorMessageWhy it failed, when it did.
DiagnosticsEvery FTaleShardDiagnosticEvent the run reported.
ElapsedMs · TimestampHow long it took, and when it ended, in local time.
OutputDirThe directory the sync tool wrote into, which the generator reads from.
PayloadAssetPath · MediaIndexAssetPathThe object paths of the payload and media index assets the run wrote, when it wrote them.
MediaImported · MediaFailed · MediaSkippedThe media tally.
ChangedItemsWhat changed, grouped by category, in the order the sync tool reported it.

FTaleShardAssetGenerator

FTaleShardAssetGenerator turns a sync’s output into the assets a game plays from: the entity stores and indexes, the table stores, the string tables, the gameplay tag ini, the manifest and — when it is on — the typed C++. It listens to the sync service’s finished delegate and runs after every successful sync; a failed sync generates nothing. The plan is computed on a background thread, and nothing on disk changes until the plan is complete and free of errors.

Member
bool Generate(const FString& OutputDir, const TArray<TPair<FString, FString>>& AlsoProduced, const FString& SyncTimestamp, bool bUpToDate, FText& OutReason)Start a generation from a sync output directory yourself. AlsoProduced names assets the sync wrote by another route, as source id to object path, so the sweep keeps them. bUpToDate skips the generation when the manifest is current and every recorded asset is still there. False with a reason when a generation is already running, the settings cannot be read, or Play In Editor is running.
bool IsGenerating() constA generation is in flight.
const TOptional<FTaleShardGenerationResult>& GetLastResult() constThe last generation’s result.
FOnTaleShardGenerationFinished& OnGenerationFinished()Fires once per generation with its FTaleShardGenerationResult — and also, as a failed result, when a sync’s generation refused to start.
static FString GeneratedPackagePath()The generated folder under the settings’ content root.
static FString TagIniDirectory()The host project’s Config/Tags folder, absolute.
static bool IsGeneratedClassPath(const FString& ClassPath)Whether a class path is one of the asset classes only the sync writes.

FTaleShardGenerationResult

What one generation did. HasErrors() is true when any diagnostic is an error, and a generation with one is a failed generation.

Field
bSuccessNo failure message and no error-level diagnostic.
bSkipped · SkipReasonNothing needed generating and nothing was touched, and why.
ErrorMessageWhy it failed, when it did. A refused start reads Asset generation did not start: and the reason.
DiagnosticsEvery FTaleShardDiagnosticEvent the plan and the commit reported.
AssetsWritten · AssetsDeletedAssets written and swept.
TagsWritten · bTagIniChangedGameplay tags written, and whether the tag ini on disk changed.
RedirectsWrittenGameplay tag redirects written, so a renamed tag keeps resolving.
bForcedFullRegenerationThe manifest was absent, unreadable or from another plugin version, so everything was regenerated.
ManifestStateThe manifest the run found — see below.
ElapsedMs · TimestampHow long it took, and when it ended, in local time.
SyncTimestampThe timestamp of the sync it followed, so the two results can be paired.
bCppGeneratedTyped C++ was written into the project’s source this run.
bCppSkippedThe C++ layer ran, found the schema unchanged, and wrote nothing.
CppFilesWritten · DataTablesWrittenWhat the C++ layer wrote.
bRestartRequiredA generated enum changed: restart the editor before opening a Blueprint that references it.
CppReportThe C++ change report — what was added, changed, removed or renamed, and what to do next. Empty when the layer did not run.

ETaleShardManifestState

Value
AbsentNo manifest asset exists — the normal first run. Ownership is inferred from asset classes.
UnreadableA manifest exists but would not load, is not a manifest, or has a layout this plugin does not know. Everything is regenerated.
VersionMismatchWritten by a different plugin version. Its records are used, and everything is regenerated.
CurrentWritten by this plugin version.

FTaleShardDiagnosticEvent

Both results carry their findings as FTaleShardDiagnosticEvent, the same struct the runtime reports with — see Diagnostics for the runtime’s codes.

Field
LevelAn ETaleShardDiagnosticLevel: Info, Warning or Error.
CodeA stable machine-readable code. Match on this, never on the message.
MessageThe human sentence.
BoardId · NodeId · FieldKeyWhere it applies, when it applies somewhere. Each is optional.

ToString() formats one for a log line.

The commandlets

Two commandlets reach the same machinery without a window, for a build machine or a test run. Both exit 0 on success and 1 otherwise, with every diagnostic in the log.

CommandletCommand lineDoes
UTaleShardImportCommandlet-run=TaleShardImport -from=<sync output directory>What ImportFromDirectory does: the payload asset, the media and every generated asset.
UTaleShardCodegenCommandlet-run=TaleShardCodegen -runtime=<runtime.json> -codegen=<codegen.json> -out=<folder> [-module=<name>] [-version=<text>]Only the typed C++, into a folder that is replaced whole. The module defaults to the project’s primary game module and the version to the plugin’s.

Both run as UnrealEditor-Cmd <project> followed by the arguments above.

Written for
Advanced integrators
Last updated