<?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"><channel><title><![CDATA[Shijian's blog]]></title><description><![CDATA[Game development]]></description><link>https://blog.catoxliu.net</link><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 04:30:47 GMT</lastBuildDate><atom:link href="https://blog.catoxliu.net/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Missing Scene Depth for Custom Vertex Factories in Unreal Engine]]></title><description><![CDATA[As last time I started using the vertex factory to consume the instance buffer by drawing indexed primitive with indirect buffer, some issues have been found which is interesting (struggling).
Firstly]]></description><link>https://blog.catoxliu.net/missing-scene-depth-for-custom-vertex-factories-in-unreal-engine</link><guid isPermaLink="true">https://blog.catoxliu.net/missing-scene-depth-for-custom-vertex-factories-in-unreal-engine</guid><category><![CDATA[unreal-engine]]></category><dc:creator><![CDATA[sj]]></dc:creator><pubDate>Wed, 25 Feb 2026 05:01:59 GMT</pubDate><content:encoded><![CDATA[<p>As last time I started using the vertex factory to consume the instance buffer by drawing indexed primitive with indirect buffer, some issues have been found which is interesting (struggling).</p>
<p>Firstly, it's the missing scene depth for the generated mesh, even the material is set to opaque and as simple as possible. Without the depth there, the overlap meshes will have z-fighting all the time which is unacceptable.</p>
<p>I checked and play around with the vertex factory shader, the FPrimitiveViewRelevance and FMeshBatch configurations and nothing works.</p>
<p>Then I tried the material itself, and do find a workaround for it, setting a small number to the "Pixel Depth Offset" seems force it render to scene depth again. Which gives me a clue, so I follow it up in the render pipeline. So without the "Pixel Depth Offset", the vertex factory's indirect draw will disappear in <code>PrePass DDM_AllOpaque</code> 's depth pass. it's because the engine default shader <code>DepthOnlyVertexShader</code> is used in this case and for our vertex factory shader map, it's missing, and then the <code>DepthRendering::GetDepthPassShaders</code> will early return false.</p>
<p>Once find the root cause, the fix is easy, just make sure add the default shader in the vertex factory permutation using <code>MaterialParameters.bIsSpecialEngineMaterial</code></p>
<pre><code class="language-cpp">bool FVertexFactory::ShouldCompilePermutation(const FVertexFactoryShaderPermutationParameters&amp; Parameters)
{
	return MyVertexFactoryPermutation() || Parameters.MaterialParameters.bIsSpecialEngineMaterial;
}
</code></pre>
<p>Then the next issue is while moving the camera around or turn on some vertex animation for the vertex factory generated mesh, part of the mesh will become black and some yellow text behind it saying:</p>
<p><mark class="bg-yellow-200 dark:bg-yellow-500/30">"Your scene contains a skydome mesh with a sky material, but it does not cover that part of the screen..."</mark></p>
<p>not my game, image from internet:</p>
<img src="https://cdn.hashnode.com/uploads/covers/626dfd3d454011df6e86c25d/b8aab285-76a4-4b30-b5f9-307ca805917f.png" alt="" style="display:block;margin:0 auto" />

<p>So I believe it's some corrupted buffer for my vertex factory, and I noticed that without the scene depth buffer fix, it's not showing up. After reading the compiled shader I realised that the default <code>DepthOnlyVertexShader</code> still needs call the vertex factory <code>GetVertexFactoryIntermediates</code>, which consume the instance buffer. But the instance buffer is written by a compute shader after the PrePass there. So a classical race condition : )</p>
<p>Then moving that compute shader pass before the PrePass get everyhing works as expected with the vertex factory now.</p>
]]></content:encoded></item><item><title><![CDATA[Custom Render Passes for Unreal Engine on iOS]]></title><description><![CDATA[Once I get the custom render pass for Unreal working fine on Windows, I started the painful journey to make it working on mobile (iOS to be specific).
To simplify, the custom render pass has two parts, the first one is computing shader to generate th...]]></description><link>https://blog.catoxliu.net/custom-render-passes-for-unreal-engine-on-ios</link><guid isPermaLink="true">https://blog.catoxliu.net/custom-render-passes-for-unreal-engine-on-ios</guid><category><![CDATA[unreal-engine]]></category><category><![CDATA[iOS]]></category><category><![CDATA[Rendering]]></category><dc:creator><![CDATA[sj]]></dc:creator><pubDate>Mon, 16 Feb 2026 04:14:10 GMT</pubDate><content:encoded><![CDATA[<p>Once I get the custom render pass for Unreal working fine on Windows, I started the painful journey to make it working on mobile (iOS to be specific).</p>
<p>To simplify, the custom render pass has two parts, the first one is computing shader to generate the instance data in the pre render base pass and then draw these instances in the base pass. For destop platform, it’s very straight forward to add the two custom passes into <code>FDeferredShadingSceneRenderer::Render</code>.</p>
<p>For the mobile platform, the compute pass added into <code>FMobileSceneRenderer::Render</code> and draw pass added into <code>FMobileSceneRenderer::RenderDeferredMultiPass</code>, which works as expected in Unreal editor preview on both Windows and Mac.</p>
<p>But while testing on iOS, it’s not working. Going into the GPU debug in XCode shows that the compute pass is working fine but the draw pass is never called. And then I learnt that for iOS, it’s using <code>FMobileSceneRenderer::RenderDeferredSinglePass</code>.</p>
<p>But adding the draw pass there after the <code>SceneColorRendering</code> pass is still not working on device and GPU debug shows that the draw pass is correctly run and the SceneColor/GBuffer result is as expected. The problem is that it’s too late, because SceneColor/GBuffer is already consumed for back buffer in the <code>SceneColorRendering</code> pass previously (yeah, it’s called for <code>RenderDeferredSinglePass</code> for a reason : ). So the correct way is to make the draw pass a subpass inside the <code>SceneColorRendering</code> pass. Or a better solution is to use unreal vertex factory for drawing our instances, more powerful and flexible, and also it will be handled by <code>FMobileBasePassMeshPassProcessor</code>, which then will be part of the subpass there.</p>
<p>A quick test with a simple vertex factory shows promising result, so I start to fully implement all our features into the vertex factory and then I start getting a crash error while starting the game.</p>
<blockquote>
<p>[UE] Ensure condition failed: Texture [File:./Runtime/Renderer/Private/MeshPassProcessor.cpp] [Line: 828] Shader TBasePassVSFNoLightMapPolicy with vertex factory FMyCustomVertexFactory never set texture at BaseIndex 0. This can cause GPU hangs, depending on how the shader uses it.</p>
</blockquote>
<p>Which is very wired because I don’t have any texture parameters in my shader. But surprisingly, after checking the compiled shader file for METAL, it turns out somehow my <code>Buffer&lt;uint&gt; ReserveBuffer</code> is translated to <code>texture_buffer ReservedBuffer [[texture(0)]]</code>! Some searching saying this is expected behavior, so for now my fix is to use StructuredBuffer&lt;uint&gt; in my shader.</p>
<p>Now, no crash or errors, but one feature is not working correctly on iOS. And I notice the data structure of this feature is not aligned with 16-bytes.</p>
<pre><code class="lang-cpp"> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">FMyDataStructure</span> 
{</span>
    FVector3f Pos;
    FVector3f UpVector;
    <span class="hljs-keyword">float</span> Height;
    <span class="hljs-keyword">float</span> Radius;
}
</code></pre>
<p>So change it into</p>
<pre><code class="lang-cpp"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">FMyDataStructure</span> 
{</span>
    FVector4f PosAndHeight;    <span class="hljs-comment">// .xyz = Pos, .w = Height</span>
    FVector4f UpVectorAndRadius; <span class="hljs-comment">// .xyz = UpVector, .w = Radius</span>
};
</code></pre>
<p>And now everything works on iOS : )</p>
]]></content:encoded></item><item><title><![CDATA[Flickering issue with Indexed Indirect Draw]]></title><description><![CDATA[In previous post I have the procedual grass rendering working with the IndexedIndirectDraw, but while testing it, I find there’re flickering issue sometimes. And after playing with it for a while I ca]]></description><link>https://blog.catoxliu.net/flickering-issue-with-indexed-indirect-draw</link><guid isPermaLink="true">https://blog.catoxliu.net/flickering-issue-with-indexed-indirect-draw</guid><category><![CDATA[unreal-engine]]></category><category><![CDATA[GPU]]></category><category><![CDATA[NVIDIA]]></category><dc:creator><![CDATA[sj]]></dc:creator><pubDate>Tue, 20 Jan 2026 02:33:33 GMT</pubDate><content:encoded><![CDATA[<p>In <a href="https://hashnode.com/post/cmk3ahsli000002jvdpxja7om">previous post</a> I have the procedual grass rendering working with the IndexedIndirectDraw, but while testing it, I find there’re flickering issue sometimes. And after playing with it for a while I can create an edge case with specific number of the size of my instance buffer, which making over 1/3 of the grasses flickering constantly.</p>
<p>Now I have a perfect test case, and I start debugging it closely. The first thing I noticed is that in the RenderDoc, and in the mesh viewer of my VS pass shows the output SV_Position is shown as NaN (Not a Number) for the almost 1/3 of the instance buffer. The interesting part is that if I debug it step by step, everything just works fine as expected and we got a solid position there. Then I learnt that RenderDoc debug shader is a “simulation” on CPU side, and it cannot guarantee the result match what’s on GPU.</p>
<p>Then I thought it could be some sync issue of the instance buffer or the indirect arguments buffer, wasting a day working on it trying different buffer setup, explicit buffer transition and memory barrieers, no luck.</p>
<p>Ruling out the sync issue, I spent another day to verifying my compute pass to make sure all the data is generated correctly without any surprises.</p>
<p>As I almost gave up, I asked AI if my structure of the instance buffer is cursed : ( but surprisingly, it notice the culprit immediately : )</p>
<p>The real trouble began with a struct that looked like this:</p>
<pre><code class="language-cpp">struct FData {
    float3 Position;
    float Width;
    // ... other floats ...
    int Payload;
    float4 ControlPos0; // &lt;-- The Saboteur
};
</code></pre>
<p>The structure is 92 bytes in total.</p>
<p>And according to google, it seems that (for NVIDIA specifically), a <code>float4</code> isn't just four floats—it is a <strong>16-byte vector entity</strong>.</p>
<p>And this seems to be the root cause that some of the instance buffer will read "invalid data".</p>
<p><strong>The Fix: Manual Padding is Your Friend</strong></p>
<p>In fact, in latest <a href="https://github.com/EpicGames/UnrealEngine/blob/0b917fe1ab67ca45e1233a866c92e791fc451ef8/Engine/Source/Runtime/D3D12RHI/Private/D3D12Buffer.cpp#L420">Unreal Engine</a> (5.7), they add a new variable "RHI_RAW_VIEW_ALIGNMENT" to check if your structured buffer stride is <code>LeastCommonMultiplier</code> of it while creating the buffer.</p>
<p>So for my case, to fix it, we had to add a simple <code>float Padding;</code> after our <code>int Payload;</code>, we manually aligned to the 16-byte boundary. And then the flickering issue goes away.</p>
<p><strong>The ByteAddressBuffer Escape Hatch</strong></p>
<p>And some search result shows there's other work around for this, but I didn't test it.</p>
<p>If you’re tired of fighting with alignment, there is the <strong>ByteAddressBuffer</strong>. It treats memory as raw bytes, skipping the "smart" auto-padding of Structured Buffers. It's more manual, but it's the ultimate way to ensure what you send is exactly what you get.</p>
]]></content:encoded></item><item><title><![CDATA[An issue with indexed indirect draw in Unreal]]></title><description><![CDATA[Long story short, I’m working on a shader for an indexed indirect draw in Unreal. And I had a VS-To-PS struct here as simple as:
struct VertexOutput
{
  float4 Position : SV_POSITION;
}

And this works just perfect fine.
But things get buggy once I a...]]></description><link>https://blog.catoxliu.net/an-issue-with-indexed-indirect-draw-in-unreal</link><guid isPermaLink="true">https://blog.catoxliu.net/an-issue-with-indexed-indirect-draw-in-unreal</guid><category><![CDATA[unreal-engine]]></category><category><![CDATA[shader]]></category><dc:creator><![CDATA[sj]]></dc:creator><pubDate>Wed, 07 Jan 2026 00:38:01 GMT</pubDate><content:encoded><![CDATA[<p>Long story short, I’m working on a shader for an indexed indirect draw in Unreal. And I had a VS-To-PS struct here as simple as:</p>
<pre><code class="lang-cpp"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">VertexOutput</span>
{</span>
  float4 Position : SV_POSITION;
}
</code></pre>
<p>And this works just perfect fine.</p>
<p>But things get buggy once I add another variable into the struct, which is still very simple</p>
<pre><code class="lang-cpp"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">VertexOutput</span>
{</span>
  float4 Position : SV_POSITION;
  float4 Test : TEXCOORD0;
}
</code></pre>
<p>The render result shows that the position data is still right, but “test” data is always default.</p>
<p>I have no idea what’s wrong so goes RenderDoc to check step by step, and everything seems just working until the PS stage as the input from VS is all default.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767743714477/c7c20212-637d-4ed3-af14-eb99d5b30145.png" alt class="image--center mx-auto" /></p>
<p>But I double check the output of the VS which is definitely fine, and also, the render result position is right.</p>
<p>Drop all the shaders into AI and ask why it happened, and it can hardly understand the real issue, other than giving possible solutions. So I simplified the question as “what possible causes for a PS only get default output from VS?”, and then I can narrow it down to the “VS-To-PS struct mismatch“. While my struct is so simple I cannot tell how it could mismatch, I suddenly realize it could be the unreal shader complier.</p>
<p>Get into the RenderDoc again and check the VS there, and my guess is correct, in the compiled VS shader, the SV_POSITION is reordered to last position in the struct, but no changes for PS shader. That’s why I get a mismatch here.</p>
<p>A quick search in the Unreal Engine source code shows it’s a bug introduced a while ago which only affect indexed indirect draw and fixed later for the shader compiler, and I’m the unlucky guy who is not using the latest version…</p>
<p>Again this is another disappointing experience using AI while coding with shader in Unreal, another case is months ago while I turned on shader debugging the editor cannot start due to shader validation failed:</p>
<pre><code class="lang-cpp"><span class="hljs-function">Get a shader compilation error when I disable shader optimize <span class="hljs-keyword">for</span> current <span class="hljs-title">project</span> <span class="hljs-params">(Unreal <span class="hljs-number">5.3</span>)</span>
5 Shader compiler errors compiling global shaders <span class="hljs-keyword">for</span> platform PCD3D_SM6:
Shader debug info dumped to: "/Saved/ShaderDebugInfo/PCD3D_SM6/Global/FShadingFurnaceTestPassPS/0"
Engine/Shaders/Private/ShadingFurnaceTest.<span class="hljs-title">usf</span><span class="hljs-params">()</span>: Shader FShadingFurnaceTestPassPS, Permutation 0, VF None:
    error: validation errors
Engine/Binaries/Win64/<span class="hljs-params">(<span class="hljs-number">6395</span>,<span class="hljs-number">6</span>)</span>: Shader FShadingFurnaceTestPassPS, Permutation 0, VF None:
    zzz.<span class="hljs-title">dxil</span><span class="hljs-params">(<span class="hljs-number">6395</span>,<span class="hljs-number">6</span>)</span>: error: Instructions should <span class="hljs-keyword">not</span> read uninitialized value.
/Engine/Shaders/Private/ShadingFurnaceTest.<span class="hljs-title">usf</span><span class="hljs-params">()</span>: Shader FShadingFurnaceTestPassPS, Permutation 0, VF None:
    note: at 'br i1 undef, label %1664, label %1699' in block '#89' of function 'MainPS'.
/Engine/Shaders/Private/ShadingFurnaceTest.<span class="hljs-title">usf</span><span class="hljs-params">()</span>: Shader FShadingFurnaceTestPassPS, Permutation 0, VF None:
    Validation failed.
/Engine/Shaders/Private/ShadingFurnaceTest.<span class="hljs-title">usf</span><span class="hljs-params">()</span>: Shader FShadingFurnaceTestPassPS, Permutation 0, VF None:
    D3DCompileToDxil failed. Error code: Unspecified <span class="hljs-title">error</span> <span class="hljs-params">(<span class="hljs-number">0x80004005</span>)</span>.</span>
</code></pre>
<p>I think this is an easy one, so I give the shader file and error message to AI and it tried several times and cannot fix it… Then I have to let it explain the shader line by line and ask if the variable is properly initialized, still no luck, I highlight that any custom struct has to be initialized explicitly, and then it finally find the fix:</p>
<pre><code class="lang-cpp">-                FDeferredLightData LightData;
+                FDeferredLightData LightData = (FDeferredLightData)<span class="hljs-number">0</span>;
</code></pre>
<p>But this time I’m not that frustrated, I have found a way to “work” with AI now and it does help me to get more efficient : )</p>
]]></content:encoded></item><item><title><![CDATA[Check your MSVC version if you having errors when using new feature in C++ 20]]></title><description><![CDATA[Getting this error while compiling an open-source code.
error C2039: 'format_string': is not a member of 'std'
Google results will tell you to make sure you're using C++20 flag in the compiler since it's a new feature. I'm pretty sure it's not the is...]]></description><link>https://blog.catoxliu.net/check-your-msvc-version-if-you-having-errors-when-using-new-feature-in-c-20</link><guid isPermaLink="true">https://blog.catoxliu.net/check-your-msvc-version-if-you-having-errors-when-using-new-feature-in-c-20</guid><category><![CDATA[C++]]></category><category><![CDATA[C2039]]></category><dc:creator><![CDATA[sj]]></dc:creator><pubDate>Thu, 29 Jun 2023 02:28:38 GMT</pubDate><content:encoded><![CDATA[<p>Getting this error while compiling an open-source code.</p>
<p><code>error C2039: 'format_string': is not a member of 'std'</code></p>
<p>Google results will tell you to make sure you're using C++20 flag in the compiler since it's a new feature. I'm pretty sure it's not the issue since <code>std::format</code> itself works fine in the code. But I double checked anyway and try all solutions I could find online (big mistake, trying to be lazy : ). I checked all the dependencies and VS packages needed. I even re-install Visual Studio 2022.</p>
<p>After wasting half a day (and a good sleep) without any progress, I started to be serious about this error.</p>
<p>So back to the error, what's this <code>std::format_string</code>. According to <a target="_blank" href="https://en.cppreference.com/w/cpp/utility/format/basic_format_string">std::basic_format_string, std::format_string, std::wformat_string -</a> <a target="_blank" href="http://cppreference.com">cppreference.com</a>, it's a new feature in C++ 20 standard library and should be in the &lt;format&gt; header file. (Yes, I do explicitly include this header file in the source code and nothing changed).</p>
<p>The definition of it is:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">template</span>&lt; class... Args &gt;
<span class="hljs-keyword">using</span> format_string = basic_format_string&lt;<span class="hljs-keyword">char</span>, <span class="hljs-built_in">std</span>::<span class="hljs-keyword">type_identity_t</span>&lt;Args&gt;...&gt;;
</code></pre>
<p>Then I open the format header in the MSVC and try to search for it. Of course no exact match, so I just tried the patterns like "basic_format_string". Finally, I find this:</p>
<pre><code class="lang-cpp"><span class="hljs-keyword">template</span> &lt;class... _Args&gt;
<span class="hljs-keyword">using</span> _Fmt_string = _Basic_format_string&lt;<span class="hljs-keyword">char</span>, <span class="hljs-keyword">type_identity_t</span>&lt;_Args&gt;...&gt;;
</code></pre>
<p>Surprise, surprise, MSVC has their own naming different from the standard library : )</p>
<p>Then changing the <code>std::format_string</code> to <code>std:_Fmt_string</code> fix the compilation errors. But why I'm getting this while it seems to work fine for others? I realise it's the MSVC version I'm using, it's 14.34.31933 even though the latest one is 14.36.32532.</p>
<p>Then I reinstall MSVC again and this time to ensure I have the latest version of MSVC installed. Then in 14.36.32532, the format header change it to <code>std::format_string</code> and now the original source code is compiled without any issues.</p>
<p>Lesson learnt : )</p>
]]></content:encoded></item><item><title><![CDATA[Unreal Engine Build Graph Copy issue]]></title><description><![CDATA[Since there're not too much useful info in Unreal Engine documentation, I have to dig this up by myself
ERROR: Source file 'C:\workspace\Binaries\Win64\UnrealEditor.target' is not under 'C:\workspace\UnrealEngine'
       while executing task <Copy Fi...]]></description><link>https://blog.catoxliu.net/unreal-engine-build-graph-copy-issue</link><guid isPermaLink="true">https://blog.catoxliu.net/unreal-engine-build-graph-copy-issue</guid><category><![CDATA[unreal-engine]]></category><dc:creator><![CDATA[sj]]></dc:creator><pubDate>Fri, 29 Jul 2022 01:29:51 GMT</pubDate><content:encoded><![CDATA[<p>Since there're not too much useful info in <a target="_blank" href="https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/BuildTools/AutomationTool/BuildGraph/ScriptAnatomy/Tasks/">Unreal Engine documentation</a>, I have to dig this up by myself</p>
<pre><code>ERROR: Source file <span class="hljs-string">'C:\workspace\Binaries\Win64\UnrealEditor.target'</span> <span class="hljs-keyword">is</span> not under <span class="hljs-string">'C:\workspace\UnrealEngine'</span>
       <span class="hljs-keyword">while</span> executing task <span class="hljs-operator">&lt;</span>Copy Files<span class="hljs-operator">=</span><span class="hljs-string">"#InternalBinaries"</span> From<span class="hljs-operator">=</span><span class="hljs-string">"C:\workspace\UnrealEngine"</span> To<span class="hljs-operator">=</span><span class="hljs-string">"C:\workspace\UnrealEngine\LocalBuilds\ArchiveForUGS\Staging"</span> Overwrite<span class="hljs-operator">=</span><span class="hljs-string">"True"</span> ErrorIfNotFound<span class="hljs-operator">=</span><span class="hljs-string">"False"</span> <span class="hljs-operator">/</span><span class="hljs-operator">&gt;</span>
       at Engine<span class="hljs-operator">/</span>Build<span class="hljs-operator">/</span>Graph<span class="hljs-operator">/</span>Examples<span class="hljs-operator">/</span>CustomBuildEditorAndTools.xml(<span class="hljs-number">151</span>)
       (see C:\workspace\UnrealEngine\Engine\Programs\AutomationTool\Saved\Logs\Log.txt <span class="hljs-keyword">for</span> full exception trace)
</code></pre><p>So this is the line causing the error</p>
<pre><code><span class="hljs-operator">&lt;</span>Tag Files<span class="hljs-operator">=</span><span class="hljs-string">"#OutputFiles"</span> Except<span class="hljs-operator">=</span><span class="hljs-string">".../Intermediate/..."</span> With<span class="hljs-operator">=</span><span class="hljs-string">"#ArchiveFiles"</span><span class="hljs-operator">/</span><span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span>Tag Files<span class="hljs-operator">=</span><span class="hljs-string">"#ArchiveFiles"</span> Except<span class="hljs-operator">=</span><span class="hljs-string">"*.pdb"</span> With<span class="hljs-operator">=</span><span class="hljs-string">"#ArchiveBinaries"</span><span class="hljs-operator">/</span><span class="hljs-operator">&gt;</span>
<span class="hljs-operator">&lt;</span>Copy Files<span class="hljs-operator">=</span><span class="hljs-string">"#ArchiveBinaries"</span> From<span class="hljs-operator">=</span><span class="hljs-string">"$(RootDir)"</span> To<span class="hljs-operator">=</span><span class="hljs-string">"$(ArchiveStagingDir)"</span><span class="hljs-operator">/</span><span class="hljs-operator">&gt;</span>
</code></pre><p>The <code>#ArchiveBinaries</code> are simply all the filtered files output from the compiling. <code>$(RootDir)</code> is the engine folder (C:\workspace\UnrealEngine) and <code>$(ArchiveStagingDir)</code> is some target folder that doesn't matter. The copy should remain the relative strcutre here, saying <code>C:\workspace\path\to\file</code> should be copied to <code>$(ArchiveStagingDir)\path\to\file</code></p>
<p>And the error is basically saying that some files is not under the <code>RootDir</code> and can't be copied with relative structure remaining, which makes sense, because you can't have something like <code>$(ArchiveStagingDir)\..\path\to\file</code>.</p>
<p>And the reason why we get files not under the <code>RootDir</code> is simple, because we don't put our game folder as a subfolder of Unreal Engine source. Once the reason is clear, the solution is simple and straight forward:</p>
<pre><code>&lt;<span class="hljs-keyword">Option</span> <span class="hljs-type">Name</span>="MyRootDir" DefaultValue="$(RootDir)\..\" Description ="The root dirctory contain both Engine and Game folders"/&gt;
&lt;<span class="hljs-keyword">Copy</span> Files="#ArchiveBinaries" <span class="hljs-keyword">From</span>="$(MyRootDir)" <span class="hljs-keyword">To</span>="$(ArchiveStagingDir)"/&gt;
</code></pre><p>What we learn today, Unreal want you to put your game under Engine folder if you use the source code, but you can choose to not listen to them :)</p>
]]></content:encoded></item><item><title><![CDATA[auto and auto& nightmare]]></title><description><![CDATA[I'm new to Unreal Engine editor, and I have the task to add some customer menu into an existing context menu. So I look at some docs and read the source code, with new UE5, it's pretty simple and straight forward
UToolMenu* SourceControlMenu = UToolM...]]></description><link>https://blog.catoxliu.net/auto-and-auto-reference-nightmare</link><guid isPermaLink="true">https://blog.catoxliu.net/auto-and-auto-reference-nightmare</guid><category><![CDATA[C++]]></category><category><![CDATA[unreal-engine]]></category><dc:creator><![CDATA[sj]]></dc:creator><pubDate>Fri, 29 Jul 2022 01:01:17 GMT</pubDate><content:encoded><![CDATA[<p>I'm new to Unreal Engine editor, and I have the task to add some customer menu into an existing context menu. So I look at some docs and read the source code, with new UE5, it's pretty simple and straight forward</p>
<pre><code>UToolMenu<span class="hljs-operator">*</span> SourceControlMenu <span class="hljs-operator">=</span> UToolMenus::Get()<span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span>ExtendMenu(<span class="hljs-string">"ID_OF_MENU"</span>);
FToolMenuSection<span class="hljs-operator">&amp;</span> Section <span class="hljs-operator">=</span> SourceControlMenu<span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span>AddSection(<span class="hljs-string">"MySection"</span>);
Section.AddEntry(<span class="hljs-comment">//my custom menu here//);</span>
</code></pre><p>So I jump to this work and made the first mistake, I didn't copy paste code and think I'm smart to ignore unreal style guide to just do it in my way.</p>
<pre><code>auto SourceControlMenu <span class="hljs-operator">=</span> UToolMenus::Get()<span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span>ExtendMenu(<span class="hljs-string">"ID_OF_MENU"</span>);
auto Section <span class="hljs-operator">=</span> SourceControlMenu<span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span>AddSection(<span class="hljs-string">"MySection"</span>);
Section.AddEntry(<span class="hljs-comment">//my custom menu here//);</span>
</code></pre><p>Compile it, pass in the first try, and run it, breakpoint hitted, it runs my code correctly without any issues, cool, seems work done.</p>
<p>But wait, where is my menu, it's not showing up on the UI. What's going wrong here?</p>
<p>...</p>
<p>After a bad sleep following several hours debugging, searching and asking around online and pulling my hairs, I just realise it's a so simple mistake I'm making here.
Looking at the function again</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">FToolMenuSection</span></span>;
FToolMenuSection&amp; UToolMenu::AddSection(...)
</code></pre><p>So the return type is a reference, and since it's a struct, then you can implicitly copy the value through a struct reference, so what I'm doing there is making a copy of the section.</p>
<p>I know this is not right to some people, as I quote "I would totally expect the auto to be of the same type of the return type i.e. a reference to FToolMenuSection" (Maybe that's why Unreal suggest to not use auto if possible)</p>
<p>To make it clear:</p>
<pre><code>FToolMenuSection<span class="hljs-operator">&amp;</span> OriginSection <span class="hljs-operator">=</span> SourceControlMenu<span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span>AddSection(<span class="hljs-string">"MySection"</span>);
auto CopiedSection <span class="hljs-operator">=</span> OriginSection; <span class="hljs-comment">//it's not the original section.</span>
<span class="hljs-comment">// Type of OriginSection is FToolMenuSection&amp;</span>
<span class="hljs-comment">// Type of CopiedSection is FToolMenuSection</span>
</code></pre><p>So I'm adding my custom menu into a local variable section which is disposed right after my function... </p>
<p>Besides the mistake I made here, is there a way to protect us from this? yes, there is, you can explicitly delete the constructor of copying from reference</p>
<pre><code><span class="hljs-keyword">struct</span> <span class="hljs-title">FToolMenuSection</span>
{
   FToolMenuSection(FToolMenuSection<span class="hljs-operator">&amp;</span> ) <span class="hljs-operator">=</span> <span class="hljs-keyword">delete</span>;
   FToolMenuSection(FToolMenuSection<span class="hljs-operator">&amp;</span><span class="hljs-operator">&amp;</span> ) <span class="hljs-operator">=</span> <span class="hljs-keyword">delete</span>;
}
FToolMenuSection<span class="hljs-operator">&amp;</span> OriginSection <span class="hljs-operator">=</span> SourceControlMenu<span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span>AddSection(<span class="hljs-string">"MySection"</span>);
auto CopiedSection <span class="hljs-operator">=</span> OriginSection; <span class="hljs-comment">//compiler errors here, don't know how to copy from a reference here</span>
</code></pre><p>And I tried to do this for Unreal Editor, but can't. Since in the TArray implementation, they need insert fucntion working with reference which needs the copy by reference.</p>
<p>So what I learn today. Always copy paste code where you can :). And maybe follow the style guideline where you can ~</p>
]]></content:encoded></item><item><title><![CDATA[How to automatically update a "private" vscode extension]]></title><description><![CDATA[The right way is to publish it into official market, but if you can't wait or don't want to, here we go:
Generally speaking, this could be as simple as:

a regular task to check the server.
Download the extension package if newer version available.
I...]]></description><link>https://blog.catoxliu.net/how-to-automatically-update-a-private-vscode-extension</link><guid isPermaLink="true">https://blog.catoxliu.net/how-to-automatically-update-a-private-vscode-extension</guid><category><![CDATA[vscode extensions]]></category><category><![CDATA[vscode]]></category><category><![CDATA[Visual Studio Code]]></category><dc:creator><![CDATA[sj]]></dc:creator><pubDate>Tue, 10 May 2022 12:55:05 GMT</pubDate><content:encoded><![CDATA[<h3 id="heading-the-right-way-is-to-publish-it-into-official-market-but-if-you-cant-wait-or-dont-want-to-here-we-go">The right way is to publish it into official market, but if you can't wait or don't want to, here we go:</h3>
<p>Generally speaking, this could be as simple as:</p>
<ol>
<li>a regular task to check the server.</li>
<li>Download the extension package if newer version available.</li>
<li>Install that extension package.</li>
</ol>
<p>You can have all kinds of different impelementations for step 1 or 2, I wouldn't go into details here.</p>
<p>The challenge part is step 3.
Previously I just ask my colleagues to manually install the vsix file I shared with them, since it's just several simple clicks on UI. But after 3 releases (bugs/feature request) in a week, this process becomes a bit unacceptable. I have to figure out a way to upgrade it automatically to prevent the fragmentations and also make other's life a bit happier.</p>
<p><strong>So the first question is can we install it through a script/cli?</strong> Well, the answer is not that obvious to me (due to my poor google skills), but hey, vscode is opensource, all the answers are already there in the code. So I go to github and quickly go through the issues (always assume somebody else may have the very same issue before), and I find someone report a bug of this command:</p>
<pre><code>code <span class="hljs-operator">-</span><span class="hljs-operator">-</span>install<span class="hljs-operator">-</span>extension path_to_extension_vsix <span class="hljs-operator">-</span><span class="hljs-operator">-</span>force
</code></pre><p>wait, I don't know that and also, it's very clear then it's doable. Everything follows up is simple and boring:</p>
<ul>
<li>a lot more help info through <code>code --help</code>.</li>
<li>searching through the code by "install-extension"</li>
<li>ha, cli command: "<strong>workbench.extensions.installExtension</strong>" (in fact, it's right there in the <a target="_blank" href="https://code.visualstudio.com/api/references/commands">offical documentation</a> :))</li>
<li>basically just call this vs command in the extension code with the vsix file URI, it's done.</li>
</ul>
<p>Can't believe I go through such a long way (again, poor google skills), but a lot of other stuffs learnt.</p>
]]></content:encoded></item></channel></rss>