Semantic Mapping
A CLIFF clan expresses “which semantic family this piece of text belongs to” (interface label, prompt, proper noun, dialogue…), while a UE Namespace is the first segment of an FTextId. The two are not the same thing, and the plugin connects them with three configurable mapping tables — never hard-coded.
IMPORTANT
Watch out for the terminology clash: the CLIFF
namespace(the first segment of the canonical ID, equal to the CLIFF Namespace setting in the plugin) and the UEFTextKey Namespaceare two different concepts. Everywhere this page writes UE Namespace it means the latter. The CLIFF namespace never enters the UE Namespace.
The three mapping tables
| Setting | Direction | Purpose |
|---|---|---|
| Clan to Namespace | clan → UE Namespace | Decides which Namespace to write into on import; reverse lookup for clan on export |
| Namespace to Type | UE Namespace → CLIFF type | Derives type on export |
| Namespace to Emotion | UE Namespace → CLIFF emotion | Derives the default emotion on export |
Location: Edit > Project Settings > Plugins > CLIFF Localization Suite > Semantic Mapping.
Defaults
The built-in tables provided by FCliffSemanticMapping::CreateDefault(). The effective mapping = built-in defaults + the entries in Project Settings (on a duplicate key the project setting wins):
Clan to Namespace
| clan | UE Namespace |
|---|---|
category | UObjectCategory |
tooltip | UObjectToolTips |
short-tooltip | UObjectShortTooltips |
display-name | UObjectDisplayNames |
proper-noun | UObjectDisplayNames |
dialogue | Dialogue |
Namespace to Type
| UE Namespace | type |
|---|---|
UObjectCategory | label |
UObjectToolTips | prompt |
UObjectShortTooltips | prompt |
UObjectDisplayNames | proper-noun |
Dialogue | dialogue |
Namespace to Emotion
| UE Namespace | emotion |
|---|---|
Dialogue | neutral |
NOTE
Both
display-nameandproper-nounmap toUObjectDisplayNames: the former is the source “class/field display name”, the latter the conclusion “by semantics it is a proper noun”. The reverse lookup takes the first match, so the exported clan is usually the first item in the table. If your project needs more precise naming, simply delete the entries you do not want.
Import direction: clan → UE Namespace
The actual behaviour of FCliffSemanticMapping::ResolveNamespace(clan) (in the importer, CliffImporter.cpp):
- A hit in
ClanToNamespace→ use that UE Namespace (treated as an “explicit” mapping) - No hit → fall back to the CLIFF header’s
namespace(that is, the project identity itself, such asp-cliff-l10n-suite) and log the warning:CLIFF clan '…' has no semantic mapping; using CLIFF namespace '…' as UE namespace.
So a project that only writes clan: ui without configuring a mapping can still import; it is just that every entry lands under a UE Namespace named after the CLIFF namespace. If you want it to land in the project’s own UI namespace (say MyGameUI), add one mapping:
; Config/DefaultEditor.ini(也可以直接在项目设置面板里编辑)
[/Script/CliffLocalizationSuite.CliffLocalizationSuiteSettings]
+ClanToNamespace=(("ui", "MyGameUI"))
Export direction: UE Namespace → clan / type / emotion
clan (ResolveClanFromNamespace):
- Reverse lookup in
ClanToNamespace(exact value match) → return the matching clan - No hit → kebab-slug the UE Namespace: split camel case + lower-case + replace non-
[a-z0-9-]characters with-+ collapse/trim hyphens (UObjectDisplayNames→u-object-display-names) - Empty slug → use
ue - A miss logs a warning telling you to extend the mapping table
type (ResolveTypeForNamespace): use it when NamespaceToType has a hit, otherwise return empty and let the exporter fall back to sentence + warning.
emotion (ResolveEmotionForNamespace): use it when NamespaceToEmotion has a hit; otherwise the emotion field is not written and CLIFF’s default rules apply (dialogue / monologue / idiom → [neutral], everything else → [objective]).
What the UE side actually gives you
| UE text source | UE Namespace | Semantics you can derive |
|---|---|---|
C++ LOCTEXT | #define LOCTEXT_NAMESPACE, usually the module name | The Namespace alone cannot tell label from dialogue → defaults to sentence |
C++ NSLOCTEXT | Explicit parameter | Same as above |
Asset / Blueprint FText | The in-asset namespace (a package-localization namespace is stripped) | The site description looks like "{StructPath} [Script Bytecode]", so the semantics have to come from a rule table |
| Class / field DisplayName | Always UObjectDisplayNames | proper-noun |
| Class / field Tooltip | Always UObjectToolTips / UObjectShortTooltips | prompt |
UObject Category metadata | Always UObjectCategory (produced by GatherTextFromMetadata) | label |
| DialogueWave | Always Dialogue | dialogue |
TIP
To map your project’s own UI text to
labelas well, the least effort is to add a rule for that text’s Namespace. For example, use#define LOCTEXT_NAMESPACE "MyGameUI"consistently in the source and then:
Clan to Namespace: ui → MyGameUI
Namespace to Type: MyGameUI → label
On export the MyGameUI entries are written as clan: ui + type: label, and on import they travel back to MyGameUI the same way.
Degradation and warning rules
| Situation | Result |
|---|---|
| clan has no explicit mapping | UE Namespace = the CLIFF header’s namespace (round trips fine, but adding a mapping is advisable) |
| UE Namespace has no reverse mapping | clan = kebab-slug + warning |
type cannot be derived | type: sentence + warning |
emotion cannot be derived | The field is not written (the CLIFF default rules apply) |
| Metadata exists | Metadata outranks every mapping table (the semantics written by the previous import are not overwritten by the tables) |
NOTE
Because metadata has the highest priority, adjusting the mapping tables only affects existing UE data that has never been through a CLIFF round trip; entries that have been imported once keep their semantics stably and do not drift when the tables change.