Skip to content

Rune authoring

Overview

Rephrased is built around a sentence system. Players collect physical rune tablets, each carrying a word, and place them into slots attached to a Rune Calculator. When the filled slots form a valid sentence (NOUN + VERB, or NOUN + VERB + NOUN), the calculator applies the verb's effect to every matching Runeable Object in range.

The core loop for designers:

  1. Place Runeable Objects in the level and assign each a noun identity.
  2. Place a Rune Calculator and configure its slots, range, and feedback.
  3. Provide the player with Runes (via Rune Slots, Memory Palace, or Combine Slots).
  4. Use Camera Zones to frame the play area.

The rest of this document details each piece.

For engineering internals, see Rune system core, Rune actors and placement, and Effect components.

Shipping interaction: Players carry one rune at a time and press Interact at slots or loose runes. Target interaction is defined in the GDD — see Implementation status.

New to the editor? Read Unreal Editor 101 first, then open Rune Showcase for PIE.


1. Rune Data Assets

URuneDataAsset is the foundational data asset that defines a rune's identity. Every rune in the game references exactly one of these. Create new assets via the Content Browser: right-click, select Data Asset, and choose RuneDataAsset.

Properties

Property Type Category Description
RuneWord FText Rune Data The displayed word (e.g., "TREE", "FLOAT", "ROCK"). This is what the player reads.
WordType EWordType Rune Data Either NOUN or VERB. Determines grammar role and which conditional fields appear in the editor.
EnglishDefinition FText (multiline) Rune Data Definition shown in UI when the player inspects the rune.
RuneVisualMesh UStaticMesh Rune Data The 3D mesh representing the physical rune tablet -- the object the player picks up and carries.

Noun-Specific Fields

These fields are only visible when WordType is set to NOUN.

Property Type Category Description
NounMesh UStaticMesh Noun Data The mesh that Runeable Objects display when they take on this noun identity. Every noun rune needs this assigned.
NounMaterials TArray\<UMaterialInterface> Noun Data Materials applied to NounMesh. If left empty, the mesh's built-in materials are used.
bNounSimulatesPhysics bool Noun Data When true, RuneableObjects with this noun fall under gravity. Used by nouns like Campfire that should settle on the ground.
InherentEffectComponents TArray\<TSubclassOf\<URuneEffectComponent>> Noun Data Components that activate automatically when an object becomes this noun. Campfire carries a FireComponent here so it always burns.
VerbComponentOverrides TMap\<URuneDataAsset, TSubclassOf\<URuneEffectComponent>> Noun Data Per-noun overrides: when verb V hits an object whose noun has an entry for V, the override component class is used instead of the verb's default.

Verb-Specific Fields

These fields are only visible when WordType is set to VERB.

Property Type Category Description
TwoWordEffectComponent TSubclassOf\<URuneEffectComponent> Verb Data The component class applied to targets in 2-word sentences (NOUN + VERB).
ThreeWordEffectComponent TSubclassOf\<URuneEffectComponent> Verb Data The component class applied in 3-word sentences (NOUN + VERB + NOUN). If left null, falls back to TwoWordEffectComponent.

If both TwoWordEffectComponent and ThreeWordEffectComponent are null, the verb is treated as the IS (Transform Into) verb, which swaps noun identity instead of applying a component.

Split Data

Property Type Category Description
bIsSplittable bool Rune Split Data Whether the rune can be split into sub-runes. Default: false.
RuneSplitData TArray\<URuneDataAsset> Rune Split Data The runes produced by splitting. Only visible when bIsSplittable is true.

Audio

Property Type Category Description
PickupSound USoundBase Audio Played when the player picks up a rune with this data.
PlaceSound USoundBase Audio Played when the player places the rune in a slot.
SplitSound USoundBase Audio Played when the rune is split.
ActivationSound USoundBase Audio Played when a sentence containing this rune activates.

All audio fields default to null. When null, the system falls back to default sounds defined on the slot or calculator.

Configuration Summary

  • Every noun rune needs NounMesh assigned. NounMaterials is optional.
  • Every verb rune needs at least TwoWordEffectComponent assigned, unless the verb is intended to be the identity-swap ("IS") verb, in which case leave both effect fields null.
  • RuneVisualMesh is required for all runes. This is the physical tablet the player sees and carries.

Merge Recipe Data Asset

UMergeRecipeDataAsset defines combinations for merging runes in Combine Slots. Create one via the Content Browser the same way as any data asset.

Property Type Description
Recipes TArray\<FMergeRecipe> Array of merge recipes.

Each FMergeRecipe entry contains:

Field Type Description
InputRunes TArray\<URuneDataAsset> The runes that must be present in the Combine Slot to trigger this recipe. Order does not matter.
OutputRune URuneDataAsset The rune produced when the recipe is matched.

2. Runes

ARune is the physical actor the player picks up, carries, and places into slots.

Properties

Property Type Default Description
RuneData URuneDataAsset -- Which rune this is. Controls the visual mesh (pulled from RuneData->RuneVisualMesh) and all downstream behavior.
FloatAmplitude float 20.0 Vertical bob amplitude (in units) when the rune is sitting in a slot.
FloatSpeed float 2.0 Bob animation speed.
DiscoveryVFXTemplate UParticleSystem null Cascade particle effect played on first pickup.
DiscoveryNiagaraVFX UNiagaraSystem null Niagara particle effect played on first pickup.

When Designers Need to Touch ARune

Rarely. Designers should not place ARune actors directly in the level. Instead, configure Rune Slots to spawn runes at BeginPlay via bSpawnWithInitialRune + InitialRuneData, or use Combine Slots / Memory Palace Slots. The ARune actor gets its mesh from RuneData->RuneVisualMesh automatically at spawn time.

The only case to manually place an ARune is if a rune needs to exist as a loose pickup in the world without being associated with any slot.


3. Rune Slots

All slot types derive from ARuneSlot. Each holds one rune (or a stack, in the case of Combine Slot). The player interacts with slots to place, take, or swap runes.

3.1 Base Slot (ARuneSlot)

The standard slot. Holds one rune. Player can place, take, or swap runes freely.

Property Type Default Category Description
bSpawnWithInitialRune bool false Slot|Initial Rune If true, spawns a rune at BeginPlay.
InitialRuneData URuneDataAsset -- Slot|Initial Rune Which rune to spawn. Only visible when bSpawnWithInitialRune is true.
bIsMemoryPalaceSlot bool false Slot Legacy flag for palace behavior. Prefer using the AMemoryPalaceSlot subclass instead.
PalaceRuneData URuneDataAsset -- Slot Rune data for palace behavior. Only visible when bIsMemoryPalaceSlot is true.
RuneHeightOffset float 50.0 Slot Vertical offset (in units) of the rune above the slot slab.
HighlightMaterial UMaterialInterface -- Visual Material applied to the slab when a rune is placed.
HoverMaterial UMaterialInterface -- Visual Material applied to the slab when the player aims at the slot.
DefinitionWidgetClass TSubclassOf\<UUserWidget> -- UI Widget class displayed when the player is near and a rune is present.
DefaultSlotPlacementSound USoundBase null Audio Fallback placement sound used when the rune's own PlaceSound is null.
OnSlotChanged Delegate -- Events Broadcast when a rune is placed or removed. This is how Rune Calculators listen for slot changes.

3.2 Test Slot (ATestSlot)

Accepts only one specific rune. Used for puzzle gates where the player must place a particular rune.

Property Type Default Description
DedicatedRune URuneDataAsset null The only rune this slot will accept. All other runes are rejected.

Test Slots include a spotlight component that reacts to rune presence (on when the correct rune is placed, off otherwise). The player borrows the rune -- they can take it out and use it elsewhere. The slot tracks whether its dedicated rune has been placed and removed.

Inherits all base ARuneSlot properties.

3.3 Combine Slot (ACombineSlot)

Stacks multiple runes and can merge them into a new rune via recipes.

Property Type Default Description
RecipeData UMergeRecipeDataAsset -- Defines valid merge combinations.
InitialRunes TArray\<URuneDataAsset> empty Runes pre-loaded into the stack at BeginPlay.

Runtime behavior: the slot maintains a RuneStack (TArray). When runes matching a recipe's InputRunes are all present in the stack, they auto-merge into the recipe's OutputRune. The merge is immediate.

Inherits all base ARuneSlot properties.

3.4 Memory Palace Slot (AMemoryPalaceSlot)

A dedicated "home" slot for a specific rune in the memory palace area.

Property Type Default Description
DedicatedRune URuneDataAsset null Which rune belongs in this slot.

Memory Palace Slots include a spotlight and a 3D definition text component that update based on rune presence. The player can borrow the rune for use in puzzles elsewhere. The system tracks the home slot so the rune can be auto-returned if needed.

Inherits all base ARuneSlot properties.


4. Rune Calculator

ARuneCalculator is the core puzzle mechanism. It owns a set of Rune Slots, validates the rune arrangement as a sentence, and applies effects to Runeable Objects in the world. This section walks through every step of editor setup.

A. Place the Actor

Drag ARuneCalculator (or a Blueprint subclass) from the Content Browser into the level. The actor's position determines where auto-created slots spawn and the center of the effect range sphere.

B. Configure the Slot Layout

Two layout modes are available, controlled by bUseGridLayout.

Linear Mode (default: bUseGridLayout = false)

Property Type Default Constraints Description
NumSlots int32 3 2--3 Number of slots arranged in a line.
SlotSpacing float 150.0 -- Distance (in units) between each slot.
  • 2 slots: only 2-word sentences (NOUN + VERB).
  • 3 slots: supports 3-word sentences (NOUN + VERB + NOUN) and 2-word sentences if only 2 slots are filled.

Grid Mode (bUseGridLayout = true)

Property Type Default Constraints Description
GridWidth int32 3 1--10 Number of columns.
GridHeight int32 3 1--10 Number of rows.
EmptySlotPositions TArray\<bool> empty Size = GridWidth * GridHeight Flat array indexed row-major. Set an entry to true to leave that grid cell empty (no slot spawned). Use this to create irregular grid shapes.
SlotSpacing float 150.0 -- Distance between grid cells.

At runtime, the grid is scanned for valid sentences across horizontal rows and vertical columns. 3-word sentences take priority over 2-word sentences. A single grid can produce multiple simultaneous sentences.

C. Choose Slot Source

The calculator resolves slots in this priority order:

  1. ManualSlots (TArray\<ARuneSlot>): Drag existing slot actors from the level into this array. Use this when you need precise manual placement or want to reuse slots across calculators.

  2. Child Actor Components named Slot_0, Slot_1, etc.: If you add ChildActorComponents to a Calculator Blueprint subclass, the calculator detects them by name.

  3. bAutoCreateSlots (bool, default true): The calculator spawns its own slots at BeginPlay using the configured layout and SlotClass.

Property Type Default Description
ManualSlots TArray\<ARuneSlot> empty Manually assigned slot references.
bAutoCreateSlots bool true Whether to auto-spawn slots at BeginPlay.
SlotClass TSubclassOf\<ARuneSlot> ARuneSlot Which slot class to spawn during auto-creation.

If ManualSlots has entries, auto-creation is skipped regardless of bAutoCreateSlots.

D. Configure the Effect Range

Property Type Default Description
bUseGlobalEffects bool false When true, effects apply instantly to ALL matching Runeable Objects in the entire level. No range sphere, no expanding ring.

When bUseGlobalEffects = false (range-based)

Property Type Default Constraints Description
RuneableRangeSphere USphereComponent -- Scale in viewport The detection radius. Select this component in the viewport and scale it to cover the desired play area. Visible as a wireframe sphere in the editor.
RingExpansionDuration float 1.5 0.1--10.0 How long (in seconds) the expanding ring takes to reach full radius. Shorter values mean faster effect propagation.
bLockPlayerDuringActivation bool true -- Freezes player input while the ring expands.
RingActorClass TSubclassOf\<AExpandingRingActor> -- -- Override the visual ring effect actor. Leave null for the default ring.

E. Configure Showcase Camera (optional)

Only available when bUseGlobalEffects is false. Controls a cinematic camera that follows the expanding ring to show targets being affected.

Property Type Default Constraints Description
ShowcaseMode EShowcaseMode Disabled -- Disabled: no showcase camera. PauseAtTarget: ring pauses at each target, camera holds, then ring resumes. LeadingSphere: camera leads ahead of the ring, panning between targets.
bShowcaseSingleTarget bool true -- If false, showcase only activates when there are multiple targets in range.
ShowcaseBlendTime float 0.4 0.1--2.0 Camera blend duration (seconds) between targets.
ShowcaseHoldDuration float 1.0 0.2--5.0 How long (seconds) the camera lingers on each target.
ShowcaseCameraPitch float 50.0 10.0--85.0 Pitch angle (degrees) of the showcase camera relative to the target.
ShowcaseCameraDistance float 500.0 -- Orbit distance (units) from the target.
ShowcaseGroupingRadius float 200.0 50.0--1000.0 Only for LeadingSphere mode. Targets closer than this distance to each other are grouped into a single camera shot.

F. Configure Slot VFX

Property Type Default Constraints Description
SlotActivationMode ESlotActivationMode Simultaneous -- Simultaneous: all participating slots fire their ring VFX at once. Sequential: slots activate one by one with a delay before the expanding ring starts.
SequentialSlotDelay float 0.3 0.1--3.0 Only for Sequential mode. Delay (seconds) between each slot's activation.

G. Runtime Behavior

When a player places or removes a rune from any connected slot, the calculator executes this sequence:

  1. Collects all filled slots.
  2. Validates sentence grammar (must be NOUN + VERB or NOUN + VERB + NOUN).
  3. For grid layouts: scans all rows and columns. 3-word sentences consume their slots first to avoid double-counting.
  4. Checks calculator priority. If multiple calculators target the same subject noun, the most recently modified calculator wins. Priority is tracked via LastModifiedTime.
  5. Selects the effect strategy based on the verb's data asset configuration (component-based or identity-swap).
  6. Applies effects either globally or via the expanding ring, depending on bUseGlobalEffects.
  7. When a rune is later removed and the sentence breaks, all effects from that sentence are automatically reverted.

H. Common Configurations

Simple 2-slot puzzle NumSlots = 2, bUseGlobalEffects = true. Player places NOUN + VERB, effect applies instantly to all matching objects in the level. No range sphere or ring visual. Good for introductory puzzles with low complexity.

3-slot range puzzle NumSlots = 3, bUseGlobalEffects = false. Scale the RuneableRangeSphere to cover the play area. Set ShowcaseMode to PauseAtTarget or LeadingSphere for cinematic feedback. The player sees the ring expand outward and hit targets one by one.

Crossword grid bUseGridLayout = true, set GridWidth and GridHeight (e.g., 5x5). Use EmptySlotPositions to carve out an irregular shape. Multiple sentences can form simultaneously across rows and columns. 3-word sentences are prioritized.

Manual slot placement bAutoCreateSlots = false. Drag existing slot actors from the level into ManualSlots. Use this when slots need to be at specific narrative-meaningful positions (e.g., embedded in a wall, on pedestals at different heights). The calculator still handles sentence validation and effect application.


5. Camera Zones

ACameraZoneActor is a trigger volume that overrides the game camera when the player enters it.

Properties

Property Type Default Condition Description
ZoneBounds UBoxComponent -- -- The trigger volume. Scale this in the viewport to define the zone area.
ZoneCamera UCameraComponent -- -- Position, rotate, and set FOV of this component to define the camera angle. Default orientation: 800 units above, pitched -50 degrees, FOV 30.
BlendTime float 0.5 -- Transition duration in seconds. Used for time-based blending and exit transitions.
BlendFunc EViewTargetBlendFunction EaseInOut -- Blend curve type.
bUseTimeBasedBlend bool false -- False: position-based blend. True: time-based blend (see below).
TransitionDepth float 250.0 !bUseTimeBasedBlend How far (units) the player must walk into the zone before the camera fully transitions. Blend alpha = penetration depth / TransitionDepth. Min: 50.0.
AlphaSmoothingSpeed float 12.0 !bUseTimeBasedBlend How quickly the blend tracks the player's position. Higher = more responsive but may jitter. Lower = smoother but laggy. Min: 1.0.
Priority int32 0 -- When zones overlap, higher priority wins.
bTrackPlayer bool false -- If true, the camera follows the player's XY movement while maintaining its authored height and angle.
TrackingInterpSpeed float 3.0 bTrackPlayer How quickly the camera follows the player.
bClampTracking bool true bTrackPlayer If true, limits how far the camera can offset from its authored position.
TrackingClampExtent FVector2D (100, 100) bTrackPlayer && bClampTracking Maximum X/Y offset (units) from the authored camera position.

Blend Modes

Position-based (bUseTimeBasedBlend = false): The camera interpolates between the previous view and the zone camera based on how deep the player is inside the zone. This creates a natural "walking into a new camera angle" feel. TransitionDepth controls how far in the player must walk before the zone camera takes full effect. AlphaSmoothingSpeed smooths the tracking to avoid jitter.

Time-based (bUseTimeBasedBlend = true): The camera blends over BlendTime seconds regardless of player position. Better for sharp transitions where the zone boundary is a hard cut.

Zone Stacking

Camera zones maintain a priority-sorted stack internally. When the player enters a higher-priority zone, that zone's camera takes over. When the player exits, the camera returns to the next zone in the stack. When all zones are exited, the camera returns to the player's default third-person camera.

Zones can overlap freely. Use Priority to control which zone wins in overlap regions. A common pattern is a large zone at priority 0 covering a room, with smaller zones at priority 1 or 2 for specific puzzle stations within the room.


6. Runeable Objects

ARuneableObject is a world actor that the rune system can affect. These are the targets of rune sentences.

Properties

Property Type Default Category Description
InitialNounData URuneDataAsset -- Rune Identity The starting noun identity. Determines the initial mesh, materials, and which sentences can target this object.
NounToMeshMap TMap\<URuneDataAsset, UStaticMesh> empty Manual Overrides Per-instance mesh overrides. If a noun transformation changes this object to a noun that exists in this map, the override mesh is used instead of the noun's default NounMesh.

Runtime State (read-only, for debugging)

Property Type Default Description
CurrentNounData URuneDataAsset = InitialNounData The object's active noun identity. Changes when the IS verb is applied.
bIsDisabled bool false Whether the object is currently hidden/disabled by a verb effect.
RuneSpeedScale float 1.0 Cumulative speed modifier from Slow/Accelerate effects.
RuneDirectionScale float 1.0 Direction multiplier from Reverse effect. -1.0 inverts movement direction.

Setup

  1. Place an ARuneableObject (or Blueprint subclass) in the level.
  2. Assign InitialNounData to a noun-type RuneDataAsset (e.g., the "TREE" data asset).
  3. The object's mesh is set automatically from the noun's NounMesh at BeginPlay.
  4. If you need a custom mesh when this specific object transforms into a different noun, add entries to NounToMeshMap.

Registration

Every ARuneableObject registers itself with the URuneableObjectRegistry world subsystem at BeginPlay based on its InitialNounData. When a calculator forms a sentence targeting noun X, it queries the registry for all objects with noun X. Designers do not interact with the registry directly. It is fully automatic.

When the IS verb changes an object's noun, the registry is updated atomically (unregistered from old noun, registered to new noun).


Quick Reference: Sentence Grammar

Pattern Slots Example Behavior
NOUN + VERB 2 TREE FLOAT Applies the verb's TwoWordEffectComponent to all objects with noun TREE.
NOUN + VERB + NOUN 3 TREE MOVETOWARD ROCK Applies the verb's ThreeWordEffectComponent (or falls back to TwoWordEffectComponent) to TREE objects, passing ROCK as the object noun for relational effects.
NOUN + IS + NOUN 3 TREE IS ROCK Identity swap. All TREE objects become ROCK objects (mesh, materials, registry entry).

Sentences are read left-to-right in linear mode. In grid mode, rows are read left-to-right and columns top-to-bottom. 3-word sentences are always prioritized over 2-word sentences.

Sentence patterns are defined in the GDD. The calculator validator today accepts NOUN + VERB, NOUN + VERB + NOUN, and NOUN + IS + NOUN only. VERB + NOUN (GDD pattern) is not validated yet — see GDD implementation status.

Incomplete or grammatically invalid arrangements (for example NOUN + NOUN with no verb) do nothing.


Quick Reference: Verb Effects

Full C++ roster and BP assignment notes: Effect components. On data assets, use BP_*Component classes in Details, not the bare U* types.

Verb 2-Word Behavior (NOUN + VERB) 3-Word Behavior (NOUN + VERB + NOUN) Component Class
FloatUp Disables gravity, floats the object upward to a configurable height, hovers with spring-damper physics. Same as 2-word, applied to subject. UFloatUpComponent
Rotate Continuous Z-axis rotation. Same as 2-word, applied to subject. URotateComponent
MoveToward Not applicable (requires object noun). Subject moves toward the nearest instance of the object noun. UMoveTowardComponent
Penetration Object passes through everything except ground. Object passes through the specified object noun only. UPenetrationComponent
Hidden Hides the object immediately. Hides the object when it collides with the specified object noun. UHiddenComponent
Burn Sets the object on fire with spreading flame effects. Same as 2-word. UFireComponent
Dangerous Object hurts the player on contact (pushback + death material). Same as 2-word. UDangerousComponent
Slow Halves rune-driven movement velocities (RuneSpeedScale *= 0.5). Same as 2-word. USlowComponent
Accelerate Doubles rune-driven movement velocities (RuneSpeedScale *= 2.0). Same as 2-word. UAccelerateComponent
Reverse Negates rune-driven movement direction (RuneDirectionScale *= -1). Same as 2-word. UReverseComponent
Enlarge Scales the object up uniformly. Same as 2-word. UEnlargeComponent
Shrink Scales the object down uniformly. Same as 2-word. UShrinkComponent
Mature Advances growth stage on supported runeables. Same as 2-word. UMatureComponent
Regress Reverses maturation on supported runeables. Same as 2-word. URegressComponent
Stop Disables physics simulation. Has special behavior for specific object types (e.g., extinguishes campfires). Same as 2-word. UStopComponent
Passing Timed passage effect; used by clock/observatory puzzles. Same as 2-word. UPassingComponent
IS (Transform Into) Not applicable (requires object noun). Changes the object's noun identity: swaps mesh, materials, and registry entry. The object becomes the other noun. None (identity swap, no component)

All verb effects are automatically reverted when the sentence is broken (rune removed from a slot).

Change history

  • 2026-05-23 — Gabriel Li — Removed document header; page starts at Overview with callouts below core loop; GDD-aligned grammar; verb roster synced with EffectComponents; carry vs Interact Mode; Editor 101 and Rune Showcase prerequisite.
  • 2026-05-08 — Gabriel Li — Added baseline change history section for weekly wiki maintenance.