<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Andras Gregori on Medium]]></title>
        <description><![CDATA[Stories by Andras Gregori on Medium]]></description>
        <link>https://medium.com/@andrasgregori?source=rss-d7867d7a4aa2------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*GePbaLZN9Yp_8iaHlSwbvg.jpeg</url>
            <title>Stories by Andras Gregori on Medium</title>
            <link>https://medium.com/@andrasgregori?source=rss-d7867d7a4aa2------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 22 Jun 2026 18:49:35 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@andrasgregori/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Stop Hard-Coding Your Footsteps: Why I Built “Logic-First” Audio for Unreal Engine]]></title>
            <link>https://medium.com/@andrasgregori/stop-hard-coding-your-footsteps-why-i-built-logic-first-audio-for-unreal-engine-83dbc43b1c7b?source=rss-d7867d7a4aa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/83dbc43b1c7b</guid>
            <dc:creator><![CDATA[Andras Gregori]]></dc:creator>
            <pubDate>Sun, 18 Jan 2026 19:26:17 GMT</pubDate>
            <atom:updated>2026-01-18T19:26:17.953Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bDq51EMxAHWOzexw3uewgw.png" /></figure><p>I want you to visualize a scenario that every Unreal Engine developer has lived through.</p><p>You are an environment artist. You have just imported a beautiful Quixel Megascan library — mossy rocks, slippery temple floor tiles, broken concrete. You build a scene. It looks AAA. You press play. You run your character across the floor.</p><p><em>Silence.</em></p><p>Ah, right. You forgot the <strong>Physical Materials</strong>.</p><p>So you open the M<em>Temple_Floor_Wet Material Instance. You search for the &quot;Phys Mat&quot; slot. You realize you haven&#39;t created a &quot;Wet Stone&quot; Physical Material yet. You go to Project Settings -&gt; Engine -&gt; Physics. You scroll down to that generic list of generic enums. You type </em><em>Surface_Type68: Wet</em>Stone. You go back to the material. You assign it.</p><p>Now you have to go to your Animation Blueprint. You have to open the PlayFootstep logic. You have to add a new pin to the &quot;Switch on EPhysicalSurface&quot; node. You have to assign a sound cue.</p><p>Congratulations. You have spent 15 minutes setting up <strong>one sound</strong>. And you have 500 more materials to go.</p><p>This is not game development. This is data entry. And I got sick of it.</p><h3>The Problem: Audio as “Explicit Data”</h3><p>The standard workflow for gameplay audio in Unreal (and Unity, to be fair) relies on <strong>Explicit definition</strong>. You, the human, must tell the engine exactly what everything is, even if it’s obvious.</p><p>If a file is named M<em>Forest_Grass</em>01, the engine treats it as dumb data. It has no idea it’s &quot;Grass&quot; until you stamp a Physical Material ticket on it like a bureaucrat at the DMV.</p><p>This creates three massive problems for AA and Indie teams:</p><ol><li><strong>Fragility:</strong> If you forget to tag one material, your immersion breaks instantly.</li><li><strong>Bloat:</strong> Your Project Settings become a graveyard of hyper-specific surface types (Wood<em>Hollow, </em><em>Wood_Solid, </em><em>Wood_Wet, </em><em>Wood</em>Creaky).</li><li><strong>Spaghetti Logic:</strong> Your character audio logic becomes a massive web of Switch nodes that are a nightmare to debug.</li></ol><h3>The Solution: Sonant (Audio as Logic)</h3><p>I built <strong>Sonant</strong> because I wanted my audio middleware to act less like a filing cabinet and more like a translator.</p><p>The core philosophy is simple: <strong>Contextual Inference.</strong></p><p>If a material is named M<em>Ancient_Temple</em>Stone, the engine <em>should know</em> it’s Stone. I shouldn&#39;t have to fill out a form to prove it.</p><h3>1. The Regex Engine</h3><p>Sonant eliminates the Physical Material workflow by using a string-matching engine. You define a central “Logic Palette” (Data Asset) with simple rules:</p><ul><li>If name contains &quot;Grass&quot; -&gt; Play S<em>Grass</em>Cue.</li><li>If name contains &quot;Stone&quot; -&gt; Play S<em>Stone</em>Cue.</li></ul><p>Now, when you import that 50-asset Megascan library, you don’t do <em>anything</em>. You drop the assets in the level, run on them, and they sound correct immediately. The middleware reads the metadata that is already there.</p><p><strong>“But wait,”</strong> the optimization engineers are screaming. <strong>“You’re doing string comparisons on Tick?!”</strong></p><p>No. That would be insane.</p><h3>2. The O(1) Optimization</h3><p>String matching is heavy. Pointers are cheap.</p><p>Sonant runs on a <strong>Game Instance Subsystem</strong>. When your character steps on a surface, the system performs a lookup:</p><ol><li>Check the Runtime Cache: <em>“Have we seen this specific Material Interface pointer before?”</em></li><li>If <strong>Yes</strong>: Return the cached sound (O(1) lookup cost). <strong>0.00ms.</strong></li><li>If <strong>No</strong>: Run the Regex Logic once. Determine it’s Stone. Cache the result. Play sound.</li></ol><p>The result is a system that feels magical during development but runs with the efficiency of hard code in production.</p><h3>The “Cave in a Forest” Problem</h3><p>The second reason I built Sonant is the <strong>Atmosphere Mixer</strong>, or what I call the “Spaghetti Graph Killer.”</p><p><strong>The Scenario:</strong> You have a forest level (Ambient Birdsong). Inside the forest, there is a cave (Reverb + Wind). Inside the cave, there is a pool of water (Underwater muffled mix).</p><p><strong>The Standard Way:</strong> You place Trigger Volumes. In the OnBeginOverlap event, you write blueprint logic:</p><ul><li><em>Forest Volume:</em> “Push Forest Mix.”</li><li><em>Cave Volume:</em> “Push Cave Mix… but wait, check if I was in the Forest? Okay, remove Forest mix.”</li><li><em>Water Volume:</em> “Push Underwater… wait, did he jump in from the cave or the forest? Check booleans.”</li></ul><p>It’s messy. It breaks easily. And God forbid you drag the Cave volume slightly outside the Forest volume.</p><p><strong>The Sonant Way:</strong> I stole a page from CSS (Cascading Style Sheets). <strong>Weighted Priority.</strong></p><p>In Sonant, you don’t write logic. You assign a Priority Integer to your mixes:</p><ul><li>Forest: <strong>5</strong></li><li>Cave: <strong>10</strong></li><li>Underwater: <strong>50</strong></li></ul><p>If the player is overlapping all three volumes simultaneously, Sonant simply does the math: 50 &gt; 10 &gt; 5. The Underwater mix wins. When you faceplant out of the water, 50 is removed, and 10 (Cave) automatically takes over.</p><p>No Blueprints. No booleans. Just integers.</p><h3>Native Power, Zero Bloat</h3><p>We are in the era of Unreal Engine 5.7. We have Nanite and Lumen. We shouldn’t be using audio workflows from 2014.</p><p>Sonant is written entirely in C++. It doesn’t require you to add an Actor Component to your character. It doesn’t Tick. It sits quietly in the background, listening for requests, resolving logic, and handling the signal chain via UE5’s modern <strong>Audio Modulation</strong> API.</p><p>It is “Middleware-Lite.” It gives you the logical power of tools like Wwise, without the enterprise price tag or the external authoring tool.</p><h3>Conclusion</h3><p>Game development is hard enough. We shouldn’t be fighting our tools.</p><p>If you are tired of being a data-entry clerk for your own game, stop hard-coding your footsteps. Let the logic handle it.</p><p><strong>Sonant is available on GitHub and Fab.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=83dbc43b1c7b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Escaping the Grid: Why I Built a “Metal C++” Voxel Engine for Unreal Engine 5.7]]></title>
            <link>https://medium.com/@andrasgregori/escaping-the-grid-why-i-built-a-metal-c-voxel-engine-for-unreal-engine-5-7-9a148e2a0dbb?source=rss-d7867d7a4aa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/9a148e2a0dbb</guid>
            <category><![CDATA[voxel]]></category>
            <category><![CDATA[unreal-engine]]></category>
            <category><![CDATA[game-development]]></category>
            <dc:creator><![CDATA[Andras Gregori]]></dc:creator>
            <pubDate>Sun, 18 Jan 2026 19:17:23 GMT</pubDate>
            <atom:updated>2026-01-18T19:17:23.204Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*P23VzNxYxU7HUT63PSNdVQ.png" /></figure><p>There is a specific kind of fatigue that hits every Environment Artist and Level Designer around 2:00 AM. You are staring at SM<em>Rock_Basalt</em>04, rotating it 35 degrees on the Z-axis, scaling it by 1.2, and jamming it into a landscape hole, hoping the player won’t notice it’s the same rock you used ten meters back.</p><p>We call this “Asset Tetris.” It works, but it’s soul-crushing.</p><p>For years, the alternative was <strong>Procedural Content Generation (PCG)</strong>. But let’s be honest: until recently, PCG in Unreal Engine meant one of two things:</p><ol><li><strong>The “Lego” Look:</strong> A grid of Instanced Static Meshes that inevitably looks like a high-res Minecraft clone.</li><li><strong>The “Spaghetti” Nightmare:</strong> A blueprint so complex it looks like a map of the Tokyo subway system, taking 4 seconds to generate a single room and running at 15 FPS because the garbage collector is choking on temporary objects.</li></ol><p>I wanted something different. I wanted infinite, seamless, organic tunnels that felt like <strong>clay</strong>, not bricks. I wanted to fly through a world that generated milliseconds before I arrived, with full Nanite support, and without touching a single “Static Mesh” asset.</p><p>So, I stopped using the tools and started writing the engine. This is the story of <strong>Instant Organic Caves (IOC)</strong>.</p><h3>The Philosophy: “Metal” C++</h3><p>When I started IOC, the temptation was to use Unreal’s shiny new <strong>PCG Graph</strong>. It’s a fantastic tool for scattering trees or placing fences. But for <em>generating geometry from thin air</em>, it has limits.</p><p>The moment you try to run 3D Cellular Automata over a 100x100x100 grid in Blueprints or high-level graphs, you hit a performance wall. 1,000,000 iterations is a hiccup for a CPU, but a death sentence for a Virtual Machine.</p><p>The decision was made: <strong>Go Metal.</strong></p><p>“Metal” C++ (in the context of UE5) means bypassing the helper libraries, the Blueprint Function Libraries, and the safety wrappers. It means modifying the memory of FDynamicMesh3 directly.</p><p>By skipping the middleware, IOC achieves generation speeds that feel instant. We aren’t asking the engine, <em>“Please spawn a rock here.”</em> We are telling the GPU, <em>“Here is a list of 50,000 vertices; render them now.”</em></p><h3>The Technical Challenge: Making Voxels not look like Voxels</h3><p>The biggest hurdle in procedural geometry is the <strong>“Sharding”</strong> effect.</p><p>If you generate a voxel grid and simply convert it to mesh faces, you get a blocky world. If you try to smooth that world using standard Laplacian Smoothing, something horrifying happens: the mesh creates internal geometry. The vertices pull inward, the faces cross, and your cave explodes into a cloud of floating triangles that looks like shattered glass.</p><h3>The Solution: The Welded Skin</h3><p>IOC solves this with a three-stage pipeline that runs entirely in memory:</p><ol><li><strong>World-Space Noise Field (With Jitter):</strong> We sample 3D Perlin Noise to determine density. But standard Perlin noise has a weakness: it returns 0.0 at integer coordinates. If your voxel size aligns with the noise frequency, you get &quot;Zebra Stripes&quot;—holes in the world that appear in a perfect grid pattern.</li></ol><p>IOC applies a prime-number coordinate jitter to the sampling algorithm, offsetting the math just enough to ensure we never hit those mathematical dead zones.</p><p><strong>2. Topological Welding:</strong> Instead of generating a cube for every voxel (which creates 8 vertices per cube), IOC uses a <strong>Linear Index Vertex Cache</strong>. Before creating a vertex, it asks: <em>“Did my neighbor already build a corner here?”</em></p><p>If yes, it reuses that Vertex ID. This “welds” the entire chunk into a single, continuous skin. It’s no longer a bag of blocks; it’s a balloon.</p><p><strong>3. The Organic Melt:</strong> Once we have a welded skin, we run a custom <strong>Iterative Smoothing Kernel</strong>. Because the vertices are shared, they pull against each other like surface tension on water.</p><p>Square corridors melt into lava tubes. Sharp corners erode into ancient cavern walls. And because we distort the vertices <em>before</em> smoothing using secondary noise frequencies (SurfaceRoughness), we avoid the &quot;melted wax&quot; look and retain that craggy, rocky feeling.</p><h3>Infinite Worlds on a Budget</h3><p>The final piece of the puzzle is the <strong>IOC World Generator</strong>.</p><p>Generating one chunk is easy. Generating an infinite world is a math problem. If you simply spawn chunks based on local coordinates, the seams won’t match. You’ll see a line where chunk A ends and chunk B begins.</p><p>IOC uses <strong>Deterministic World-Space Generation</strong>.</p><p>Every voxel queries the global world coordinate system. This means if Chunk A generates noise at X=100, and Chunk B generates noise at X=101, the math is continuous.</p><p>You can fly from the origin to X=1,000,000, and the caves will continue to snake around you, seamlessly, forever. And because we utilize UDynamicMeshComponent with <strong>Runtime Nanite</strong> support (a feature unlocked fully in UE 5.7), the geometry stream costs are negligible compared to the visual fidelity.</p><h3>Why this matters</h3><p>The “Raison d’être” of Instant Organic Caves is not just to make caves. It’s to validate a workflow.</p><p>We are entering an era of game development where assets need to be <strong>smart</strong>. A static mesh is dumb; it takes up disk space and never changes. A procedural actor is smart; it weighs nothing on disk and adapts to its environment.</p><p>IOC was built to prove that you don’t need a team of 50 artists to create an infinite underground world. You just need the right math, a little bit of “Metal” C++, and the willingness to let go of the grid.</p><p><em>Instant Organic Caves is available now for Unreal Engine 5.7 on GitHub and Fab.com.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9a148e2a0dbb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cracking the Earth Open: Why I Rebuilt Unreal’s Terrain System from Scratch (So You Don’t Have To)]]></title>
            <link>https://medium.com/@andrasgregori/cracking-the-earth-open-why-i-rebuilt-unreals-terrain-system-from-scratch-so-you-don-t-have-to-e775f6d81df5?source=rss-d7867d7a4aa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/e775f6d81df5</guid>
            <category><![CDATA[cplusplus]]></category>
            <category><![CDATA[game-development]]></category>
            <category><![CDATA[unreal-engine]]></category>
            <dc:creator><![CDATA[Andras Gregori]]></dc:creator>
            <pubDate>Sat, 17 Jan 2026 19:08:24 GMT</pubDate>
            <atom:updated>2026-01-17T19:08:24.674Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>By Andras Gregori @ GregOrigin</strong></p><h4>If you have ever tried to make a grenade leave a permanent crater in a standard Unreal Engine Landscape, you know the sound of a game developer crying.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-YYyUNpMBMMTgzXgFEyZUw.png" /></figure><p>It usually goes like this: You enable “Edit Layers.” You realize runtime modification is experimental. You try the “Voxel Plugin,” which is a technological marvel — a Ferrari of engineering. But then you realize you’re building a rugged off-road rally game, and bringing a Ferrari to a mud fight involves a lot of expensive repair bills (performance costs).</p><p>There was a missing link in the Unreal ecosystem. We have the <strong>Static Mountain</strong> (Landscape) and the <strong>Volumetric God-Mode</strong> (Voxels). But we lacked the <strong>Dynamic Ground</strong>.</p><p>Enter <strong>TerraDyne</strong>.</p><p>This is the story of why I built a native C++ plugin to solve the “2.5D Problem,” why N³ complexity is the enemy of optimization, and why we eventually had to go &quot;Metal&quot; to survive the Unreal Engine 5.7 API apocalypse.</p><h3>The “Goldilocks” Problem of Dirt</h3><p>Here is the fundamental engineering problem with destructible terrain in 2026:</p><ol><li><strong>Standard Landscapes (Heightfields)</strong> are optimized for kilometers of view distance but are notoriously rigid at runtime. They hate changing shape after the game starts.</li><li><strong>Voxel Systems (Volumetric)</strong> simulate massive blocks of data so you can have caves and arches. But updating a chunk requires calculating volume ($N³$ complexity) and rebuilding complex collision hulls. It’s heavy.</li></ol><p><strong>TerraDyne exists for the middle ground.</strong></p><p>If you are making <em>Battlefield</em>, <em>SimCity</em>, or a Tank Simulator, you don’t need caves. You don’t need floating islands. You need <strong>craters</strong> and <strong>ruts</strong>. You need the ground to move Up and Down, instantly, without stalling the Game Thread.</p><p>TerraDyne is a <strong>Dynamic 2.5D Heightfield system</strong>. It keeps the simplicity of a texture ($N²$ complexity) but allows for the brute-force malleability of a voxel engine.</p><h3>Going “Metal”: Surviving Dependency Hell</h3><p>When I started writing TerraDyne, I played nice. I used the high-level wrappers. I used the friendly Blueprint libraries provided by Epic.</p><p>Then Unreal Engine 5.7 dropped.</p><p>Suddenly, WeightmapTextures were private. Helper functions were deprecated. The Input system was locked down. The plugin shattered.</p><p>This led to a philosophy shift: <strong>The “Metal” Workflow.</strong></p><p>Instead of relying on fragile, shifting Editor APIs, TerraDyne now talks directly to the engine’s memory and math kernels.</p><ul><li><strong>Physics:</strong> We don’t ask the engine to “please update the collider.” We reach into the FDynamicMesh3 pointers and move vertices manually using raw double-precision math.</li><li><strong>Visuals:</strong> We don’t use high-level material draw calls. We lock the GPU Texture memory and memcpy our float arrays directly into the Render Hardware Interface (RHI).</li></ul><p>The result? <strong>Speed.</strong> A 128x128 chunk updates its collision and rendering in microseconds because we aren’t waiting for the engine’s bureaucracy. We are writing 0s and 1s directly to the metal.</p><h3>Only What You See (The Lidar Solution)</h3><p>One of the funniest hurdles we faced was simply: <em>How do we copy an existing Landscape?</em></p><p>With UE 5.7 efficiently hiding the raw data of landscapes behind “Private” access modifiers to support Nanite, we couldn’t just “read the heightmap” anymore.</p><p>Our solution? <strong>Lidar.</strong></p><p>TerraDyne includes a “Nuclear Option” import tool. It fires thousands of raycasts from the sky, physically scanning your level geometry. It doesn’t care if your terrain is a Landscape, a Static Mesh, or a pile of cubes. If collision hits it, TerraDyne captures it.</p><p>It creates a perfect physical clone of your world, completely decoupling you from the source asset’s internal data format.</p><h3>The Sync Crisis: Orbs vs. Spikes</h3><p>The hardest part of dynamic terrain is that <strong>Physics (CPU)</strong> and <strong>Rendering (GPU)</strong> live in different universes.</p><p>In the early days of development, we had specific “Grotesque” bugs. The visual mesh (VHFM) would look perfect, but physics projectiles would bounce off invisible walls 50 meters in the air. Or the physics would be correct, but the visual terrain would look like spiky glitch art.</p><p>The breakthrough was a <strong>Single Source of Truth</strong>.</p><p>TerraDyne maintains a raw TArray&lt;float&gt; on the CPU.</p><ol><li><strong>Input:</strong> A brush command modifies this float array.</li><li><strong>Visuals:</strong> We flash-upload this array to an R16f Texture.</li><li><strong>Physics:</strong> We iterate the array and snap the collision mesh vertices to the exact same values.</li></ol><p>By forcing both systems to slave to the same float array in the same tick, we achieved what few plugins manage: <strong>1:1 Synchronization.</strong> A falling orb hits exactly where the pixel is drawn.</p><h3>Conclusion: Don’t Buy a Helicopter to Drive to Work</h3><p>Voxel Plugin is incredible. If you are making <em>Minecraft</em> or <em>Deep Rock Galactic</em>, use it. It is superior in features.</p><p>But if you are building a game where the ground needs to react to explosions, heavy tires, or terraforming lasers — without eating your frame budge — you need a tank, not a helicopter.</p><p><strong>TerraDyne</strong> is that tank. It is lightweight, native, and built to take a beating so your frame rate doesn’t have to.</p><p><em>TerraDyne is available now on GitHub and Fab. Check the documentation at </em><a href="https://www.gregorigin.com"><em>gregorigin.com</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e775f6d81df5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Stop Tabbing Out: Why I Built a Native LTX-2 Bridge for Unreal Engine 5]]></title>
            <link>https://medium.com/@andrasgregori/stop-tabbing-out-why-i-built-a-native-ltx-2-bridge-for-unreal-engine-5-f8f2d57aa283?source=rss-d7867d7a4aa2------2</link>
            <guid isPermaLink="false">https://medium.com/p/f8f2d57aa283</guid>
            <category><![CDATA[ai-video-generator]]></category>
            <category><![CDATA[comfy-ui]]></category>
            <category><![CDATA[unreal-engine]]></category>
            <category><![CDATA[game-development]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Andras Gregori]]></dc:creator>
            <pubDate>Sat, 17 Jan 2026 18:50:35 GMT</pubDate>
            <atom:updated>2026-01-17T18:50:35.411Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>Generative AI has a “workflow problem.” It creates assets instantly, but integrating them takes twenty minutes. Here is why I built UELTX2 to fix the pipeline, keep your data local, and kill the “Alt-Tab” loop.</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_Ab5YSlCLVFiumIX7RNH2Q.png" /><figcaption>“Living Textures” are a feature of the UELTX2 plugin.</figcaption></figure><p>We need to talk about the “Alt-Tab Walk of Shame.”</p><p>You know the drill. You are in the flow state, building a cyberpunk level in Unreal Engine 5. You need a texture for a holographic billboard. You Alt-Tab to a web browser. You log into a cloud service (Runway, Kling, Sora). You type a prompt. You wait in a queue. You pay 50 credits.</p><p>You download an .mp4. You Alt-Tab back to Unreal. You import the file. You create a Media Player. You create a Media Texture. You realize it doesn’t loop. You open Premiere. You fix the loop. You re-import. You create a Material. You plug the texture into Emissive Color.</p><p><strong>Total time:</strong> 15 minutes. <strong>Creative flow:</strong> Dead.</p><p>This was the frustration that birthed <strong>UELTX2</strong>.</p><p>I realized that for Generative Video to actually be useful in Game Development, it cannot be a destination you visit. It has to be a tool <em>inside</em> the box.</p><p>Here is the rationale, the architecture, and the philosophy behind building a native bridge for <strong>Lightricks’ LTX-2</strong> inside Unreal Engine 5.</p><h3>The “Localhost” Philosophy</h3><p>The first question I usually get is: <em>“Why LTX-2? Why not just API into the big cloud models?”</em></p><p>Two reasons: <strong>Privacy</strong> and <strong>Burn Rate</strong>.</p><h3>1. The NDA Problem</h3><p>If you work at a AAA studio (or even a secretive Indie), you cannot upload screenshots of your unannounced Level Greybox to a public cloud server to do “Image-to-Video.” That is a data leak waiting to happen.</p><p><strong>LTX-2</strong> is open weights. It runs locally. With UELTX2, I designed the architecture to bridge Unreal Engine directly to a local <strong>ComfyUI</strong> instance running on localhost:8188. Your assets never leave your GPU. You can animate a texture for a top-secret project without your legal department having a panic attack.</p><h3>2. Iteration should be free</h3><p>Game dev is about iteration. If every attempt to generate a “magical fire effect” costs $0.50 in cloud credits, you become precious about your prompts. You hesitate.</p><p>When the model runs on your RTX 4090, the cost is electricity. You can generate 50 variations of a User Interface glitch loop over lunch. That freedom is essential for artistic exploration.</p><h3>The “Zero-Click” Pipeline</h3><p>The core “Raison d’Exister” of this plugin isn’t just generating the pixels — it’s automating the <strong>Unreal Engine Media Framework</strong> hell that comes after.</p><p>If you have ever tried to set up video playback in UE5 manually, you know it involves about four different asset types linked in a specific chain.</p><p>I wrote the UELTX2 Subsystem to handle what I call the <strong>“Zero-Click Asset Generation.”</strong></p><p>When you hit <strong>[Generate]</strong> in my plugin, the C++ doesn’t just download a video file. It executes a complete pipeline:</p><ol><li>It catches the finished file from ComfyUI.</li><li>It imports it as a FileMediaSource.</li><li>It creates a MediaPlayer and sets it to <strong>Auto-Loop</strong>.</li><li>It creates a MediaTexture and links the player.</li><li>It generates an <strong>Unlit Material</strong> and wires the texture to the Emissive channel.</li><li>It creates a LevelSequence or NiagaraSystem depending on your workflow.</li></ol><p>By the time the progress bar finishes, you don’t have a video file; you have a <strong>ready-to-use Material</strong> or <strong>Animatic</strong>. You just drag and drop.</p><h3>The Three “Killer Apps” for In-Engine Video</h3><p>Why do we even need video in a 3D engine? Isn’t Real-Time 3D the point?</p><p>Yes, but 3D is expensive. Here are the three use cases where UELTX2 pays for itself:</p><h3>1. The Living Texture (Image-to-Video)</h3><p>This is my favorite workflow. You right-click a static Texture in your Content Browser, choose <strong>“Animate with LTX-2,”</strong> and 3 minutes later, it’s moving.</p><ul><li><strong>Use case:</strong> Distant cyberpunk cities, flickering screens, magical portraits, moving skies.</li><li><strong>Why:</strong> Doing this with shaders is hard. Doing this with 3D geometry destroys your frame rate. A video texture is cheap and looks expensive.</li></ul><h3>2. Disposable Animatics (Text-to-Video)</h3><p>Level Designers use “Greyboxing” to test flow. But how do you test the <em>timing</em> of a massive scripted event — like a bridge collapsing — before the animators spend 3 weeks making it? With UELTX2, you prompt <em>“Stone bridge collapsing, physics destruction,”</em> and drag the resulting <strong>Level Sequence</strong> into the map. Now you can time your sound cues, camera shakes, and lighting triggers against a placeholder that actually looks like the final event.</p><h3>3. The “EmberGen” Shortcut (VFX)</h3><p>Niagara is powerful, but you need source textures. Creating a 64-frame flipbook of “Green Toxic Smoke” usually implies opening Houdini or EmberGen. I added a workflow where you prompt for “Black background, isolated smoke,” and the plugin automatically builds an <strong>Additive Material</strong> ready for Niagara. It transforms a text prompt into a particle sprite in minutes.</p><h3>The Tech Stack: ComfyUI as the Engine Room</h3><p>I chose <strong>ComfyUI</strong> as the backend because it is the industry standard for optimization. LTX-2 is a heavy DiT (Diffusion Transformer) model. If I tried to run the inference memory inside the Unreal process, the Editor would crash instantly when VRAM spiked.</p><p>By decoupling them (Unreal as the Frontend, ComfyUI as the Backend), we let the OS handle memory paging. You can keep working in the Viewport while the video generates in the background.</p><p>It uses a polling system (checking file timestamps) rather than a complex WebSocket setup, making it robust enough to handle crashes on either side without hanging the other.</p><h3>Conclusion: Curated Generation</h3><p>We are moving past the novelty phase of AI. Use tools that treat AI as a <strong>utility</strong>, not a magic trick.</p><p>The goal of <strong>UELTX2</strong> wasn’t to replace the 3D pipeline. It was to fill the gaps <em>in between</em> the 3D assets with high-fidelity motion, without ever forcing the developer to leave the environment they are building in.</p><p>It’s open architecture, it’s local, and it respects your time.</p><p><em>UELTX2 is available now on Fab and GitHub.</em></p><p><em>(Author’s Note: Ensure you have an NVIDIA GPU with at least 12GB VRAM before attempting to run LTX-2 locally. The future is cool, but it is VRAM hungry.)</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8f2d57aa283" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>