Texturge Beta Architecture Overview

Texturge is a high-performance modular glyph processing and text animation engine plugin for UE 5.6+. Its core goal is turning static text into per-glyph drivable animations: at compile time the animations designers orchestrate in Blueprints are baked into runtime-efficient data structures, and at runtime they are evaluated per frame and rendered at high performance through UMG/Slate.

Module Layout

Texturge consists of two modules:

ModuleLoading phaseResponsibilities
Texturge (Runtime)DefaultBake compiler, curve data, Blueprint assets, stage controller, UMG widgets, rich text parsing, Unicode, localization
TexturgeEditor (Editor)Default (editor only)Animation Blueprint editor, designer viewport, preview arbitration, Sequencer track editing, Details customization

NOTE

Texturge has no separate Baker or Renderer module. Animation compilation happens in the runtime module’s pure-function compiler (FAnimationCompiler), and runtime rendering is handled by the native UMG/Slate pipeline.

Data Flow

Compile Time (Bake)

Input: UTextAnimationBlueprint + FString Text

  ├─ FAnimationCompiler::BuildScheduleInfos(Text)
  │     → TArray<FGlyphScheduleInfo> (prefilled index, character, glyph classification)

  ├─ FAnimationCompiler::BakeAllStages(BP, Text, Customizer)
  │     ├─ Create temp UTextAnimInstance → ProcessEvent invokes the BP event
  │     │     └─ BuildDefaultAnimation(GlyphCount, Text) → FBakedStage
  │     │           └─ Default implementation: CreateLayer → CreateFactory → AddLayer → Bake()
  │     │                 └─ UGlyphAnimationFactory::Bake() (three-step pipeline)
  │     │                       STEP 1:   per-layer independent bake BakeStageWithCurves
  │     │                       STEP 1.5: apply Layer-level GlyphCurveOverrides
  │     │                       STEP 2:   per-glyph per-layer copy → FPerLayerCurves
  │     │                       STEP 3:   factory-level post-processing (scheduling/tweaks/animation clip)
  │     └─ Assemble FBakedAnimation (Intro/Default/Outro + dual fingerprints)

  └─ Output: FBakedAnimation (cached by default in UTextAnimInstance::CachedBakedAnimation)

Runtime (Evaluate)

UAnimatedTextBlock (UMG)
  └─ UTextAnimationStageController::TickAnimation(dt)
       ├─ advance StageTime, detect stage boundaries (TransitionTo)
       └─ EvaluateAllGlyphs(OutStates)
             └─ FBakedGlyph::Evaluate(StageTime, OutState)
                   └─ per-layer FPerLayerCurves::Evaluate(LocalTime, InOutState)
                         ├─ 21 channels: BuildRichCurveFromKeys → Eval
                         └─ combine by BlendMode (empty channels skipped)
  └─ OnPaint reads FGlyphAnimationState per glyph → Slate drawing

Core Data Structures

FBakedAnimation (not a USTRUCT, held by TUniquePtr)
  ├── TUniquePtr<FBakedStage> IntroStage     ← may be nullptr
  ├── TUniquePtr<FBakedStage> DefaultStage   ← usually valid
  ├── TUniquePtr<FBakedStage> OutroStage     ← may be nullptr
  ├── uint64 TextFingerprint / BlueprintFingerprint
  └── FBakedStage (USTRUCT, fully UPROPERTY)
        ├── EAnimationStage StageType
        ├── int32  GlyphCount / float TotalDuration
        └── TArray<FBakedGlyph> Glyphs
              └── FBakedGlyph (USTRUCT)
                    ├── OriginalIndex / StartTime / Duration
                    ├── bIsStatic / DefaultState / bHideFirstFrame
                    ├── TArray<FPerLayerCurves> LayerCurves   ← 21 channels per layer
                    │     └── FPerLayerCurves
                    │           ├── BlendMode / PlayDirection / NumberOfLoops
                    │           ├── PlaySpeedMultiplier / LayerDuration
                    │           └── 21 × TArray<FRichCurveKey>
                    └── FGlyphCurveOverride FactoryOverride   ← factory-level tweaks

Glyph Animation State

FGlyphAnimationState (10 fields) is the runtime per-glyph rendering state:

GroupFields
TransformPositionOffset (FVector2D), Scale (FVector2D), Rotation (float), Shear (FVector2D), Pivot (FVector2D)
ColorColor (FLinearColor, RGB=tint color, A=tint share), Opacity (float)
ShadowShadowOffset (FVector2D), ShadowColor (FLinearColor)
TypographyLetterSpacing (float)

21 channels refers to the number of curve channels in FPerLayerCurves: 3 (Float) + 5×2 (Vector2D components) + 2×4 (Color components) = 21, each channel backed by a TArray<FRichCurveKey>.

Three-Layer Architecture

UMG presentation    UAnimatedTextBlock / UAnimatedRichTextBlock
   │                OnPaint drives Tick + per-glyph Slate drawing
Animation control   UTextAnimationStageController / UTextAnimator
   │                play, pause, stage transitions, evaluation
Data asset layer    UTextAnimationBlueprint / UGlyphAnimation / FBakedAnimation
                    compile-time bake results + fingerprint caching

Runtime Control

UTextAnimationStageController is the runtime playback engine: it maintains playback state and the stage clock, advances time, and broadcasts OnAnimationComplete when playback finishes. It supports play/pause/resume/stop, play direction (Forward / Reverse / PingPong), looping, and per-glyph evaluation.

Editor Workflow

[Blueprint editor] → [animation list + design viewport] → [compile] → [preview arbitration]
  1. Double-click a text animation blueprint (UTextAnimationBlueprint) to open FTextAnimationBlueprintEditor (Designer / Graph dual modes, 7 tabs)
  2. Add glyph animations (UGlyphAnimation) in the animation panel and edit keyframe curves in the Sequencer timeline
  3. In Graph mode, override the BuildDefaultAnimation event and orchestrate animations with Layer / Factory nodes
  4. Click CompileFTextAnimationBlueprintCompilerContext → generates UTextAnimationBlueprintGeneratedClass
  5. Preview live in the viewport through FPreviewSourceMediator (StagePreview / GlyphAnimation sources)

Core Design Principles

  1. Bake at compile time, zero compilation at runtime — curves are extracted into FBakedAnimation at compile time; runtime only evaluates
  2. Fully UPROPERTY-safeFBakedStage / FBakedGlyph are entirely composed of UPROPERTYs, so BlueprintNativeEvent carries zero crash risk
  3. Per-layer independent evaluation — eliminates curve-merge interpolation errors and FRichCurve::Eval extrapolation traps
  4. Fingerprint caching — dual invalidation: TextFingerprint (CityHash64 of text) + BlueprintFingerprint (asset signature + variables + CompileCount)
  5. Blueprint-programmable — designers fully control animation behavior by overriding a single event; 72+ Layer / Factory Blueprint functions can be chained
images/architecture-overview.png — Architecture overview diagram: left shows compile-time (UTextAnimationBlueprint + text → FAnimationCompiler → FBakedAnimation with three stages), right shows runtime (UTextAnimationStageController → FBakedGlyph::Evaluate → FGlyphAnimationState → UAnimatedTextBlock rendering), with Layer/Factory bake pipeline in the middle
images/data-flow.png — Data flow diagram: compile-time inputs (blueprint GlyphAnimations + StageTransitionConfig, source text) → BuildScheduleInfos and BuildDefaultAnimation event → factory three-step bake → FBakedAnimation with dual fingerprint cache; runtime StageController Tick → per-layer evaluation → per-glyph Slate drawing in OnPaint