<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog |</title><link>https://example.com/blog/</link><atom:link href="https://example.com/blog/index.xml" rel="self" type="application/rss+xml"/><description>Blog</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Tue, 02 Jun 2026 00:00:00 +0000</lastBuildDate><image><url>https://example.com/media/icon_hu_e5ffefdcd177be74.png</url><title>Blog</title><link>https://example.com/blog/</link></image><item><title>My Unreal Engine Profiling &amp; Tracing Launch Arguments</title><link>https://example.com/blog/ue-tracing-commands/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://example.com/blog/ue-tracing-commands/</guid><description>&lt;p&gt;A reference list of executable launch parameters for profiling Unreal Engine with Unreal Insights—covering CPU traces, Garbage Collection logging, Slate UI performance, context switches, File I/O, and world streaming.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-base-settings"&gt;The Base Settings&lt;/h2&gt;
&lt;p&gt;Most of these configurations share a common set of baseline parameters designed to stabilize performance and enable standard profiling markers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-statnamedevents&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Translates traditional engine stat counters (like &lt;code&gt;stat game&lt;/code&gt; or custom cycle counters) into named event markers that appear in the Unreal Insights timeline.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-NoVerifyGC&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Disables heavy garbage collection validation checks. This avoids massive frame spikes that would otherwise pollute profiling captures.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-DPCvars=&amp;quot;gc.VerifyAssumptionsOnFullPurge=0&amp;quot;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Directly overrides the Device Profile Config (DPC) variable to disable verifying GC assumptions during a full purge, further speeding up GC behavior during profiling.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="1-cpu-tracing"&gt;1. CPU Tracing&lt;/h2&gt;
&lt;p&gt;For basic CPU profiling, use this layout to capture the default engine events along with detailed task graph scheduling.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;default,task -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-trace=default,task&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables the standard performance counters (&lt;code&gt;default&lt;/code&gt;) and tracks task execution across the Engine&amp;rsquo;s Thread Pool (&lt;code&gt;task&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-cpu-tracing-with-in-game-graphs"&gt;2. CPU Tracing with In-Game Graphs&lt;/h2&gt;
&lt;p&gt;If you need visual feedback on performance spikes in real-time while recording a trace, this variation displays the unit graph and FPS counters on screen.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;default,task -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt; -ExecCmds&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;stat unitgraph, stat fps&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-ExecCmds=&amp;quot;stat unitgraph, stat fps&amp;quot;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Executes these console commands immediately on launch so that the scrolling timeline and framerate graphs are visible as you test.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-garbage-collection-profiling"&gt;3. Garbage Collection Profiling&lt;/h2&gt;
&lt;p&gt;Garbage collection (GC) can cause sudden, periodic frame drops. Use these arguments to output detailed GC logging alongside your performance trace to correlate hitches with GC sweeps.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;default,task -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt; -ExecCmds&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;stat unitgraph, stat fps&amp;#34;&lt;/span&gt; -LogCmds&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LogGarbage Verbose&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-LogCmds=&amp;quot;LogGarbage Verbose&amp;quot;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the garbage collection logger to &lt;code&gt;Verbose&lt;/code&gt; level, printing detailed reports of every object collected, sweep duration, and purge cycle to the log.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-profiling-without-ensures"&gt;4. Profiling Without Ensures&lt;/h2&gt;
&lt;p&gt;An &lt;code&gt;ensure&lt;/code&gt; or &lt;code&gt;ensureAlways&lt;/code&gt; statement that fails will capture a callstack, which can stall the game thread for several milliseconds. To make sure developer-facing ensures don&amp;rsquo;t artificially skew your profiling data, use this configuration to ignore them.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;default,task -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt; -ExecCmds&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;stat unitgraph, stat fps&amp;#34;&lt;/span&gt; -HandleEnsurePercent&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-HandleEnsurePercent=0&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Instructs the engine to skip capturing callstacks or executing error-handling routines for ensures, treating them as simple pass-through statements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="5-combined-cpu-gc--ensure-disabled-profiling"&gt;5. Combined CPU, GC, &amp;amp; Ensure-disabled Profiling&lt;/h2&gt;
&lt;p&gt;For a comprehensive profiling configuration that tracks CPU and task graphs, outputs verbose Garbage Collection logging, displays in-game statistics, disables heavy GC verification, and ignores ensures, combine all parameters:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;default,task,counters -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt; -ExecCmds&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;stat unitgraph, stat fps&amp;#34;&lt;/span&gt; -LogCmds&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;LogGarbage verbose&amp;#34;&lt;/span&gt; -HandleEnsurePercent&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="6-context-switch--thread-scheduling"&gt;6. Context Switch &amp;amp; Thread Scheduling&lt;/h2&gt;
&lt;p&gt;If you are investigating thread contention, core scheduling, or suspect that threads are blocking each other, you need to capture thread context switches at the OS level.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;taskgraph,contextswitch -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-trace=taskgraph,contextswitch&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Captures high-frequency scheduling events, letting you visualize when and why threads are being swapped out on CPU cores.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context Switch Administrator Requirement&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;The
channel lets you see when a thread is not getting CPU cycles. To capture context switches on Windows you must run the UE application as administrator. Otherwise, leave the &lt;code&gt;contextswitch&lt;/code&gt; channel disabled to prevent log spam.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="7-file-io--loading-times"&gt;7. File I/O &amp;amp; Loading Times&lt;/h2&gt;
&lt;p&gt;When profiling level transition hiccups, asset loading, or initial startup bottlenecks, use these trace channels to monitor disk activity and serialization.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;cpu,file,assetloadtime,loadtimes,iostore,contextswitch -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-trace=cpu,file,assetloadtime,loadtimes,iostore,contextswitch&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables detailed tracking of:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cpu&lt;/code&gt;: Main CPU thread timelines.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;file&lt;/code&gt;: Standard file read/write calls.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assetloadtime&lt;/code&gt;: High-level asset loading metrics.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;loadtimes&lt;/code&gt;: Detailed package serialization and loading stages.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iostore&lt;/code&gt;: Zen/I/O Store requests for packaged builds.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contextswitch&lt;/code&gt;: Context switching to see load-thread wakeups.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="8-slate-ui-profiling"&gt;8. Slate UI Profiling&lt;/h2&gt;
&lt;p&gt;To profile UI performance and analyze widget tick, layout, and paint evaluation timelines in Unreal Insights, pass the &lt;code&gt;slate&lt;/code&gt; trace channel to the &lt;code&gt;-trace&lt;/code&gt; argument.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;default,task,slate -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;slate&lt;/code&gt; Trace Channel (&lt;code&gt;-trace=...,slate&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;Enables the &lt;code&gt;slate&lt;/code&gt; trace channel to record UI widget timing, layout, tick, and paint event timelines in Unreal Insights.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WITH_VERY_VERBOSE_SLATE_STATS&lt;/code&gt; Macro
&lt;ul&gt;
&lt;li&gt;To record complete, granular per-widget telemetry and detailed Slate hierarchy breakdowns in Insights, compile the engine or project with the &lt;code&gt;WITH_VERY_VERBOSE_SLATE_STATS&lt;/code&gt; preprocessor macro enabled (&lt;code&gt;#define WITH_VERY_VERBOSE_SLATE_STATS 1&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="9-world-streaming--world-partition-profiling"&gt;9. World Streaming &amp;amp; World Partition Profiling&lt;/h2&gt;
&lt;p&gt;When diagnosing streaming hitches, level streaming stalls, or World Partition cell loading/unloading bottlenecks, you need simultaneous visibility across disk I/O, asset serialization, async worker tasks, physics lock contention, and thread scheduling.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-trace&lt;span class="o"&gt;=&lt;/span&gt;default,counter,stats,file,loadtime,assetloadtime,task,chaoslocks,contextswitch -statnamedevents -NoVerifyGC -DPCvars&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gc.VerifyAssumptionsOnFullPurge=0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-trace=default,counter,stats,file,loadtime,assetloadtime,task,chaoslocks,contextswitch&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables telemetry across the core world streaming pipelines:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;default&lt;/code&gt;: Standard baseline engine timeline events (CPU frames, bookmarks).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;counter&lt;/code&gt;: Tracks numeric metrics and telemetry values over time (e.g., streaming pool budgets, resident cell counts).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stats&lt;/code&gt;: Emits STAT system stats and cycle counters into the trace.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;file&lt;/code&gt;: Low-level file system activity (file opens, async reads, seeks).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;loadtime&lt;/code&gt;: Package loading, serialization stages, and linker phases.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assetloadtime&lt;/code&gt;: High-level asset instantiation and registration timing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;task&lt;/code&gt;: Task Graph and Task System execution across worker threads.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chaoslocks&lt;/code&gt;: Chaos physics lock contention, scene sync points, and mutex wait times when generating collision for newly streamed actors/cells.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contextswitch&lt;/code&gt;: OS-level thread scheduling to spot core migration, thread preemption, or streaming worker starvation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-statnamedevents&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Converts cycle counters and stat scopes into named event markers on the Unreal Insights timeline, ensuring you can clearly correlate custom streaming scopes and subsystem events alongside disk and task activity.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context Switch Administrator Requirement&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;The
channel lets you see when a thread is not getting CPU cycles. To capture context switches on Windows you must run the UE application as administrator. Otherwise, leave the &lt;code&gt;contextswitch&lt;/code&gt; channel disabled to prevent log spam.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>My List of Useful Console Commands</title><link>https://example.com/blog/ue-console-cmds/</link><pubDate>Mon, 25 May 2026 00:00:00 +0000</pubDate><guid>https://example.com/blog/ue-console-cmds/</guid><description>&lt;p&gt;A reference sheet of Unreal Engine console commands I frequently use for debugging, profiling, rendering, and runtime inspection, organized by category.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="misc--execution"&gt;Misc / Execution&lt;/h2&gt;
&lt;p&gt;Commands for general utility, time manipulation, and calling functions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Slomo &amp;lt;multiplier&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Changes the game speed (e.g., &lt;code&gt;Slomo 0.5&lt;/code&gt; for slow motion, &lt;code&gt;Slomo 1&lt;/code&gt; for normal speed, &lt;code&gt;Slomo 2&lt;/code&gt; for fast forward).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;t.MaxFps &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Caps the maximum framerate (e.g., &lt;code&gt;t.MaxFps 60&lt;/code&gt; or &lt;code&gt;t.MaxFps 0&lt;/code&gt; to uncap).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dumpticks&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Dumps a list of all currently ticking actors and components to the log, which is extremely useful for identifying tick-heavy performance bottlenecks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tick.AllowBatchedTicks &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables native actor and component tick batching (introduced in UE 5.5). Groups tick execution to significantly reduce TaskGraph dispatch overhead and improve CPU cache coherency when dealing with high counts of ticking objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ToggleDebugCamera&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles the debug camera, allowing you to fly around freely and inspect actor bounds and world layouts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ce &amp;lt;ufunction name which has exec&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Calls an &lt;code&gt;exec&lt;/code&gt; function by name on the local Player Controller or cheat manager.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ke &amp;lt;instance name or *&amp;gt; &amp;lt;ufunction name&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Triggers a function on all or specific instances of an object/actor in the level (e.g., &lt;code&gt;ke * ActivateTrap&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;teleport&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Teleports the player character to whatever surface the camera is currently looking at.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BugIt&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Creates a screenshot and metadata file containing camera coordinates, rotation, and current level, useful for reporting bugs with exact placement context.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ButItGo&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;(Often written as &lt;code&gt;BugItGo&lt;/code&gt; / &lt;code&gt;BugIt Go&lt;/code&gt;) Teleports to the coordinates specified by a BugIt screenshot/log entry.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;log &amp;lt;category&amp;gt; &amp;lt;verbosity&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Dynamically sets log verbosity for a specific category (e.g., &lt;code&gt;log LogTemp Verbose&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="stats--profiling"&gt;Stats &amp;amp; Profiling&lt;/h2&gt;
&lt;p&gt;Use these commands to get real-time telemetry on system performance.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;stat none&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Clears all active stat displays from the screen.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat unit&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Shows the time spent on the main Game thread, Render thread, GPU, and RHI thread, along with overall frame time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat UnitMax&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays the maximum (peak) values for frame metrics (like Game, Draw, GPU, RHI) over a recent window of frames, helping debug spikes and performance hitches.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat detailed&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays a detailed combination of performance metrics, including FPS, unit times, and peak frame time stats.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat unitGraph&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles a scrolling graphical representation of the &lt;code&gt;stat unit&lt;/code&gt; times.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat game&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays general game thread statistics, including tick times, blueprint times, and gameplay system overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat Engine&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;General engine statistics. Useful for triangle count of static and skeletal meshes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat gpu&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays a detailed breakdown of GPU render time across different rendering passes (shadows, base pass, lighting, post-processing).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat RHI&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays low-level rendering statistics, such as memory usage, render targets, textures, and GPU (pair with &lt;code&gt;rhi.ResourceMemory&lt;/code&gt; or &lt;code&gt;rhi.DumpMemory&lt;/code&gt; for dumped allocation breakdowns).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat SceneRendering&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays detailed rendering statistics, including draw calls, decals, lights, ray tracing, and CPU rendering costs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat DrawCount&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Detailed draw call data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat RenderThreadCommands&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays real-time statistics and counter metrics for commands enqueued and executed on the Render Thread (such as commands dispatched via &lt;code&gt;ENQUEUE_RENDER_COMMAND&lt;/code&gt;). Essential for diagnosing render thread command queue saturation and high command submission overhead from the game thread.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat initviews&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays information about visibility culling performance (how many primitives were processed, occluded, or visible).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat Foliage&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays the number of instanced static meshes and their triangle count (not just foliage).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat Landscape&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays performance metrics, draw calls, render stats, and component patch count for landscape and terrain.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat Niagara&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Detailed view of Niagara systems costs. (We&amp;rsquo;ll cover this in a future post)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat NiagaraSystemCounts&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Shows the number of Niagara particle systems active, ticking, and rendering in the scene.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat memory&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays current memory usage breakdowns across different allocation categories.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat navigation&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Shows navigation mesh statistics, including build times and memory footprint.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat net&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays real-time multiplayer network statistics including ping, incoming/outgoing bandwidth, packet counts, and loss rate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat Slate&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays real-time performance telemetry for the Slate UI framework, including widget tick, layout, and paint evaluation times.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat streaming&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays real-time texture and asset streaming telemetry, including memory pool usage, pool budget, wanted vs. resident mips, and pending streaming requests. (Also see &lt;code&gt;stat StreamingDetails&lt;/code&gt; for a deeper breakdown).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="show-commands"&gt;Show Commands&lt;/h2&gt;
&lt;p&gt;Toggle rendering flags to visualize colliders and debugging layouts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;show DebugAnimation&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Visualizes animation debug data, skeletal structures, and bone transforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;show Collision&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles the visibility of collision geometry (colliders, triggers, simple physics shapes) in the viewport.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;show Splines&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles the visibility of spline components and curves in the viewport.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;showflags.bounds &amp;lt;0 or 1&amp;gt;&lt;/code&gt; (or &lt;code&gt;show Bounds&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;Toggles the visibility of actor/primitive bounding boxes in the viewport, essential for diagnosing frustum culling and inflated bounds issues.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;show Fog&lt;/code&gt; (or &lt;code&gt;showflags.fog &amp;lt;0 or 1&amp;gt;&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;Toggles the visibility and rendering of fog (including Exponential Height Fog and atmospheric fog) in the viewport, useful for isolating lighting and inspecting geometry without fog obstruction.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="slate--ui"&gt;Slate &amp;amp; UI&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Slate.EnableGlobalInvalidation &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables Slate&amp;rsquo;s global invalidation system, caching unchanged UI widgets to significantly reduce CPU thread overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Slate.AllowToolTips &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables Slate tooltips globally across the editor and UI elements. Commonly set to &lt;code&gt;0&lt;/code&gt; (or added to &lt;code&gt;ConsoleVariables.ini&lt;/code&gt; as &lt;code&gt;Slate.AllowToolTips=0&lt;/code&gt;) to prevent intrusive tooltips and hover hitches during debugging and profiling.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slate.EnableTooltips &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables Slate tooltips globally across the editor and UI elements (used interchangeably with or superseding &lt;code&gt;Slate.AllowToolTips&lt;/code&gt; in modern engine versions).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SlateDebugger.Invalidate.Start&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Highlights widgets when they invalidate. Good for a gut check, though often too loud to be useful. (Can be stopped with &lt;code&gt;SlateDebugger.Invalidate.Stop&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SlateDebugger.bCaptureRootInvalidationCallstacks &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Pushes invalidation callstack to Slate Insights trace. Mouse over widget in Frame View to inspect.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SlateDebugger.Break&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Breaks on widget events:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OnWidgetBeginPaint&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OnWidgetEndPaint&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OnWidgetInvalidation&lt;/code&gt; (Widget ID, Reason).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="ensures--asserts"&gt;Ensures &amp;amp; Asserts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;core.ResetEnsureState&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Resets the ensure state counter, allowing the engine to fire ensures that have already been triggered and suppressed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;core.Ensure&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Provides configuration options for how ensures behave (e.g., whether they should break into the debugger, write to the log, or crash).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="garbage-collection"&gt;Garbage Collection&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;obj gc&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Forces an immediate garbage collection pass.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gc.CollectGarbageEveryFrame &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Forces the engine to collect garbage on every single frame. Useful for detecting memory leaks and validating reference integrity under stress, but will severely impact framerate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="memory-inspection"&gt;Memory Inspection&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;list obj class=&amp;lt;name&amp;gt; -resourcesizesort -countsort&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Lists all instantiated objects of a specific class. Sorting flags prioritize resource size (&lt;code&gt;-resourcesizesort&lt;/code&gt;) or count (&lt;code&gt;-countsort&lt;/code&gt;), making it highly effective for finding memory hogs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;obj refs shortest name=&amp;lt;object_path&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Finds and displays the shortest path of references from a root object to the specified object. Extremely useful for identifying memory leaks and figuring out why a specific asset or object remains loaded in memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;obj.tracesnapshot&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Captures a snapshot of all active UObjects into the trace. Useful for comparing UObject memory states at different points in time during a profiling session (requires the &lt;code&gt;object&lt;/code&gt; trace channel to be enabled).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rhi.ResourceMemory&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Dumps a comprehensive breakdown of low-level GPU/RHI resource allocations (vertex buffers, index buffers, textures, render targets, and structured buffers) to the log, making it indispensable for tracking down VRAM usage at the hardware abstraction level.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rhi.DumpMemory&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Dumps overall RHI memory tracking and GPU memory statistics to the log, providing a high-level summary of allocated video memory, pool sizes, and driver-level overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="rendering--quality"&gt;Rendering &amp;amp; Quality&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.DistanceFieldShadowing &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles Ray Traced Distance Field Shadows.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.MeshDrawCommands.DynamicInstancing &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables dynamic auto-instancing for mesh draw commands on the GPU Scene pipeline (default is &lt;code&gt;1&lt;/code&gt;). Turning this off (&lt;code&gt;0&lt;/code&gt;) disables runtime instancing, which is useful for checking draw call batching efficiency or debugging stale cached mesh draw commands and visual artifacts on duplicate meshes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.RayTracing.NormalBias &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Offsets the origin of secondary ray-traced rays outward along the surface normal (default is &lt;code&gt;0.1&lt;/code&gt;). Increasing this (e.g., &lt;code&gt;r.RayTracing.NormalBias 5.0&lt;/code&gt;) prevents ray self-intersection, shadow acne, and dark noisy splotches on complex geometry or Nanite foliage, though setting it too high can cause light leaking or detached shadows (&amp;ldquo;peter-panning&amp;rdquo;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.DetailMode &amp;lt;0, 1, 2&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls the detail mode of components (0 = Low, 1 = Medium, 2 = High). Useful for profiling how different detail tiers impact visual performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.LightMaxDrawDistanceScale &amp;lt;multiplier&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Applies a global multiplier to the Max Draw Distance and fade range of all lights (e.g., &lt;code&gt;r.LightMaxDrawDistanceScale 1&lt;/code&gt; for default, &lt;code&gt;&amp;lt; 1&lt;/code&gt; to cull distant lights sooner for performance, &lt;code&gt;&amp;gt; 1&lt;/code&gt; to extend draw distances, or &lt;code&gt;0&lt;/code&gt; to disable distance culling).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.ScreenPercentage &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the render resolution percentage of the viewport (e.g., &lt;code&gt;r.ScreenPercentage 50&lt;/code&gt; for half-res upscaled, &lt;code&gt;r.ScreenPercentage 100&lt;/code&gt; for native).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.VSync &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles VSync on or off.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="texture-streaming"&gt;Texture Streaming&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.Streaming.DropMips &amp;lt;0, 1, 2&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls whether the texture streamer drops mips to save texture memory (0 = don&amp;rsquo;t drop, 1 = drop mips under memory pressure, 2 = force drop mips even if memory is not low). Can also be supplied at launch via &lt;code&gt;-DPCvars=&amp;quot;r.Streaming.DropMips=1&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.TextureStreaming &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Globally enables or disables the texture streaming system.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Streaming.PoolSize &amp;lt;value in MB&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Overrides the texture streaming pool size in megabytes (e.g., &lt;code&gt;r.Streaming.PoolSize 3000&lt;/code&gt;, or &lt;code&gt;0&lt;/code&gt; for unlimited).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="nanite"&gt;Nanite&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.nanite.maxpixelsperedge &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls the level of detail (LOD) metric for Nanite meshes. Higher numbers reduce detail by allowing larger polygons per edge, which improves rendering performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.nanite.showstats &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Displays real-time on-screen statistics and telemetry for Nanite, including rendered triangle counts, cluster counts, instances, and streaming/culling performance metrics. &lt;em&gt;(Note: Requires &lt;code&gt;r.ShaderPrint.Enable 1&lt;/code&gt; to render the debug text on screen.)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.ShaderPrint.Enable &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables the GPU Shader Print debugging system, allowing compute and graphics shaders to draw debug text directly in the viewport (required for commands like &lt;code&gt;r.nanite.showstats 1&lt;/code&gt; to display).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Nanite.Streaming.StreamingPoolSize &amp;lt;value in MB&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the dedicated memory pool size in megabytes for Nanite geometry streaming (e.g., &lt;code&gt;r.Nanite.Streaming.StreamingPoolSize 1024&lt;/code&gt;). Increasing this helps prevent geometry popping, thrashing, and streaming stalls in complex scenes with dense Nanite assets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;showflag.nanitemeshes &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles whether Nanite geometry is rendered as Nanite or falls back to traditional fallback meshes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Nanite.Visualize.PixelProgrammableVisMode&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Visualizes pixel-programmable operations (like masked materials and world position offset) on Nanite meshes, which can cause significant performance overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="materials"&gt;Materials&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.showmaterialdrawevents &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles the display of material draw events in profiling tools, making it easier to see which specific materials are costing the most draw calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="megalights"&gt;Megalights&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.MegaLights.DownsampleMode&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Configures downsampling modes for Megalights to balance lighting quality against GPU rendering cost.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="lumen"&gt;Lumen&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.DiffuseIndirect.Allow &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles diffuse indirect lighting evaluation for Lumen. Disabling this (&lt;code&gt;0&lt;/code&gt;) stops indirect bounces and emissive materials from projecting light onto nearby surfaces, which is often one of the heaviest GPU costs in Lumen scenes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Master toggle for screen probe gather, which computes diffuse global illumination by integrating incoming radiance across screen-space probes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.StochasticInterpolation &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables stochastic sampling when interpolating between screen probes (e.g., &lt;code&gt;r.Lumen.ScreenProbeGather.StochasticInterpolation 1&lt;/code&gt;), improving GI detail and sharpness in probe reconstruction with reduced overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.SpatialFilterNumPasses &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls the number of spatial filter passes applied to screen probe gather results (e.g., &lt;code&gt;r.Lumen.ScreenProbeGather.SpatialFilterNumPasses 2&lt;/code&gt;), balancing high-frequency noise suppression against over-blurring.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.DownsampleFactor &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the downsample factor for screen probe gather (e.g., &lt;code&gt;8&lt;/code&gt; or &lt;code&gt;16&lt;/code&gt;). Higher values reduce probe density and drastically cut GPU frame times at the expense of lower GI resolution.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.ScreenTraces &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables screen-space ray tracing before falling back to mesh distance fields or surface cache cards. Disabling skips tracing against the screen depth buffer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.ScreenTraces.HZBTraversal.MaxIterations &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the maximum number of Hierarchical Z-Buffer (HZB) traversal iterations during screen-trace ray marching. Lowering this caps ray step cost in complex scenes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.Temporal &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles temporal accumulation and filtering for screen probe gathering.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.Temporal.MaxFramesAccumulated &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Limits the maximum number of history frames used for temporal accumulation in screen probe gathering. Lower values reduce ghosting artifacts behind moving objects, while higher values provide cleaner noise-free convergence.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.Temporal.DistanceThreshold &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the relative distance/depth threshold for discarding historical probe data during temporal filtering (e.g., &lt;code&gt;r.Lumen.ScreenProbeGather.Temporal.DistanceThreshold 1.65&lt;/code&gt;). Tuning this helps eliminate ghosting and dark trailing artifacts behind moving geometry without introducing excessive GI noise or foliage flickering.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.MaxRayIntensity &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Clamps the maximum radiance/intensity of individual rays gathered during screen probe integration (e.g., &lt;code&gt;r.Lumen.ScreenProbeGather.MaxRayIntensity 10&lt;/code&gt;). Tames bright &amp;ldquo;firefly&amp;rdquo; noise, specular hot spots, and harsh light bleed from intensely bright emissive materials.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.Reflections.DownsampleFactor &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the internal resolution downsample factor for Lumen reflections (e.g., &lt;code&gt;1&lt;/code&gt; for full resolution, &lt;code&gt;2&lt;/code&gt; or &lt;code&gt;1.85&lt;/code&gt; for reduced internal resolution). Higher values significantly cut GPU rendering cost on reflective surfaces with minimal sharpness loss after temporal upscaling.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.Reflections.HierarchicalScreenTraces.MaxIterations &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the maximum ray-marching traversal iterations for Hierarchical Screen Traces (HZB) in Lumen reflections (e.g., &lt;code&gt;r.Lumen.Reflections.HierarchicalScreenTraces.MaxIterations 4&lt;/code&gt;). Lowering this caps the trace cost of screen-space reflection passes in complex scenes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.RadianceCache.GridResolution &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the grid probe resolution for the world-space Radiance Cache used to accelerate probe traces, balancing spatial fidelity against cache memory and update overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ScreenProbeGather.VisualizeTraces &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Visualizes screen probe gather ray traces directly in the viewport for debugging trace distribution and surface hit coverage.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.DiffuseIndirect.CardTraceEndDistanceFromCamera &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Maximum camera distance in unreal units where Lumen traces against surface cache cards. Geometry beyond this distance skips card tracing, saving substantial GPU time in open worlds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.DiffuseIndirect.CullGridPixelSize &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the 2D tile/pixel size for the light and surface card culling grid used during diffuse indirect calculations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.DiffuseIndirect.MinTraceDistance &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Specifies the minimum world-space distance before rays evaluate against surface cards or distance fields, preventing near-field self-intersections and reducing trace cost.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.IrradianceFieldGather.NumProbesToTraceBudget &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the maximum per-frame budget for tracing irradiance field probes, preventing performance spikes when lighting updates across large scene areas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Lumen.ProbeHierarchy.SamplePerPixel &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls the probe hierarchy sampling density per pixel for lighting evaluation and probe interpolation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="shadows--virtual-shadow-maps-vsm"&gt;Shadows &amp;amp; Virtual Shadow Maps (VSM)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.Virtual.Enable &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables Virtual Shadow Maps (VSM). Disabling (&lt;code&gt;0&lt;/code&gt;) falls back to traditional Cascaded Shadow Maps (CSM).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.RadiusThreshold &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls the screen-size threshold below which objects stop casting dynamic shadows (default is &lt;code&gt;0.03&lt;/code&gt;). Increasing this (e.g., &lt;code&gt;r.Shadow.RadiusThreshold 0.06&lt;/code&gt;) aggressively culls shadows from small or distant objects to improve framerates, while lowering it prevents shadow popping in open-world views.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.Virtual.ResolutionLodBiasDirectional &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Biases the resolution mip/LOD level specifically for directional light Virtual Shadow Maps (e.g., &lt;code&gt;0&lt;/code&gt; for default, positive values like &lt;code&gt;1&lt;/code&gt; reduce page resolution to boost performance and cut VRAM footprint, while negative values like &lt;code&gt;-1.1&lt;/code&gt; increase shadow detail over distance).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.Virtual.Clipmap.LastLevel &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the coarsest (outermost) shell level for directional light Virtual Shadow Map clipmaps (default is &lt;code&gt;22&lt;/code&gt;, covering ~40 km). Lowering this (e.g., &lt;code&gt;15&lt;/code&gt; or &lt;code&gt;20&lt;/code&gt;) drops distant cascade shells to save substantial GPU time and VRAM in contained maps, while raising it extends shadow reach for planetary or flight-scale worlds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.Virtual.Clipmap.UseConservativeCulling &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles conservative culling for directional light VSM clipmaps. Enabling this (&lt;code&gt;1&lt;/code&gt;) removes the frustum-clipped culling volume for non-Nanite meshes, submitting more geometry to help isolate and debug shadow clipping or missing shadow bugs (default is &lt;code&gt;0&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange &amp;lt;value&amp;gt;&lt;/code&gt; (or &lt;code&gt;r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRadius&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;Sets the maximum world-space distance from the camera where material-driven vertex deformation (such as World Position Offset / wind on foliage) can invalidate cached VSM pages (e.g., &lt;code&gt;3600&lt;/code&gt;). Prevents distant animated foliage from continuously dirtying the shadow cache and causing heavy GPU spikes. &lt;em&gt;(Note: Often referenced as &lt;code&gt;...InvalidationRadius&lt;/code&gt; or &lt;code&gt;...InvalidationRange&lt;/code&gt; across engine revisions).&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.Virtual.NonNanite.IncludeInCoarsePages &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls whether non-Nanite geometry (standard static meshes, skeletal meshes, non-Nanite foliage) is rendered into coarse, lower-resolution hierarchical MIP pages of Virtual Shadow Maps. Disabling this (&lt;code&gt;0&lt;/code&gt;) provides a major performance boost in open-world scenes with dense non-Nanite assets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.Virtual.ForceOnlyVirtualShadowMaps &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Forces lights using Virtual Shadow Maps to strictly use the VSM pipeline without creating conventional fallback shadow maps (e.g., CSM), eliminating redundant shadow passes and reducing memory overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.Virtual.UseFarShadowCulling &amp;lt;value or 0/1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls far-shadow culling for Virtual Shadow Maps. Enabling it culls distant shadows past a set range to preserve performance, while disabling or lowering the threshold (&lt;code&gt;0&lt;/code&gt; or &lt;code&gt;0.1&lt;/code&gt;) forces distant objects to keep casting virtual shadows, eliminating abrupt shadow popping at long distances.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sg.ShadowQuality &amp;lt;0, 1, 2, 3, 4&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Scalability group setting for shadows (0 = Low, 1 = Medium, 2 = High, 3 = Epic, 4 = Cinematic).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.ShadowQuality &amp;lt;0, 1, 2, 3, 4, 5&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Directly overrides shadow quality level, controlling filter kernel quality, sample counts, and shadow map resolutions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Shadow.MaxResolution &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the maximum texture resolution for conventional shadow depth maps (e.g., &lt;code&gt;r.Shadow.MaxResolution 2048&lt;/code&gt; or &lt;code&gt;1024&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="foliage"&gt;Foliage&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sg.FoliageQuality &amp;lt;0, 1, 2, 3, 4&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets foliage quality group settings (Low, Medium, High, Epic, Cinematic).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Foliage.DensityScale &amp;lt;multiplier&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Scales the density of rendered foliage dynamically (e.g., &lt;code&gt;Foliage.DensityScale 0.5&lt;/code&gt; reduces rendering to 50% density).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="decals"&gt;Decals&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.Decal.FadeScreenSizeMult &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Multiplier for decal fading based on screen size, controlling how early decals fade out as they get further from the camera.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="animation--skeletal-meshes"&gt;Animation &amp;amp; Skeletal Meshes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;a.ParallelAnimEvaluation &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles parallel animation evaluation on worker threads. Disabling this (&lt;code&gt;0&lt;/code&gt;) forces animation evaluation to run synchronously on the game thread, which is useful for isolating thread-safety bugs and race conditions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a.StripFramesOnCompression &amp;lt;0 or 1&amp;gt;&lt;/code&gt; &amp;amp; &lt;code&gt;a.StripOddFramesWhenFrameStripping &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Strips alternate frames during animation compression. Can result in an approximate memory saving of around 20–30% on animation data, which is particularly useful for lower-end and memory-constrained platforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.FreeSkeletalMeshBuffers &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls whether mesh geometry buffers are retained CPU-side after upload. If your project is not using CPU-dependent features like runtime Mesh Merging, enable this (&lt;code&gt;1&lt;/code&gt;) to save memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Controlrig.EnableAnimNodePerformanceOptimizations &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables Control Rig anim node performance optimizations, allowing Control Rigs to share the AnimGraph&amp;rsquo;s transform buffer, reducing memory footprint and improving performance (enabled by default in UE 5.6+).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a.AnimNode.FootPlacement.Debug &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables debug visualizations for the foot placement node, showing trace lines, target offsets, and IK status.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a.DebugAnimNotify &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables debug messages for AnimNotifies as they trigger on actors.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a.VisualizeLODs &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables debug visualization for skeletal mesh Animation LODs in the viewport, displaying which LOD level animated characters are using.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="metahuman--crowds"&gt;MetaHuman &amp;amp; Crowds&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mh.Crowds.DebugISKMs &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles debug visualization and rendering status for Instanced Skeletal Mesh Managers (ISKMs) used in MetaHuman crowd systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="physics"&gt;Physics&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;p.Chaos.Collision.MarginMax &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sets the maximum collision margin distance for shapes in Chaos physics collision detection. Useful for tuning collision precision or diagnosing floating and clipping artifacts caused by overly large shape margins.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p.Chaos.DebugDraw.Enabled &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Master switch to enable or disable Chaos physics debug drawing in the viewport.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p.Chaos.ImmPhys.DebugDrawCollisions &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables debug visualization of collision contacts, manifolds, and contact points for Immediate Physics simulations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p.Chaos.ImmPhys.DebugDrawShapes &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables debug visualization of simulation and collision shapes for Immediate Physics (e.g., AnimNode_RigidBody).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p.RigidBodyNodeWithControl.DebugDraw &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables debug draw visualizations for RigidBody with Control animation nodes in the viewport.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p.RigidBodyNodeWithControl.EnableSimulation &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles simulation for RigidBody with Control animation nodes. Setting this to &lt;code&gt;0&lt;/code&gt; disables physics simulation, which is useful for debugging physics-driven skeletal mesh issues or isolating performance bottlenecks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p.VisualizeMovement &amp;lt;0 or 1&amp;gt;&lt;/code&gt; (or &lt;code&gt;p.VisualizeMovement 1&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;Visualizes velocity and acceleration vectors for character movement components (e.g., &lt;code&gt;p.VisualizeMovement 1&lt;/code&gt; to enable, &lt;code&gt;0&lt;/code&gt; to disable).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="networking"&gt;Networking&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;p.NetShowCorrections &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles visual debugging for network position corrections, displaying red and green collision shapes to represent server corrections and client state.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p.NetEnableMoveCombining &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables combining client moves before sending them to the server. Disabling this (&lt;code&gt;0&lt;/code&gt;) is useful for testing raw client input replication and debugging tick-by-tick prediction issues.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NetEmulation.PktLag &amp;lt;value in ms&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Simulates outbound network latency/lag in milliseconds (e.g., &lt;code&gt;NetEmulation.PktLag 150&lt;/code&gt; for 150ms).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NetEmulation.PktLagVariance &amp;lt;value in ms&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Adds random variance to the packet lag (e.g., &lt;code&gt;NetEmulation.PktLagVariance 20&lt;/code&gt; with &lt;code&gt;PktLag 150&lt;/code&gt; randomizes lag between 130ms and 170ms).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NetEmulation.PktLagMin &amp;lt;value&amp;gt;&lt;/code&gt; &amp;amp; &lt;code&gt;NetEmulation.PktLagMax &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Specifies a minimum and maximum range for simulated latency in milliseconds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NetEmulation.PktLoss &amp;lt;percentage&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Simulates outbound packet loss percentage (e.g., &lt;code&gt;NetEmulation.PktLoss 10&lt;/code&gt; for 10% packet loss).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NetEmulation.PktOrder &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Simulates network packets being received out of order.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="water-system"&gt;Water System&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.Water.SingleLayer.DepthPrepass &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables or disables depth prepass for single-layer water shaders.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Water.SingleLayer.DistanceFieldShadow &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles distance field shadowing for single-layer water.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Water.SingleLayer.ShadersSupportDistanceFieldShadows &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Configures whether water shaders compile and support distance field shadows.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Water.SingleLayer.Reflection &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles reflections on single-layer water.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.Water.SingleLayer.DownSampleFactor &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Configures the resolution downsample factor for water reflection/translucency render targets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="volumetric-fog"&gt;Volumetric Fog&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r.VolumetricFog.GridPixelSize &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls the screen grid tile size in pixels for volumetric fog voxel calculation (default is typically &lt;code&gt;8&lt;/code&gt; or &lt;code&gt;16&lt;/code&gt;). Larger values (e.g., &lt;code&gt;16&lt;/code&gt;) drastically reduce compute shader cost while still maintaining solid visual fidelity when temporally accumulated.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.VolumetricFog.TemporalReprojection &amp;lt;0 or 1&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Toggles temporal reprojection for volumetric fog. Enabling this accumulates samples across frames to produce smooth, high-quality volumetric lighting at lower base grid resolutions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.VolumetricFog.UpsampleJitterMultiplier &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Controls jittering during volumetric fog upsampling to reduce banding artifacts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r.VolumetricFog.HistoryMissSupersampleCount &amp;lt;value&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Configures the number of supersamples taken when history reprojection misses, sharpening the fog buffer at the cost of performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="launch--command-line-arguments-ez-args"&gt;Launch / Command Line Arguments (EZ Args)&lt;/h2&gt;
&lt;p&gt;Pass these parameters directly to the executable or in the Editor&amp;rsquo;s executable arguments for quick setup:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-Log&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Opens a separate output log window in standard Windows CMD format when running standalone games.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-NewConsole&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Launches standalone games using a separate console window for cleaner stdout tracking.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-StompMalloc&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Enables the stomp memory allocator, which places pages in a way that immediately crashes the application when a memory overrun or read-after-free occurs (crucial for hunting memory corruption bugs).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Blueprint Compiler Extensions</title><link>https://example.com/blog/ue5-blueprint-compiler-extensions/</link><pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate><guid>https://example.com/blog/ue5-blueprint-compiler-extensions/</guid><description>&lt;p&gt;Standard &lt;code&gt;Delay&lt;/code&gt; nodes in Unreal Engine don&amp;rsquo;t respect the Gameplay Ability lifecycle. In the &lt;strong&gt;Gameplay Ability System (GAS)&lt;/strong&gt;, abilities should use the &lt;strong&gt;Wait Delay&lt;/strong&gt; task node (&lt;code&gt;UAbilityTask_WaitDelay&lt;/code&gt;) instead of standard latent delays.&lt;/p&gt;
&lt;p&gt;To enforce this automatically, we can create a &lt;strong&gt;Blueprint Compiler Extension (&lt;code&gt;UBlueprintCompilerExtension&lt;/code&gt;)&lt;/strong&gt;. By hooking directly into the Blueprint compilation process, we can check node graphs during compilation and fail the build if a forbidden node is used.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="how-blueprint-compiler-extensions-work"&gt;How Blueprint Compiler Extensions Work&lt;/h2&gt;
&lt;p&gt;Unreal Engine provides the &lt;code&gt;UBlueprintCompilerExtension&lt;/code&gt; class (in the &lt;code&gt;BlueprintCompiler&lt;/code&gt; module) to run custom validation rules during Blueprint compilation.&lt;/p&gt;
&lt;p&gt;When a developer compiles a Blueprint:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The compiler instantiates all loaded subclasses of &lt;code&gt;UBlueprintCompilerExtension&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It calls &lt;code&gt;ProcessBlueprintCompiled()&lt;/code&gt; on each extension.&lt;/li&gt;
&lt;li&gt;The extension inspects the Blueprint&amp;rsquo;s graphs, nodes, and variables.&lt;/li&gt;
&lt;li&gt;If an invalid pattern is found, errors are pushed directly to the &lt;strong&gt;Compiler Results&lt;/strong&gt; log, aborting compilation.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="setting-up-your-editor-module"&gt;Setting Up Your Editor Module&lt;/h2&gt;
&lt;p&gt;Because compiler extensions rely on editor-only modules like &lt;code&gt;BlueprintCompiler&lt;/code&gt;, &lt;code&gt;KismetCompiler&lt;/code&gt;, and &lt;code&gt;UnrealEd&lt;/code&gt;, this code must live in an &lt;strong&gt;Editor Module&lt;/strong&gt; (e.g., &lt;code&gt;MyProjectEditor&lt;/code&gt;). Placing editor dependencies inside a primary game module will break standalone builds.&lt;/p&gt;
&lt;h3 id="step-1-update-the-uproject-file"&gt;Step 1: Update the &lt;code&gt;.uproject&lt;/code&gt; File&lt;/h3&gt;
&lt;p&gt;Add the editor module configuration to your project&amp;rsquo;s &lt;code&gt;.uproject&lt;/code&gt; file under &lt;code&gt;&amp;quot;Modules&amp;quot;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block-container"&gt;
&lt;div class="code-block-header"&gt;&lt;span&gt;MyProject.uproject&lt;/span&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyProjectEditor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;Type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Editor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;LoadingPhase&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PostEngineInit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;AdditionalDependencies&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;MyProject&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="step-2-update-target-files"&gt;Step 2: Update Target Files&lt;/h3&gt;
&lt;p&gt;In your project&amp;rsquo;s &lt;code&gt;MyProjectEditor.Target.cs&lt;/code&gt;, add the editor module to &lt;code&gt;ExtraModuleNames&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block-container"&gt;
&lt;div class="code-block-header"&gt;&lt;span&gt;Source/MyProjectEditor.Target.cs&lt;/span&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ExtraModuleNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;MyProject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;MyProjectEditor&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="step-3-create-the-editor-module-buildcs"&gt;Step 3: Create the Editor Module Build.cs&lt;/h3&gt;
&lt;p&gt;Create &lt;code&gt;MyProjectEditor.Build.cs&lt;/code&gt; in your editor module directory:&lt;/p&gt;
&lt;div class="code-block-container"&gt;
&lt;div class="code-block-header"&gt;&lt;span&gt;Source/MyProjectEditor/MyProjectEditor.Build.cs&lt;/span&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;UnrealBuildTool&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyProjectEditor&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ModuleRules&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;MyProjectEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ReadOnlyTargetRules&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PCHUsage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PCHUsageMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseExplicitOrSharedPCHs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PublicDependencyModuleNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Core&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;CoreUObject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Engine&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;MyProject&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;PrivateDependencyModuleNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;UnrealEd&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;BlueprintGraph&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;KismetCompiler&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Kismet&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;GameplayAbilities&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="step-4-create-module-header-and-source-files"&gt;Step 4: Create Module Header and Source Files&lt;/h3&gt;
&lt;p&gt;Initialize the editor module with main header and source files:&lt;/p&gt;
&lt;div class="code-block-container"&gt;
&lt;div class="code-block-header"&gt;&lt;span&gt;Source/MyProjectEditor/MyProjectEditor.h&lt;/span&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#pragma once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;CoreMinimal.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;Modules/ModuleManager.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FMyProjectEditorModule&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IModuleInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;StartupModule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ShutdownModule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block-container"&gt;
&lt;div class="code-block-header"&gt;&lt;span&gt;Source/MyProjectEditor/MyProjectEditor.cpp&lt;/span&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;MyProjectEditor.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;Modules/ModuleManager.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;BlueprintCompilationManager.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;BPCE_Ability_Delay.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;UBPCE_Ability_Delay&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;AbilityDelayCheckExtension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;FMyProjectEditorModule&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StartupModule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AbilityDelayCheckExtension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NewObject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UBPCE_Ability_Delay&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AbilityDelayCheckExtension&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;AddToRoot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FBlueprintCompilationManager&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RegisterCompilerExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UBlueprint&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StaticClass&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;AbilityDelayCheckExtension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;FMyProjectEditorModule&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ShutdownModule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AbilityDelayCheckExtension&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AbilityDelayCheckExtension&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;RemoveFromRoot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AbilityDelayCheckExtension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;IMPLEMENT_MODULE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FMyProjectEditorModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MyProjectEditor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="implementing-the-compiler-extension"&gt;Implementing the Compiler Extension&lt;/h2&gt;
&lt;p&gt;Implement the validator class inside the editor module:&lt;/p&gt;
&lt;h3 id="c-header-file"&gt;C++ Header File&lt;/h3&gt;
&lt;div class="code-block-container"&gt;
&lt;div class="code-block-header"&gt;&lt;span&gt;Source/MyProjectEditor/BPCE_Ability_Delay.h&lt;/span&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#pragma once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;CoreMinimal.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;BlueprintCompilerExtension.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;BPCE_Ability_Delay.generated.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;UCLASS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MYPROJECTEDITOR_API&lt;/span&gt; &lt;span class="nl"&gt;UBPCE_Ability_Delay&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;UBlueprintCompilerExtension&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;GENERATED_BODY&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;ProcessBlueprintCompiled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FKismetCompilerContext&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;CompilationContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FBlueprintCompiledData&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="c-source-file"&gt;C++ Source File&lt;/h3&gt;
&lt;div class="code-block-container"&gt;
&lt;div class="code-block-header"&gt;&lt;span&gt;Source/MyProjectEditor/BPCE_Ability_Delay.cpp&lt;/span&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;BPCE_Ability_Delay.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;K2Node_CallFunction.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;KismetCompiler.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;Abilities/GameplayAbility.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;EdGraph/EdGraph.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;#34;Kismet/KismetSystemLibrary.h&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;UBPCE_Ability_Delay&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ProcessBlueprintCompiled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FKismetCompilerContext&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;CompilationContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FBlueprintCompiledData&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;UBlueprint&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CompilationContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;Blueprint&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;ParentClass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Check if the blueprint is a Gameplay Ability
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;ParentClass&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;IsChildOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UGameplayAbility&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StaticClass&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;TArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UEdGraph&lt;/span&gt;&lt;span class="o"&gt;*&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AllGraphs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;GetAllGraphs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AllGraphs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Change the Blacklisted Function here
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;UClass&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;LibraryClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UKismetSystemLibrary&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StaticClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;UFunction&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;DelayFunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LibraryClass&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;FindFunctionByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GET_FUNCTION_NAME_CHECKED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UKismetSystemLibrary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UEdGraph&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nl"&gt;Graph&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AllGraphs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;Graph&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UEdGraphNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nl"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Graph&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Nodes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;UK2Node_CallFunction&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;FuncNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UK2Node_CallFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;UFunction&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FuncNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;GetTargetFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;DelayFunc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UE_LOG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LogTemp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Critical: Blueprint &amp;#39;%s&amp;#39; contains a forbidden Delay node in graph &amp;#39;%s&amp;#39;!&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;GetName&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Graph&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;GetName&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FText&lt;/span&gt; &lt;span class="n"&gt;ErrorMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FText&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Delay nodes are forbidden in Gameplay Abilities. Use &amp;#39;Wait Delay&amp;#39; node or other latent ability tasks instead (Error in @@)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CompilationContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MessageLog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ErrorMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="how-it-works"&gt;How It Works&lt;/h2&gt;
&lt;h3 id="graph-and-node-traversal"&gt;Graph and Node Traversal&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Blueprint-&amp;gt;GetAllGraphs(AllGraphs)&lt;/code&gt; collects all graphs within the Blueprint (event graph, custom functions, macro graphs, interfaces). Inside each graph, we iterate through &lt;code&gt;Graph-&amp;gt;Nodes&lt;/code&gt; and cast to &lt;code&gt;UK2Node_CallFunction&lt;/code&gt; to inspect target function calls.&lt;/p&gt;
&lt;h3 id="function-signature-matching"&gt;Function Signature Matching&lt;/h3&gt;
&lt;p&gt;Instead of string comparisons on function names every compile pass, we cache the target &lt;code&gt;UFunction&lt;/code&gt; pointer using &lt;code&gt;FindFunctionByName&lt;/code&gt; and match against the node&amp;rsquo;s target function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;UClass&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;LibraryClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UKismetSystemLibrary&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StaticClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;UFunction&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;DelayFunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LibraryClass&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;FindFunctionByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GET_FUNCTION_NAME_CHECKED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UKismetSystemLibrary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="formatting-compilation-errors-and-hyperlinks"&gt;Formatting Compilation Errors and Hyperlinks&lt;/h3&gt;
&lt;p&gt;Unreal Engine&amp;rsquo;s compiler log parser supports the &lt;code&gt;@@&lt;/code&gt; token. When included in the error message, the compiler results window replaces &lt;code&gt;@@&lt;/code&gt; with a clickable hyperlink pointing to the node passed as the second parameter:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;FText&lt;/span&gt; &lt;span class="n"&gt;ErrorMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FText&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;... Error in @@ ...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When pushed with &lt;code&gt;CompilationContext.MessageLog.Error(Message, Node)&lt;/code&gt;, double-clicking the compiler error jumps directly to the problematic node in the graph editor.&lt;/p&gt;
&lt;h2 id="validating-existing-gameplay-abilities"&gt;Validating Existing Gameplay Abilities&lt;/h2&gt;
&lt;p&gt;To run validation on all existing Gameplay Ability assets at once:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Filter for &lt;code&gt;GameplayAbility&lt;/code&gt; assets in the Content Browser.&lt;/li&gt;
&lt;li&gt;Select all matching assets, right-click, and click &lt;strong&gt;Validate Assets&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This executes compiler validation across every selected ability and outputs errors for any forbidden &lt;code&gt;Delay&lt;/code&gt; nodes directly to the log.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Once &lt;code&gt;UBlueprintCompilerExtension&lt;/code&gt; is registered, you can expand it to enforce additional node blacklists or architectural constraints across your Blueprints.&lt;/p&gt;</description></item></channel></rss>