<?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:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Procedural Level]]></title><description><![CDATA[Procedural Level]]></description><link>https://blog.procedurallevel.com</link><image><url>https://blog.procedurallevel.com/img/substack.png</url><title>Procedural Level</title><link>https://blog.procedurallevel.com</link></image><generator>Substack</generator><lastBuildDate>Mon, 18 May 2026 04:54:11 GMT</lastBuildDate><atom:link href="https://blog.procedurallevel.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Łukasz]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[procedurallevel@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[procedurallevel@substack.com]]></itunes:email><itunes:name><![CDATA[Łukasz]]></itunes:name></itunes:owner><itunes:author><![CDATA[Łukasz]]></itunes:author><googleplay:owner><![CDATA[procedurallevel@substack.com]]></googleplay:owner><googleplay:email><![CDATA[procedurallevel@substack.com]]></googleplay:email><googleplay:author><![CDATA[Łukasz]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[An Attempt at Designing ImGUI with Retained UI Elements]]></title><description><![CDATA[A few iterations into this idea. Many more to go.]]></description><link>https://blog.procedurallevel.com/p/an-attempt-at-designing-imgui-with-retained-ui-elements</link><guid isPermaLink="false">https://blog.procedurallevel.com/p/an-attempt-at-designing-imgui-with-retained-ui-elements</guid><dc:creator><![CDATA[Łukasz]]></dc:creator><pubDate>Tue, 07 Apr 2026 17:50:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!VxND!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2><p>&#8203;&#9;To preface: I&#8217;m not an expert on UI. This is just a result of a search for a solution that fits my current needs and was something that I just wanted to learn and found interesting. I have about 10 years of experience with Unity3D, but I&#8217;ve never enjoyed working with its retained UI system. But I really like the ImGUI API. Custom editors are probably the best feature Unity has to offer and what kept me with the engine for all this time. But recently I&#8217;ve decided to try something new. For my current set of ideas, a custom 2D engine might be a better option. And that&#8217;s what I&#8217;m trying to do. But it also means that I need my own UI system.</p><h2>First iteration</h2><p>&#8203;&#9;My first idea was to make the UI a retained one, but declare layout and all widgets like I would with ImGUI. It was done in the constructor/init method, modified and updated in a standard event/callback flow. It was hard to work with and really slow to iterate on. Also, now that I wasn&#8217;t using Unity, I was able to use C# hotreload feature, and this approach didn&#8217;t play well with it. I&#8217;ve scrapped this idea even before I&#8217;ve used it for any real UI.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.procedurallevel.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>Second iteration</h2><p>&#8203;&#9;In the meantime, I've settled on a game idea that later turned into "Dropt". I didn't want to get stuck on iterating the UI framework, so I've picked the most primitive solution for layout you can get. Rect struct, with some helper methods like "SplitHorizontal", "AddPadding/Margin". I would hardcode my UI this way. API was simple: "draw button at rect". It worked, but there were problems.</p><p>&#8203;&#9;One of them was that for more complex layouts, I would have to know ahead of time how many widgets there were and what size they would need.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eQVJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eQVJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png 424w, https://substackcdn.com/image/fetch/$s_!eQVJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png 848w, https://substackcdn.com/image/fetch/$s_!eQVJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png 1272w, https://substackcdn.com/image/fetch/$s_!eQVJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eQVJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png" width="589" height="243" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:243,&quot;width&quot;:589,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24252,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.procedurallevel.com/i/193491574?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!eQVJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png 424w, https://substackcdn.com/image/fetch/$s_!eQVJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png 848w, https://substackcdn.com/image/fetch/$s_!eQVJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png 1272w, https://substackcdn.com/image/fetch/$s_!eQVJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fa89503-786c-41c5-b5c1-d7c1c8393fc9_589x243.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#8203;&#9;Or have a &#8220;builder&#8221; class that would try to keep track of it, but it was only good for a simple vertical/horizontal list of mostly static elements.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OPuS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OPuS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png 424w, https://substackcdn.com/image/fetch/$s_!OPuS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png 848w, https://substackcdn.com/image/fetch/$s_!OPuS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png 1272w, https://substackcdn.com/image/fetch/$s_!OPuS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OPuS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png" width="662" height="283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e767804-c894-4782-b351-17b4d8ce621b_662x283.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:283,&quot;width&quot;:662,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29222,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.procedurallevel.com/i/193491574?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OPuS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png 424w, https://substackcdn.com/image/fetch/$s_!OPuS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png 848w, https://substackcdn.com/image/fetch/$s_!OPuS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png 1272w, https://substackcdn.com/image/fetch/$s_!OPuS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e767804-c894-4782-b351-17b4d8ce621b_662x283.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>&#8203;&#9;Another issue was, for example, drawing background frames. I could use depth buffer to mostly solve this, but it then introduced a different kind of complexity, of managing z-index for each element, which I didn&#8217;t really want to deal with. This was meant to be a simple UI system. </p><p>&#8203;&#9;But it worked, I&#8217;ve created every panel I wanted this way. It mostly worked with hot reload, which greatly increased my iteration speed. I didn&#8217;t have to recompile and restart the game each time I wanted to adjust some button position or padding. It started falling apart when I started working on Rogue-like elements of gameplay. &#8220;Luckily&#8221;, I&#8217;ve cut that part of the game as it wasn&#8217;t fun, but it pushed me towards thinking about a better UI solution.</p><h2>Third iteration</h2><p>&#8203;&#9;My current idea is to try to mimic the &#8220;GUILayout&#8221; API of Unity, with some simplifications/changes. I need to be able to put objects in vertical/horizontal lines. I want to be able to either assign a static size to an element or make it flexible. And that covers all the layout needs that I have. It reuses layout objects, so there is no memory allocation, and calculations are rather simple, so there isn&#8217;t much overhead on this. It will first calculate the layout, then draw each object in order, so it solves the problem of backgrounds. Elements with static size will stretch with children, as this is the behaviour that I need most of the time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VxND!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VxND!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png 424w, https://substackcdn.com/image/fetch/$s_!VxND!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png 848w, https://substackcdn.com/image/fetch/$s_!VxND!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png 1272w, https://substackcdn.com/image/fetch/$s_!VxND!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VxND!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png" width="837" height="357" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:357,&quot;width&quot;:837,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:37586,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.procedurallevel.com/i/193491574?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VxND!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png 424w, https://substackcdn.com/image/fetch/$s_!VxND!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png 848w, https://substackcdn.com/image/fetch/$s_!VxND!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png 1272w, https://substackcdn.com/image/fetch/$s_!VxND!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6eff75a-168c-421a-b62f-3e1f3f282210_837x357.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zOd7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zOd7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png 424w, https://substackcdn.com/image/fetch/$s_!zOd7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png 848w, https://substackcdn.com/image/fetch/$s_!zOd7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png 1272w, https://substackcdn.com/image/fetch/$s_!zOd7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zOd7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png" width="607" height="341" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:341,&quot;width&quot;:607,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:26771,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.procedurallevel.com/i/193491574?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zOd7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png 424w, https://substackcdn.com/image/fetch/$s_!zOd7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png 848w, https://substackcdn.com/image/fetch/$s_!zOd7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png 1272w, https://substackcdn.com/image/fetch/$s_!zOd7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f5262cc-b451-493a-ab27-87e9560a7f30_607x341.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Nested UI Elements</h2><p>&#8203;&#9;But this is still a work in progress. For example, to draw multiple UI objects in the same layout element, I would either have to create a separate class that implements UI related interface, or split it into 2 methods like below. BuildLayout prepares the layout and ensures that the parent object knows how much space it will take. Draw method then uses that layout to draw elements. This is something that I don't like and is something that I need to improve for the next iteration. But I've ported all of the UI in my current project to this layout approach, and it seems to fit my needs better than previous iterations.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i2gX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i2gX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png 424w, https://substackcdn.com/image/fetch/$s_!i2gX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png 848w, https://substackcdn.com/image/fetch/$s_!i2gX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png 1272w, https://substackcdn.com/image/fetch/$s_!i2gX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i2gX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png" width="625" height="665" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:665,&quot;width&quot;:625,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75568,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.procedurallevel.com/i/193491574?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!i2gX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png 424w, https://substackcdn.com/image/fetch/$s_!i2gX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png 848w, https://substackcdn.com/image/fetch/$s_!i2gX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png 1272w, https://substackcdn.com/image/fetch/$s_!i2gX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0bc1d81-8d27-4bf3-b485-a1dd00cc2a6d_625x665.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.procedurallevel.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>