Runtime Module Overview
CliffLocalizationSuite (Type: Runtime, LoadingPhase: Default) is a pure data and algorithms module: CLIFF 1.0 parsing, validation, serialization, semantic mapping and the plugin settings all live here. It does not depend on UnrealEd / AssetTools / Slate, so it can be used directly in Game targets, command line tools and even unit tests.
Dependencies
PublicDependencyModuleNames: Core, CoreUObject, Engine, DeveloperSettings
PrivateDependencyModuleNames: (empty)
What it provides
| Type | File | Responsibility |
|---|---|---|
FCliffDocument | Public/Cliff/CliffDocument.h | Parse entry point and document root object |
FCliffHeader / FCliffGroup / FCliffEntry | Same as above | The CLIFF data model (header / group / entry) |
FCliffValidationIssue / ECliffValidationCategory | Same as above | Validation issues and their 7 categories |
FCliffSemanticMapping | Public/Cliff/CliffSemanticMapping.h | clan ↔ UE Namespace, type / emotion rules |
FCliffSerializer | Public/Cliff/CliffSerializer.h | Canonical CLIFF 1.0 serialization |
UCliffLocalizationSuiteSettings | Public/Settings/CliffLocalizationSuiteSettings.h | Project Settings and the effective mapping |
ECliffDeepSeekThinkingLevel | Same as above | Thinking level enum (for configuration) |
Typical usage
Parse and validate
#include "Cliff/CliffDocument.h"
const FString Text = FFileHelper::LoadFileToString(CliffFilePath);
FCliffDocument Document;
TArray<FCliffValidationIssue> Issues;
// 传路径可额外做「文件名/目录 ↔ header」布局一致性检查
const bool bOk = FCliffDocument::ParseAndValidate(Text, CliffFilePath, Document, Issues, /*bCheckWidth=*/false);
if (!bOk)
{
for (const FCliffValidationIssue& Issue : Issues)
{
if (Issue.IsError())
{
UE_LOG(LogTemp, Error, TEXT("line %d [%d] %s"), Issue.Line, static_cast<int32>(Issue.Category), *Issue.Message);
}
}
return;
}
Iterate entries and generate canonical IDs
for (const FCliffGroup& Group : Document.Groups)
{
for (const FCliffEntry& Entry : Group.Entries)
{
const FString CanonicalId = Document.GetCanonicalId(Group, Entry); // namespace.clan.group.entry
const FString Source = Entry.Source.Get(TEXT(""));
const FString Type = Entry.Type.IsSet() ? Entry.Type.GetValue() : Group.Type.GetValue();
const FString Status = Entry.Status.Get(TEXT("initial"));
// …
}
}
Semantic mapping
#include "Settings/CliffLocalizationSuiteSettings.h"
const UCliffLocalizationSuiteSettings* Settings = GetDefault<UCliffLocalizationSuiteSettings>();
const FCliffSemanticMapping Mapping = Settings->GetSemanticMapping();
bool bExplicit = false;
const FString UENamespace = Mapping.ResolveNamespace(TEXT("category"), &bExplicit); // UObjectCategory
const FString Clan = Mapping.ResolveClanFromNamespace(TEXT("UObjectToolTips"), &bExplicit); // tooltip
const FString Type = Mapping.ResolveTypeForNamespace(TEXT("Dialogue")); // dialogue
const FString Emotion = Mapping.ResolveEmotionForNamespace(TEXT("Dialogue"));// neutral
Serialization
#include "Cliff/CliffSerializer.h"
const FString CanonicalText = FCliffSerializer::Serialize(Document); // UTF-8 无 BOM、LF 由调用方写盘时决定
FFileHelper::SaveStringToFile(CanonicalText, *OutPath, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM);
Build a document from scratch and export it
FCliffDocument Document;
Document.Header.Namespace = TEXT("my-game");
Document.Header.Clan = TEXT("ui");
Document.Header.SourceLanguage = TEXT("en-US");
Document.Header.TargetLanguage = TEXT("zh-Hans");
FCliffGroup& Group = Document.Groups.AddDefaulted_GetRef();
Group.Path = TEXT("options");
FCliffEntry& Entry = Group.Entries.AddDefaulted_GetRef();
Entry.Id = TEXT("resolution");
Entry.Source = TEXT("Resolution");
Entry.Target = TEXT("分辨率");
Entry.Type = TEXT("noun");
Entry.Status = TEXT("final");
NOTE
The model layer performs no vocabulary validation — illegal fields constructed this way are only reported as
vocabularyissues once you callDocument.Validate(). RunningParseAndValidatebefore writing to disk is always recommended.
Notes
| Item | Description |
|---|---|
| Threading | All types are pure value types / stateless utilities and can be constructed and parsed on any thread; but UCliffLocalizationSuiteSettings::Get() is a UObject and can only be accessed on the game thread |
| Large files | Parsing processes the whole text in one go (no streaming API); shard very large files yourself |
| Comment retention | The parser does not keep comments in the data model (consistent with the CLIFF specification); only the file header comment the exporter deliberately writes is carried through serialization |
| Encoding | Input may contain a BOM (stripped) and CRLF (treated as LF); a bare CR is a syntax error; serialized output should use ForceUTF8WithoutBOM |
x- extensions | Kept in the Extensions map, classified as extension during validation and not counted as a failure |
Next
- Runtime class reference — every field and method signature
- Importer and exporter — the Editor module API