Back to Blog
    Last Week in Unreal

    Last Week in Unreal: Three People, One Bot, and the Last Wall Comes Down (July 6 to 12, 2026)

    Venkat S10 min read
    Last Week in Unreal: Three People, One Bot, and the Last Wall Comes Down (July 6 to 12, 2026)

    Unreal Engine Weekly: The Last Wall Comes Down

    Week of July 6 – 12, 2026 | 64 commits on ue6-main, 0 on ue5-main | Branch: ue6-main

    Overview

    Epic is on its annual company-wide summer shutdown, two weeks off, and the commit graph shows it: 64 commits on ue6-main against a normal week’s ~880, following 75 the week before. One commit message says the quiet part out loud. The author of the Lore rename opens with “You madman! Why are you submitting this during summer break?” (6ba090ed).

    Do not read a trend into the volume. This is not a slowdown, not a branch cut, and not a release-cycle signal. It is a holiday, and the graph will snap back.

    ue5-main saw zero commits. Not a handful, not a trickle: zero. 5.x stabilization is fully paused for the shutdown, so if you are waiting on a 5.x backport, assume nothing moves until Epic returns.

    All 64 commits come from three people and a build bot. Henrik Karlsson has 41 of them. Matt Begoghina has 15. Wouter Burgers has 2. The buildmachine bot has 6. And in a week where almost nobody was working, Karlsson finished a campaign we have been tracking for four weeks: he drove the editor’s circular-dependency allowlist from 13 entries to zero, then shipped a live status page for the UBA build cache. If last week was “the walls keep falling,” this week the last one came down.


    TL;DR

    • The editor’s circular-dependency allowlist is now empty, down from 13 entries. UnrealEd, Kismet, BlueprintGraph, GraphEditor, KismetCompiler, and AnimGraph no longer form a link cycle, so they can be built and relinked independently. Editor iteration time drops, and forks and plugins that were getting Blueprint headers for free through UnrealEd’s shared PCH break (dae0d248, e03cbcbd, 10e8206a).
    • UBA’s cache service now serves a live status web page, and UbaCli cacheproxy tunnels a remote cache host’s dashboard to your machine. Build-cache observability landed in-engine, and it is the biggest new capability this week (5bb6fad7).
    • A four-line UBT fix repaired nondeterministic shared-PCH cache keys. If your shared build cache has had an unexplained mediocre hit rate, start here (a18c43ec).
    • Slate is being annotated for dynamic invalidation, widget batch by widget batch, including the entire property grid. Nothing changes behavior yet. It is the groundwork for turning invalidation caching on broadly (22432ab7, c5cfe7ab, and thirteen siblings).

    Highlights

    The editor’s circular-dependency allowlist went to zero

    What changed

    CircularlyReferencedDependentModules was the long-standing escape hatch that let UnrealEd, Kismet, BlueprintGraph, GraphEditor, KismetCompiler, and AnimGraph reach into each other. It started this week at 13 entries. It ends at zero.

    The AnimGraph cut removed all four ("AnimGraph", *) entries and took the allowlist from 13 to 9 (f78a9d69). That commit is Build.cs-only, because three prep commits had already severed or bridged every reference (2709d889, a3766671, 27cd49ad). Note that the prep relocated UAnimPreviewInstance into AnimGraphRuntime behind a class redirect (a3766671), so there is serialized-asset impact.

    Then UnrealEd stopped linking Kismet. Kismet moved to DynamicallyLoadedModuleNames, with the DLL kept resident by loading KismetCompiler at UnrealEd startup so the bridge implementations still bind at static-init (dc1f317a). UnrealEd’s link dependency on BlueprintGraph was cut next (2fce5938), followed by UnrealEd to GraphEditor (6474dcc8). The last three entries died in a single 50-file commit that inverted node and pin color lookups, plus roughly 57 context-menu command references, behind new BlueprintGraph-owned interfaces (dae0d248). KismetCompiler was then absorbed into BlueprintGraph, emptying the list (e03cbcbd), and its shim module was deleted in a 74-file cleanup that is mostly Build.cs edits across ControlRig, Chooser, LiveLink, Optimus, and Lyra (6410df6a).

    The pattern is consistent and reusable. The lower module owns a pure-virtual interface header (IK2NodeColorProvider, IK2GraphContextCommands, IBlueprintEditorBridge, IAnimBlueprintEditorBridge), the upper module implements it and self-registers at DLL static-init, and the dependency flips from a link edge to a name-loaded module. Providers forward per-call rather than caching, specifically to dodge static-init ordering hazards (dae0d248).

    Buried in the KismetCompiler absorption is a small unrelated fix worth a line: EdGraphCompiler.cpp‘s FindNodeByClass now skips null entries in Graph->Nodes instead of dereferencing them (e03cbcbd).

    Why this is important

    A circular link group cannot be built or relinked independently. Touch one module in the cycle and you drag the whole cluster with it. For the Blueprint editor stack, that cluster is six modules sitting directly under the code most editor programmers touch every day, so the cost showed up as editor iteration time on every incremental build.

    The sharper consequence is the shared PCH. BlueprintGraph headers came out of UnrealEdSharedPCH.h, which by Epic’s own count was exporting those types into 1,200-plus inheriting modules (10e8206a). Anything that was transitively picking up BlueprintGraph, Kismet, or AnimGraph headers through UnrealEd or its shared PCH will now fail to compile, and will need explicit Build.cs dependencies. Epic fixed its own code pre-emptively: UnrealEd Kismet2 consumers across roughly 70 modules (934e6b00), AssetTools (52eb36a7), LyraEditor (e4307de0), and Chooser.h (79d80a95). Third-party code gets no such courtesy.

    Also worth checking: AnimGraph and BlueprintEditorLibrary are now demand-loaded rather than resident. Any code that assumed they are already loaded at editor startup should be revisited.

    Who should care

    Anyone maintaining a custom engine fork, anyone shipping an editor plugin, and anyone with a game editor module that includes Blueprint or AnimGraph types. Build engineers too, because the payoff is smaller relink units on editor builds.

    Urgency

    High if you fork. Do not wait for your first merge conflict to discover this. Grep your editor modules for Blueprint, Kismet, and AnimGraph includes and add explicit Build.cs dependencies now, while the change is fresh and the interface pattern is easy to copy. If you only consume released binaries, this is a “know it is coming” item.

    UBA got build-cache observability, and a real scheduler bug got fixed

    What changed

    Nine UBA commits landed this week, and they are easy to miss: most carry a bare [UBA] tag and no message body.

    The UBA cache service now serves a live status web page via -http=<port>, and a new UbaCli cacheproxy mode tunnels that page over the UBA cache protocol (a new CacheMessageType_HttpRequest) so you can view a remote cache host’s dashboard locally. It is 1,679 lines across 17 files, and it exposes throughput, hit rate, storage, connected clients, maintenance history, and per-bucket controls (5bb6fad7).

    Memory-based scheduling had two real defects (0bcfde5d). A memory-throttled queue pop was indistinguishable from an empty queue, so the host repeatedly spawned local duplicates of processes already running remotely instead of picking up queued work. Your build farm loses throughput and never tells you. Separately, an expensive predicted-memory callback ran while holding the process-entries lock. Both failures make a distributed build look randomly slower under load without ever producing an error.

    The rest: the host no longer waits on remotes after it has already won the race (1ce40548), detoured processes killed from outside UBA no longer orphan their children (6194406d), and cacheproxy was fixed against a crypto-enabled cache server, with CAS validation de-prioritized so proxies can still pull during maintenance (22801911). Binaries were rebuilt (5fb183a7).

    Separately, a four-line UBT change fixed a shared-PCH cache-key bug (a18c43ec). bUseUnity was part of the shared-PCH cache key, but modules sharing a PCH explicitly set bUseUnity = false, so the key for the same shared PCH differed depending on which module created it first. UBT now takes the target’s unity setting instead of the module’s.

    Minor, and a footnote at most: WaitMutex is now settable in BuildConfiguration.xml, which helps shared CI hosts running concurrent UBT invocations (5032fd6c).

    Why this is important

    Nondeterministic cache-key generation is the worst kind of cache miss. It is invisible, it never errors, and it just looks like your cache is mediocre. Four lines fix it. If your shared or accelerated build cache has had a stubbornly poor hit rate with no explanation, this is a candidate cause, and the cheapest thing you will test all month.

    The observability work matters for a different reason. Until now, diagnosing a bad cache meant inferring from build times. A hosted status page with hit rate, throughput, and per-bucket controls, viewable through a proxy from a developer machine, turns that inference into a measurement.

    Who should care

    Build and CI engineers running UBA, anyone operating a shared build cache, and anyone who has been quietly tolerating a distributed build that is fast most days and inexplicably slow on others.

    Urgency

    Act now. The shared-PCH key fix and the memory-scheduling fix are both cherry-pick candidates today, and both move numbers you can measure. Stand up the cache status page next.


    Worth Tracking

    Slate is being annotated for dynamic invalidation

    Fifteen commits from Matt Begoghina under one ticket add TWidgetTypeTraits<W>::SupportsInvalidation() specializations across the widget library: core Slate covering docking and tabs (22432ab7), multibox (363cb557), notifications, canvas, and tooltips (344b0e77), popups and title bars (16298b3a), and layout and box widgets (a6595f63); the whole PropertyEditor stack (c5cfe7ab, 2f3fc266, 0836db2b, e02ac01f); EditorWidgets (2aa42eeb, 8f1b07e9); and the Verse EntityPrefabEditor (d3d7391c).

    Dynamic invalidation is opt-in per widget type, and a single unmarked widget inside an invalidation panel poisons the cache for that entire subtree, which is why SInvalidationPanel has historically been unusable across most editor UI. Epic is clearing that gate widget by widget, including the property grid, the heaviest Slate surface in the editor.

    Nothing changes behavior yet. It only pays off when something downstream turns the caching on broadly. Watch for the commit that enables SInvalidationPanel by default or flips a global invalidation setting. Editor UI framerate moves then, and so does the cost of any custom Slate widget in your project that has not declared SupportsInvalidation: it starts silently forcing repaints of its parent subtree. If you ship editor tooling with custom Slate widgets, add the trait.

    “Skein” and “Unreal Revision Control” are both “Lore” now

    Epic consolidated both names to Lore (6ba090ed, follow-up 138774cd). Nothing technical changed, and both commits are tiny. Treat this as naming confirmation on Epic’s source-control effort, not a feature landing. It is also the commit carrying the summer-break quote.


    What We Ignored

    • Five “Horde: Updating schema documentation” commits from buildmachine, plus an automated binaries bump. Bot traffic.
    • A Commit.gitdeps.xml binary-manifest blob bump (9d4036d3). It is a blob bump. There is nothing to read.
    • Assorted empty-message commits and include-hygiene one-liners, including a spelling fix for InitalizeExtenders (c522f9d2), which we mention only because fixing a typo during your own holiday is a choice.

    Closing

    A quiet week on the calendar, but the allowlist going to zero and a four-line cache-key fix will both cost you time if you find out about them the hard way.

    Commit SHAs are cited inline, in parentheses, next to each claim. They reference the ue6-main branch of EpicGames/UnrealEngine. Many of the highest-interest entries resolve to Commit.gitdeps.xml binary-manifest blobs: the commit message is real, but the code lives in Epic’s internal binaries, which we cannot see.

    Share this article