{"id":1914,"date":"2026-10-03T12:35:42","date_gmt":"2026-10-03T10:35:42","guid":{"rendered":"https:\/\/stuff.tamius.net\/sacred-texts\/?p=1914"},"modified":"2026-10-03T12:46:32","modified_gmt":"2026-10-03T10:46:32","slug":"vibe-coding-adventure-ii-2-vibe-2-code","status":"publish","type":"post","link":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/","title":{"rendered":"Vibe Coding Adventure II: 2 Vibe 2 Code"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Here&#8217;s the TL;DR:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Claude\/Sonnet 5 good<\/li>\n\n\n\n<li>VS Copilot is meh (unless it routes you to Sonnet)<\/li>\n\n\n\n<li>During this entire debacle, it turned out that some of the assumptions I&#8217;ve made in my &#8220;how to print your game character&#8221; tutorial aren&#8217;t exactly correct<\/li>\n\n\n\n<li>I still write my blog posts myself, btw<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Other important stuff<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This blog post is about tools that extract assets from video games. Note that use of such tools may be prohibited by your game&#8217;s EULA and can result in a game ban. Usage of the tools mentioned in this post is <strong>only<\/strong> <strong>intended with games that allow you to use their content <\/strong>in their EULAs, Content Terms of Use (aka Fan use policies), other applicable policies and laws, and <strong>only within the limits outlined in said policies.<\/strong> <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Extracting game assets from games without permission of the game owners very likely constitutes copyright infringement and is therefore illegal.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">The last time I tried vibe coding, I didn&#8217;t exactly find the whole experience very comfortable. To keep the story short, the important takeaway is that I felt that I wasted just as much time as I saved. But then again, given I was using ChatGPT, it&#8217;s not like I was using the best tool for the job.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fast forward some time, and the world has changed. I feel it in the Intel GPA depreciation notice (which states Intel GPA download page is gonna be taken offline 6 months ago, but seems that Intel &#8220;kinda forgot\u2122&#8221; <sup id=\"mfn-content-00000000000004b60000000000000000_1914-1\" class=\"modern-footnotes-footnote modern-footnotes-footnote--expands-on-desktop \" data-mfn=\"1\" data-mfn-post-scope=\"00000000000004b60000000000000000_1914\"><a href=\"javascript:void(0)\"  title=\"Though fortunately, final version of Intel GPA was archived on the Internet Archive\"  role=\"button\" aria-pressed=\"false\" aria-describedby=\"mfn-content-00000000000004b60000000000000000_1914-1\">1<\/a><\/sup><span role=\"tooltip\" class=\"modern-footnotes-footnote__note\" tabindex=\"0\" data-mfn=\"1\">Though fortunately, final version of Intel GPA was archived on the Internet Archive<\/span>). I can feel it in my OS. I can&#8217;t smell it in the air because I moved from Windows to Linux. This leaves me in a rather similar spot as I was in the last time I went for vibe coding.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The problem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Intel GPA, being a Windows program that does very low-level stuff with your GPU, isn&#8217;t exactly going to run on Linux. Fortunately, Intel GPA isn&#8217;t the only suite that can be used for extracting 3D models from games. RenderDoc, being free and open source, can do many of the same things Intel GPA could (at least in theory), and it also runs on Linux. In practice, though, RenderDoc is a massive downgrade from Intel GPA for my purpose. Natively, it cannot export meshes in a blender-ready format, and forget about exporting more than 1 posed mesh in one go. It is also incredibly, super ultra SLOW &#8230; at least compared to Intel GPA, and a lot less user-friendly. Getting to the meshes I wanted was a lot more difficult and involved than with Intel GPA. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fortunately, RenderDoc has python plugins. I hoped I&#8217;d manage to dodge the fun time by going to the friendly local search engine and looked for anyone who came before. Initially, research seemed at least somewhat promising. I found two things:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>someone made an addon for ripping 3D models from Google Maps in Google Chrome<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/rrtt2323\/RenderdocResourceExporter\">Renderdoc Resource Exporter<\/a>, which allegedly gives you a handy option to export meshes as <code>.fbx<\/code> <\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">I initially thought I could get away with the Google Maps export plugin. Github page said it only works with Google Chrome + Google Maps, but I mean &#8230; surely I can misuse it for exporting meshes from other programs, too? After all, draw calls are the same no matter the program, right? <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Yeah, of course not. If the capture you tried to export wasn&#8217;t Google Maps in Google Chrome, the plugin would give a &#8220;this isn&#8217;t google maps in google chrome&#8221; error and refuse to do shit. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As for Renderdoc Resource Exporter &#8230; Let&#8217;s just say that in programmer circles, &#8220;python script&#8221; is well-known for being a shorthand for &#8220;three <code>exe<\/code>s in a trenchcoat<sup id=\"mfn-content-00000000000004b60000000000000000_1914-2\" class=\"modern-footnotes-footnote modern-footnotes-footnote--expands-on-desktop \" data-mfn=\"2\" data-mfn-post-scope=\"00000000000004b60000000000000000_1914\"><a href=\"javascript:void(0)\"  title=\"Often it&#8217;s not a literal .exe, given that many python libraries come in Linux and Mac editions, but it is a compiled executable of a program written in a real programming language. However, I&#8217;m playing the &#8220;artistic license&#8221; card on this one for entertainment reasons.\"  role=\"button\" aria-pressed=\"false\" aria-describedby=\"mfn-content-00000000000004b60000000000000000_1914-2\">2<\/a><\/sup><span role=\"tooltip\" class=\"modern-footnotes-footnote__note\" tabindex=\"0\" data-mfn=\"2\">Often it&#8217;s not a literal <code>.exe<\/code>, given that many python libraries come in Linux and Mac editions, but it is a compiled executable of a program written in a real programming language. However, I&#8217;m playing the &#8220;artistic license&#8221; card on this one for entertainment reasons.<\/span>&#8220;, and that&#8217;s kinda what&#8217;s going on with this extension. FBX exporter is written in C++ and provided as  a bunch of <code>exe<\/code>s and <code>dll<\/code>s, which are no good on Linux.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Where does that leave us? In a spot where the thing I want doesn&#8217;t exist. If I want it, I&#8217;ll have to make it &#8230; except that I don&#8217;t want to spend the months actually making it. Seriously, it&#8217;s the kind of thing I&#8217;m gonna be using maybe thrice a year. I&#8217;ve consulted that XKCD table and came to a conclusion: spending 3 months (minimum) making something that can be solved in 3 minutes by booting into Windows doesn&#8217;t exactly math out.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"832\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika-1024x832.png\" alt=\"slika\" class=\"wp-image-1916\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika-1024x832.png 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika-300x244.png 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika-768x624.png 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika-1052x855.png 1052w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika.png 1141w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">XKCD <a href=\"https:\/\/xkcd.com\/1205\/\">source<\/a>.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Fortunately, we have friends.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Claude, round 1: Let&#8217;s roll our own parser<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There are three things you need to know about RenderDoc: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li> <code>.rdc<\/code> files aren&#8217;t cross-platform. If you captured a scene on nVidia GPU, you can&#8217;t open it on AMD GPUs, and if you captured a scene on Linux, you can&#8217;t open that on Windows (and vice-versa). <\/li>\n\n\n\n<li>On Linux, you don&#8217;t need to open RenderDoc in order to do game captures. You can just do:<br><code>sudo renderdoccmd vulkanlayer --register --system<br>ENABLE_VULKAN_RENDERDOC_CAPTURE=1 steam<\/code><br>in the scary black box, which is a lot faster than trying to launch software through Renderdoc&#8217;s UI. <\/li>\n\n\n\n<li>RenderDoc doesn&#8217;t do xdg-desktop-portal, and it&#8217;s default file picker is not only complete and utter garbage with none of the creature comforts KDE&#8217;s and even Gnome&#8217;s file pickers offer, but it does the retarded &#8220;click once to open folder \/ choose file&#8221; thing that Dolphin on KDE used to do 10 years ago. What the actual fuck? <\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Needless to say, my first thought was: &#8220;can I make a webpage that takes a <code>.rdc<\/code> file and renders out the scene, so I can just click on the objects that I want and export them&#8221;?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The answer to that question is no.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8230; <em>buuuut <\/em>if you&#8217;re gucci with running <code>renderdoccmd convert -f capture.rdc -o capture.zip.xml -c zip.xml<\/code> in the scary black hacker box, that gives you two files that you can write a parser for, so I decide to send Claude down that route. Not too long after I had a web page that I could parse <code>XML+ZIP<\/code> &#8230; in theory. In practice, I ran into browser limitations really really fast.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Turns out <code>XML + ZIP<\/code> option gives you an XML file that weighs couple hundred megs \u2014 sometimes almost north of a gig \u2014 and that&#8217;s even for fairly old games like Guild Wars 2. Accompanying <code>zip<\/code> file is even larger, typically measured in gigabytes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Guess who outright refuses to work with XML files this big? Google Chrome (though VSCode copilot eventually managed to find a workaround).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Another thing that wasn&#8217;t happening was trying to open that <code>.zip<\/code>. Loading the entire <code>zip<\/code> inside the browser was a very quick and easy way to run into &#8220;whoopsie daisy, ate all the ram&#8221; issues. When I pointed that out, Claude fixed the issue by not reading the entire <code>.zip<\/code> at once. Would it surprise you if I told you that this merely traded one kind of &#8220;broken, doesn&#8217;t work&#8221; for a different kind of &#8220;broken, doesn&#8217;t work?&#8221; Because after that fix, no draw calls would be loaded successfully. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, I&#8217;m not blaming Claude for this issue. After all, it was me who decided to go for a browser-based solution, even though it&#8217;s by far not the correct tool for the job. But that doesn&#8217;t change the fact that this option isn&#8217;t working out, so let&#8217;s cut the losses and move on to the approach that was the obvious winner from the start.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Claude, round 2: RenderDoc addon<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This part was incredibly smooth. I asked to export all meshes and textures into a folder of my choosing. I got a script that popped open a file chooser, and then exported all meshes and textures. Of course, that was only source geometry, but I wanted posed meshes. I go back to Claude and explain that I want posed meshes. Extension now exports both posed meshes and source geometry. And textures.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At this point, we have more-than parity with our old Intel GPA workflow. But we can go further.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We could export texture mapping, so our exported meshes are perfectly textured out of the box. I ask. I receive a bunch of <code>.mtl<\/code> files next to the <code>.obj<\/code>s.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Neat. But we can still go further.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Posed meshes from world space are squished. It would be really neat if we could undo that in the extension.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Claude made an effort, which improved things over exporting meshes as-is. The models now no longer look as if someone went over them with a 100 ton steamroller. However, they&#8217;re still not very on-point \u2014 for example, the following should be a square\/box:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2463\" height=\"1527\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/squish.avif\" alt=\"squish\" class=\"wp-image-1918\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/squish.avif 2463w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/squish-300x186.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/squish-1024x635.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/squish-768x476.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/squish-1536x952.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/squish-2048x1270.avif 2048w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/squish-1140x707.avif 1140w\" sizes=\"auto, (max-width: 2463px) 100vw, 2463px\" \/><figcaption class=\"wp-element-caption\">That&#8217;s not quite a square now, is it?<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">But that&#8217;s just minor details. It&#8217;s entirely possible that RenderDoc doesn&#8217;t expose all the necessary details. It&#8217;s entirely possible that Claude is lying. In any case, we already have a tool that fixes this problem (remember the previous vibe coding challenge), plus the vibe coding experience has been pretty smooth (except for the part where we&#8217;re blowing through free tier limits like a speed demon). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, that skybox didn&#8217;t stay nice and blue forever. I was initially testing RenderDoc addon with a capture of the Guild Wars 2 character selection screen, which is extremely light as far as captures go. The moment I tried loading and exporting a bigger, more real-world-scenario capture, a new problem appeared.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Turns out that exporting meshes from RenderDoc is really, <em>REALLY <\/em>slow. Export was happening at 1-2 draw calls per second. This is a problem because your average capture has thousands of draw calls, even for games from early 2010&#8217;s. Do the math.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We <strong>have <\/strong>to go further.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Under the hood, modern games tend to render each frame way more than once. If you export all the draw calls that happened, you get with multiple instances of same mesh\/object in the scene, often overlapping. That&#8217;s undesirable even on a good day, but now that it costs us significant amount, something needs to be done.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So I consult with Claude and tell it to detect different passes, as well as the purpose of each pass. Claude comes back with an answer.<\/p>\n\n\n\n<figure class=\"wp-block-image alignwide size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2003\" height=\"1146\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/export.avif\" alt=\"export\" class=\"wp-image-1919\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/export.avif 2003w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/export-300x172.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/export-1024x586.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/export-768x439.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/export-1536x879.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/export-1140x652.avif 1140w\" sizes=\"auto, (max-width: 2003px) 100vw, 2003px\" \/><figcaption class=\"wp-element-caption\">Not the nicest UI, but it&#8217;s functional and that&#8217;s what matters.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Claude detects different passes like magic. I specify which boxes need to be checked by default, and the extension is more or less done. Yay.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But I want more.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Claude, round 3: let&#8217;s re-do the Intel GPA squish calculator<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There&#8217;s a problem with dumping game meshes that we haven&#8217;t mentioned yet. Different game engines tend to have wildly different approaches to scale.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In Godot, Unity, and Minecraft, and Blender, 1 unit is 1 meter. In Unreal and Maya, 1 unit is 1 centimeter. And then you have special snowflake engines like Source, where 1 hammer unit is 1\/16 of a foot, and Guild Wars 2 where 1 unit is 1 inch (<em>allegedly according to reddit, <\/em>but the math checks out. Pre-transform\/pre-pose meshes of my character come out to about 3 meters tall with this math, which checks out with the final napkin math I did for the <a href=\"https:\/\/stuff.tamius.net\/sacred-texts\/2023\/08\/30\/the-charr-cosplay-the-matter-of-size\/\">still-ongoing charr cosplay project<\/a>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These discrepancies can cause issues when we simply dump exported objects into modeling software of choice and try to locate our meshes.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1057\" height=\"617\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/blender-clip-distance.avif\" alt=\"blender-clip-distance\" class=\"wp-image-1924\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/blender-clip-distance.avif 1057w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/blender-clip-distance-300x175.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/blender-clip-distance-1024x598.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/blender-clip-distance-768x448.avif 768w\" sizes=\"auto, (max-width: 1057px) 100vw, 1057px\" \/><figcaption class=\"wp-element-caption\">Distant objects vanish.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Combined with the fact that we often don&#8217;t actually need or want the entire scene for whatever we&#8217;re doing, it would be really nice to have a program that can clean-up the capture or fix a few issues that we know our capture has.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So here&#8217;s the feature list that we want from our app:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>it needs to ensure captured scenes get resized to a reasonable size if they&#8217;re too small<\/li>\n\n\n\n<li>3D scene should be navigable<\/li>\n\n\n\n<li>we want the ability to filter out meshes we aren&#8217;t interested in<\/li>\n\n\n\n<li>we want to port over the de-squish logic from <a href=\"https:\/\/tamius-han.github.io\/intel-gpa-squish-calculator\/\">Intel GPA squish calculator<\/a><\/li>\n\n\n\n<li>we want the ability to pick a landmark in our app, instead of in advance when exporting meshes. Picking a landmark should also automatically de-squish the entire capture, based on the difference in size between the original and posed post-transform models.<br>(Admittedly, this is potentially not going to work. So far, I&#8217;m making an assumption that squishing is linear. However, objects closer to the camera might be squished by a different amount than objects further away from the camera. If that&#8217;s the case, this isn&#8217;t gonna work &#8230; and Claude does say this is the case)<\/li>\n\n\n\n<li>we want everything to be convenient. We should select objects by clicking.<\/li>\n\n\n\n<li>whatever other feature turns out to be needed in order for (relatively) moron-friendly UX<\/li>\n<\/ul>\n\n\n\n<p class=\"alignfull wp-block-paragraph\">So I start prompting away. Things started promising. I soon had a basic 3D renderer that would accept a folder and draw the scene, with all the textures properly imported and mapped to the models. I had a filter that filters out skyboxes and large pieces of terrain. I had blender-like navigation with the mouse. I had free-fly camera. I had a switch that allows people to switch to the much inferior WASD control scheme, because at the end of the day &#8230; this is gonna live on my github.<\/p>\n\n\n\n<figure class=\"wp-block-image alignfull size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1311\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/fixer_v1-scaled.avif\" alt=\"fixer_v1\" class=\"wp-image-1925\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/fixer_v1-scaled.avif 2560w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/fixer_v1-300x154.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/fixer_v1-1024x524.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/fixer_v1-768x393.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/fixer_v1-1536x787.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/fixer_v1-2048x1049.avif 2048w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/fixer_v1-1140x584.avif 1140w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><figcaption class=\"wp-element-caption\">The state of the project.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">But that&#8217;s as far as I got on the easy mode, because slowly but surely the problems started popping up. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first problem was that as the project was becoming larger, I was blowing through the limits of Claude free tier faster and faster \u2014 more and more often, with a single prompt. Some tasks took multiple usage limit windows to finish.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Though a part of the issue was that I kept reusing existing chat for too long before moving on. Longer chat history makes you run through your token allotments a lot faster.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Now, I do understand that I can&#8217;t really complain about these kinds of things when I&#8217;m freeloading, but it was still annoying me nonetheless. But then I remembered &#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Hey. vscode has copilot, and copilot can theoretically also do this.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So I started using copilot while Claude was on cooldown, and that&#8217;s about where this adventure started to more closely resemble the first one. Because boy, copilot is quite noticeably worse than Claude &#8230; even if you pull out your credit card for Copilot Pro (which I got purely because I think inline suggestions are incredibly nice).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Perhaps the easiest way to demonstrate this is the resources panel I added to the project. I gave a prompt to copilot: I want the object preview to be this big, and I want the texture preview to be this tall, and I want two markers in each corner to make it resizable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With copilot, object preview often wasn&#8217;t visible inside the box, because the camera was looking somewhere random. The preview also wasn&#8217;t resizing with the window, and it wasn&#8217;t as big as I specified. Same story for the textures, which weren&#8217;t loading until I did some manual digging.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With Claude, same prompt ended up giving me mostly what I wanted in one shot (though I was spamming &#8220;continue&#8221; once every 5 hours for a day and a half). <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"539\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/resource-panel-1024x539.avif\" alt=\"resource panel\" class=\"wp-image-1927\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/resource-panel-1024x539.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/resource-panel-300x158.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/resource-panel-768x404.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/resource-panel-1536x808.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/resource-panel-1140x600.avif 1140w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/resource-panel.avif 1810w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Resource panel<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">There are a few things that Claude didn&#8217;t quite get first try that you can&#8217;t see because the image isn&#8217;t interactive, but hey. Result is a lot better.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Similar story happened with the camera panning and orbiting. I decided that orbiting should work more like it does in Plasticity, where pivot for zooming and orbiting is the object under your mouse, and not a 3D cursor you never bother to set. Prompting VSCode&#8217;s chat just burned through the credits without giving me the result I want. Same prompt in Claude? It took a day and a half, but I got what I wanted.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, despite the issues so far, I don&#8217;t actually think this project is going bad. I think I&#8217;m having a relatively good time. Much better than the last time, even. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And I know this project is a few features away from being complete, but &#8230; all this time, I&#8217;ve been doing my test and imports with Guild Wars 2. Let&#8217;s &#8230; let&#8217;s try to use it with a capture from a game that isn&#8217;t 15 years old.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So I disable wayland on Blades of Greed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I launch Styx: Blades of Greed. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I do a capture or two.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I exit Blades of Greed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I open Renderdoc and try to load the capture.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And that&#8217;s where a brand new rounds of problems started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Oops, it&#8217;s all crashes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When I tried to load the capture, Renderdoc reacted in one of three ways:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Error popup that said &#8220;oopsie whoopsie, VULKAN_NO_MEMORY_ERROR_SOMETHING&#8221;<\/li>\n\n\n\n<li>Error popup that said something along the lines of &#8220;this opaque address was this, but now it&#8217;s this and that&#8217;s illegal&#8221;<\/li>\n\n\n\n<li>crash with no errors<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The only fix for the first one is getting a GPU with more VRAM, and re-doing the capture on that card. The only fix for the second is re-doing the capture, preferably after a reboot, and hoping things are gucci on your next attempt. The only way to fix the third is to try again, and hope the luck is on your side this time around.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Okay, there&#8217;s actually a secret fourth option. Remember the <code>XML + ZIP<\/code> thing from earlier? I did. I also remembered that I have 1500 credits on Copilot Pro.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So I try for the second time, and 60% of my credit limit later, I end up here:<\/p>\n\n\n\n<figure class=\"wp-block-image alignfull size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2552\" height=\"1287\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/xmlzip.avif\" alt=\"xmlzip\" class=\"wp-image-1929\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/xmlzip.avif 2552w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/xmlzip-300x151.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/xmlzip-1024x516.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/xmlzip-768x387.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/xmlzip-1536x775.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/xmlzip-2048x1033.avif 2048w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/xmlzip-1140x575.avif 1140w\" sizes=\"auto, (max-width: 2552px) 100vw, 2552px\" \/><figcaption class=\"wp-element-caption\">I did briefly consider doing the XML+ZIP importer on the new project, but my better judgment said that the work should be done on the old project. After all, I don&#8217;t exactly want my decisions to end with the currently working project being broken.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;m not getting any textures, and I&#8217;m not getting any world-space meshes with poses applied. But I am getting all the source meshes, which means that the things have moved ahead from where they were. Unfortunately, that&#8217;s also about how far things got, so I decided it&#8217;s time to stop wasting time and tokens and call it the night.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The next day, CachyOS updater said there&#8217;s updates. After updates, the updater said reboot is recommended. So I did just that. After reboot, just for shits and giggles, I tried to capture Blades of Greed again. I launch the game, do a few captures in main menu and inside the game, and then quit. I try to load the captures in Renderdoc &#8230; and this time, they <em>do <\/em>open just fine. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Huh.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But opening the capture is only half the battle. Let&#8217;s try exporting it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1072\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/cutoff_dialog-scaled.avif\" alt=\"cutoff_dialog\" class=\"wp-image-1930\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/cutoff_dialog-scaled.avif 2560w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/cutoff_dialog-300x126.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/cutoff_dialog-1024x429.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/cutoff_dialog-768x322.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/cutoff_dialog-1536x643.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/cutoff_dialog-2048x858.avif 2048w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/cutoff_dialog-1140x477.avif 1140w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><figcaption class=\"wp-element-caption\">Yeah, modern unreal games have A LOT of passes.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Well that&#8217;s a problem. The list of passes is so long that the dialog cannot fit on the monitor anymore. The extension thus gets a few additional export options. Namely, option that only shows &#8220;forward&#8221; passes, and another option that hides all the post-processing passes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, exporting all the forward options still yields no objects that would resemble a goblin. After a quick search, I get told that modern game engines resemble Utah police a bit, in the sense that they do things differently. If I want to get geometry, I should be looking at gbuffer passes, apparently. The only problem with this is that g-buffer passes don&#8217;t contain nowhere as many draw calls as I would expect \u2014 and to be completely honest, draw call counts seem pretty low across the board. So I ask copilot, and copilot gives an answer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I reload the addon in Renderdoc and hit export.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Renderdoc crashes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I rollback the addon to the last version that I know for sure worked, and try exporting again.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Renderdoc crashes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I open Renderdoc again and try to re-export a GW2 capture that I successfully exported with the last known-to-work version of the addon.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Renderdoc crashes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I really don&#8217;t appreciate finding out that stuff I use is susceptible to the software equivalent of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tin_pest\">tin pest<\/a>, where stuff works without problems until you get a crash, which retroactively breaks everything.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But the more I try to figure out what&#8217;s going on, the more it seems that the crashes are RenderDoc quirk. According to the logs, crashing appears to be pretty random. If I litter my code with debug <code>print<\/code> statement, the final line before the crash differs from run to run &#8230; although the variability might also be due to the fact that <code>print<\/code> command doesn&#8217;t flush the logs to disk right away.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With nothing much to be done, it&#8217;s time to move on.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Correcting the squish<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Remember when earlier, I said:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<ul class=\"wp-block-list\">\n<li>we want the ability to pick a landmark in our app, instead of in advance when exporting meshes. Picking a landmark should also automatically de-squish the entire capture, based on the difference in size between the original and posed post-transform models.<br>(Admittedly, this is potentially not going to work. So far, I&#8217;m making an assumption that squishing is linear. However, objects closer to the camera might be squished by a different amount than objects further away from the camera. If that&#8217;s the case, this isn&#8217;t gonna work &#8230; and Claude does say this is the case)<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">So basically, here&#8217;s what this means. When you export meshes from the game, they&#8217;re squished. For example, in the following screenshot, you can see that the post-transform crate is pretty crooked in comparison to the pre-transform crate in the lower left corner:<\/p>\n\n\n\n<figure class=\"wp-block-image alignwide size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2553\" height=\"1311\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/default-import.avif\" alt=\"default-import\" class=\"wp-image-1932\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/default-import.avif 2553w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/default-import-300x154.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/default-import-1024x526.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/default-import-768x394.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/default-import-1536x789.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/default-import-2048x1052.avif 2048w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/default-import-1140x585.avif 1140w\" sizes=\"auto, (max-width: 2553px) 100vw, 2553px\" \/><figcaption class=\"wp-element-caption\">According to the preview, this should be a cube &#8230; but it isn&#8217;t.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In the &#8220;3D print your game character&#8221; tutorial, I basically said that you undo this squish by: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>scaling object&#8217;s width by your monitor&#8217;s aspect ratio<\/li>\n\n\n\n<li>scaling object&#8217;s depth by [eyeball something]<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Intel GPA squish fixer replaced &#8220;eyeball something&#8221; by comparing width, height, and depth of the pre-transform and post-transform objects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This looked correct when I eyeballed stuff, and I assumed that this means that once you calculate squish factors for one object in the scene, these squish factors are correct for all the objects in the scene. Unfortunately, &#8220;looks correct&#8221; often means &#8220;slightly wrong,&#8221; and if you scale the entire scene by squish factors of your landmark, then the further from your landmark you get, the more squished the objects become.<\/p>\n\n\n\n<figure class=\"wp-block-image alignfull size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1389\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-progressive-scaled.avif\" alt=\"crate-distort-progressive\" class=\"wp-image-1933\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-progressive-scaled.avif 2560w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-progressive-300x163.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-progressive-1024x556.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-progressive-768x417.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-progressive-1536x833.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-progressive-2048x1111.avif 2048w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-progressive-1140x618.avif 1140w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><figcaption class=\"wp-element-caption\">Landmark cube is on point. Benchmark cubes get less cube-y the farther you get from the landmark, even though they should all be the same.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In retrospect, the fact that the previous approach isn&#8217;t gonna work should be pretty obvious from the get go. You can&#8217;t bring TRS to a perspective matrix job. But to be fair to me &#8230; there&#8217;s historical reasons.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">History of me extracting meshes from GW2<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First tutorial <em>did <\/em>mention you need a matrix transform to undo a perspective matrix transform. <\/li>\n\n\n\n<li>However, manually undoing perspective transform with Blender&#8217;s lattice modifier requires a lot of eyeballing and therefore produces bad results<\/li>\n\n\n\n<li>Intel GPA squish calculator initially only calculated squish factors, but didn&#8217;t fix the mesh for you. Despite not being the correct tool for the job, giving you two scaling factors for width and depth was giving more accurate mesh correction than eyeballing a lattice in Blender<\/li>\n\n\n\n<li>mesh fixing was added to Intel GPA squish calculator at a slightly later time, and by &#8220;added&#8221; I mean &#8220;merely bolted on with some duck tape&#8221;<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Anyway, now that I can see the entire scene, the inaccuracies of the previous approach bother me, so I had it done properly. Which apparently takes a bit less effort than the implementation from the previous project, too. Plus, I added a tool that allows you to define the ground plane (inital import lives in camera space, and is therefore tilted). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two more things to tick off the list.<\/p>\n\n\n\n<figure class=\"wp-block-image alignfull size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2545\" height=\"1480\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-fixed.avif\" alt=\"crate-distort-fixed\" class=\"wp-image-1934\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-fixed.avif 2545w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-fixed-300x174.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-fixed-1024x595.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-fixed-768x447.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-fixed-1536x893.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-fixed-2048x1191.avif 2048w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/crate-distort-fixed-1140x663.avif 1140w\" sizes=\"auto, (max-width: 2545px) 100vw, 2545px\" \/><figcaption class=\"wp-element-caption\">You can see that top surface of all three crates is now a perfect(-ish) square (slight crookedness due to me not nailing the viewing angle not withstanding).<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Oh no, the tokens ran out.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating the UI<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">While computer graphics is way out of my wheelhouse, web design isn&#8217;t. Between strict token limits, me having a vision, and me actually enjoying the part where I get to make the interface around the scene viewer, I obviously decided to do the UI by myself. No vibe-coding.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While claude &amp; co wouldn&#8217;t blink twice at putting all the spaghetti into a single <code>html<\/code> with a very limited number of scripts on the side,  I&#8217;ve decided that I want to split things up a bit. Because I don&#8217;t want to bring in the big guns (react, vue, angular), I decided to go with WebComponents. First impressions: they&#8217;re a wee bit more annoying than the webdev trio, but they&#8217;re okay\/10 for this project.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I ended up settling up on the simple, monospace + flat + rectangles style of UI, mostly because that combination gives you a <em>really <\/em>good combination of &#8220;looks nice&#8221; or &#8220;has a charm,&#8221; while not requiring too much effort (although I&#8217;d rather not discuss <em>that. <\/em>I still ended up spending non-negligible amount of time on getting the interface to where I wanted it to be).<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1855\" height=\"1302\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/import.avif\" alt=\"import\" class=\"wp-image-1937\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/import.avif 1855w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/import-300x211.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/import-1024x719.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/import-768x539.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/import-1536x1078.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/import-1140x800.avif 1140w\" sizes=\"auto, (max-width: 1855px) 100vw, 1855px\" \/><figcaption class=\"wp-element-caption\">&#8220;landing&#8221; page of the app.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Main app has more of them browns and flat design with sharp corners:<\/p>\n\n\n\n<figure class=\"wp-block-image alignwide size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1177\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view-scaled.avif\" alt=\"main_view\" class=\"wp-image-1942\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view-scaled.avif 2560w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view-300x138.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view-1024x471.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view-768x353.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view-1536x706.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view-2048x942.avif 2048w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view-1140x524.avif 1140w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><figcaption class=\"wp-element-caption\">The percent input was fine before the slider was made logarithmic, now it overflows. Maybe I should fix that.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The object filtering sliders are kind of a mess, especially once you click &#8216;hide flat objects&#8217; checkbox &#8230; but it&#8217;s good <em>enough.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image alignwide size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1730\" height=\"794\" src=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view_2.avif\" alt=\"main_view_2\" class=\"wp-image-1943\" srcset=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view_2.avif 1730w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view_2-300x138.avif 300w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view_2-1024x470.avif 1024w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view_2-768x352.avif 768w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view_2-1536x705.avif 1536w, https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/main_view_2-1140x523.avif 1140w\" sizes=\"auto, (max-width: 1730px) 100vw, 1730px\" \/><figcaption class=\"wp-element-caption\">Main app view, but with Intel GPA import and ground plane tool active. I also think I might be getting a bit too heavy on the avif compression slider here.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">&#8230; and so on. I&#8217;m not gonna show the export screen because it&#8217;s more of the same.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Intel GPA compatibility<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You probably owo *noticed the Intel GPA export option* over there in the UI section. Well, some time through the project I decided that if I&#8217;m<sup id=\"mfn-content-00000000000004b60000000000000000_1914-3\" class=\"modern-footnotes-footnote modern-footnotes-footnote--expands-on-desktop \" data-mfn=\"3\" data-mfn-post-scope=\"00000000000004b60000000000000000_1914\"><a href=\"javascript:void(0)\"  title=\"shut up, you know what I mean\"  role=\"button\" aria-pressed=\"false\" aria-describedby=\"mfn-content-00000000000004b60000000000000000_1914-3\">3<\/a><\/sup><span role=\"tooltip\" class=\"modern-footnotes-footnote__note\" tabindex=\"0\" data-mfn=\"3\">shut up, you know what I mean<\/span> making a better Intel GPA squish calculator, I might as well have the ability to fix Intel GPA exports within this project as well. Although, I&#8217;ve decided to change my approach.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the Intel GPA squish calculator project, I&#8217;ve decided on the following strategy:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Pick an object in your scene that will serve as your landmark, and export source geometry<\/li>\n\n\n\n<li>Add the rest of your character to your selection. Export output geometry.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">This approach had several drawbacks. Most notably, it was made with assumption that source geometry is going to be made from one (1) contiguous mesh, which wasn&#8217;t always the case and therefore wasn&#8217;t very robust. Landmark search was less than optimal as well. The code looked at how many vertices and faces the landmark has, and then tried to find something with the same number of faces and vertices in the output geometry. This wasn&#8217;t perfect, but it was good enough (as long as you didn&#8217;t forget to include landmark in your output geometry export). However, it was also very different from the approach I went with in this project. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is why this time around, the project requires three files: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>source geometry of your landmark (English subtitles: model as authored)<\/li>\n\n\n\n<li>output geometry of your landmark (English subtitles: model as seen by your GPU)<\/li>\n\n\n\n<li>output geometry of your character <\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The two landmark files are used to auto-calculate the transform matrix, which gets auto-applied to output geometry on import.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Auto-calculating and auto-fixing distortion. And also, auto-levelling<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After Intel GPA import had automatic distortion fix on import, I decided that <em>actually, I want to have this program automatically detect and correct distortion on import for RenderDoc exports as well. <\/em>With Claude doing my homework, how hard can it be?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The answer: slightly more annoying than usual. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is, until I decided that &#8220;well, if I&#8217;m having automatic distortion fix, why can&#8217;t I also have automatic leveling of the imported scene, so that the ground is level instead of tilted? Given how easy it was to implement the &#8220;ground plane selection&#8221; tool, I thought auto-levelling would be similarly done in a jiffy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It wasn&#8217;t. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It took a lot of explaining in order to get Claude to do what I wanted, especially since it kept insisting that it did exactly what I asked. Though it&#8217;s not completely clear whether Claude&#8217;s sense of spatial stuff is not on point, or whether I was just shit at prompting. Probably it&#8217;s a bit of column A, a bit of column B.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At least getting it to fix difference in coordinate system <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cartesian_coordinate_system#Orientation_and_handedness\" target=\"_blank\" rel=\"noreferrer noopener\">handedness<\/a> was fairly straightforward.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping up<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Implementing other features that I wanted was either more or less straightforward, or more or less more of the same, so I&#8217;m going to skip those parts. The moral of the story is: a bit less than three weeks in, the project was at the point I deemed fine. It did what I needed it to do, and that&#8217;s enough for me to move on.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There&#8217;s two ends that were left open, though.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>RenderDoc Exporter extension is not quite functional. It works with Guild Wars 2. It doesn&#8217;t work with Styx 3. Trying to make it work with Stxy 3 resulted in lots of &#8220;going around in circles,&#8221; so I decided to drop the matter.<br>When extension is running, RenderDoc will continue to crash from time to time. I suspect this is a RenderDoc issue, which means there&#8217;s nothing I can really do. RenderDoc project won&#8217;t either, because they want to be 120% above board. Which is fair.<\/li>\n\n\n\n<li>For a moment, I toyed around with an idea to include AI image <strong>upscalers<\/strong> (think something along the lines of waifu2x\/DLSS that can run locally in your browser, not to be confused with AI image <strong>generators<\/strong> ala Midjourney\/StableDiffusion\/etc, which are a very different beast) in order to upscale textures. The models are small enough you could practically include them on a webpage. At the end of the day, I decided I shouldn&#8217;t let feature creep creep any further.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">But all in all, the experience this time around was <em>kinda okay, actually. <\/em>The only problem is that I have very little idea what the code related to the graphics is doing. This would be a problem if I had plans to maintain this project beyond what I need it for, but I don&#8217;t. As I said: I&#8217;m interested in having this tool. I&#8217;m not interested in making or maintaining it, especially not beyond my needs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And that&#8217;s where things stand. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8230; the code is kinda spaghetti, tho.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Links<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/tamius-han\/renderdoc-scene-exporter\">RenderDoc Scene Exporter<\/a> (python extension for RenderDoc)<\/li>\n\n\n\n<li><a href=\"https:\/\/tamius-han.github.io\/renderdoc-scene-fixer\/\">RenderDoc Scene Fixer (web app)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tamius-han\/renderdoc-scene-fixer\">RenderDoc Scene Fixer (github repo)<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>The last time I tried vibe coding, I didn&#8217;t exactly find the whole experience very comfortable. To keep the story short, the important takeaway is that I felt that I wasted just as much time as I saved. But then again, given I was using ChatGPT, it&#8217;s not like I was using the best tool for the job. Fast forward some time, and the<span class=\"more-dots\">&#8230;<\/span> <span class=\"more-tag d-block mt-05\"><a class=\"more-link\" href=\"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/\">Continue Reading...<span class=\"screen-reader-text\"> \"Vibe Coding Adventure II: 2 Vibe 2 Code\"<\/span><\/a><\/span><!-- .more-tag --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pgc_sgb_lightbox_settings":"","footnotes":""},"categories":[13,38],"tags":[],"class_list":["post-1914","post","type-post","status-publish","format-standard","hentry","category-programming","category-projects","no-post-thumbnail"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Vibe Coding Adventure II: 2 Vibe 2 Code - Tamius&#039; sacred texts<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Vibe Coding Adventure II: 2 Vibe 2 Code - Tamius&#039; sacred texts\" \/>\n<meta property=\"og:description\" content=\"The last time I tried vibe coding, I didn&#8217;t exactly find the whole experience very comfortable. To keep the story short, the important takeaway is that I felt that I wasted just as much time as I saved. But then again, given I was using ChatGPT, it&#8217;s not like I was using the best tool for the job. Fast forward some time, and the...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/\" \/>\n<meta property=\"og:site_name\" content=\"Tamius&#039; sacred texts\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-03T10:35:42+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-03T10:46:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1141\" \/>\n\t<meta property=\"og:image:height\" content=\"927\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Tamius Han\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Tamius Han\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"24 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/\"},\"author\":{\"name\":\"Tamius Han\",\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/#\\\/schema\\\/person\\\/4677d05a4f45974f27cd21481c561c21\"},\"headline\":\"Vibe Coding Adventure II: 2 Vibe 2 Code\",\"datePublished\":\"2026-10-03T10:35:42+00:00\",\"dateModified\":\"2026-10-03T10:46:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/\"},\"wordCount\":5257,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/slika-1024x832.png\",\"articleSection\":[\"Programming\",\"Projects\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/\",\"url\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/\",\"name\":\"Vibe Coding Adventure II: 2 Vibe 2 Code - Tamius&#039; sacred texts\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/slika-1024x832.png\",\"datePublished\":\"2026-10-03T10:35:42+00:00\",\"dateModified\":\"2026-10-03T10:46:32+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/#\\\/schema\\\/person\\\/4677d05a4f45974f27cd21481c561c21\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/#primaryimage\",\"url\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/slika.png\",\"contentUrl\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/slika.png\",\"width\":1141,\"height\":927,\"caption\":\"slika\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/2026\\\/10\\\/03\\\/vibe-coding-adventure-ii-2-vibe-2-code\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Vibe Coding Adventure II: 2 Vibe 2 Code\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/#website\",\"url\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/\",\"name\":\"Tamius&#039; sacred texts\",\"description\":\"... containing one of the weirdest mix of pointless topics.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/#\\\/schema\\\/person\\\/4677d05a4f45974f27cd21481c561c21\",\"name\":\"Tamius Han\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1ce12569905c4aff5d48778af8527565f1175c254ad56cc5e5221666ff1e222b?s=96&d=blank&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1ce12569905c4aff5d48778af8527565f1175c254ad56cc5e5221666ff1e222b?s=96&d=blank&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1ce12569905c4aff5d48778af8527565f1175c254ad56cc5e5221666ff1e222b?s=96&d=blank&r=pg\",\"caption\":\"Tamius Han\"},\"url\":\"https:\\\/\\\/stuff.tamius.net\\\/sacred-texts\\\/author\\\/tamius-han\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Vibe Coding Adventure II: 2 Vibe 2 Code - Tamius&#039; sacred texts","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/","og_locale":"en_US","og_type":"article","og_title":"Vibe Coding Adventure II: 2 Vibe 2 Code - Tamius&#039; sacred texts","og_description":"The last time I tried vibe coding, I didn&#8217;t exactly find the whole experience very comfortable. To keep the story short, the important takeaway is that I felt that I wasted just as much time as I saved. But then again, given I was using ChatGPT, it&#8217;s not like I was using the best tool for the job. Fast forward some time, and the...","og_url":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/","og_site_name":"Tamius&#039; sacred texts","article_published_time":"2026-10-03T10:35:42+00:00","article_modified_time":"2026-10-03T10:46:32+00:00","og_image":[{"width":1141,"height":927,"url":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika.png","type":"image\/png"}],"author":"Tamius Han","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Tamius Han","Est. reading time":"24 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/#article","isPartOf":{"@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/"},"author":{"name":"Tamius Han","@id":"https:\/\/stuff.tamius.net\/sacred-texts\/#\/schema\/person\/4677d05a4f45974f27cd21481c561c21"},"headline":"Vibe Coding Adventure II: 2 Vibe 2 Code","datePublished":"2026-10-03T10:35:42+00:00","dateModified":"2026-10-03T10:46:32+00:00","mainEntityOfPage":{"@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/"},"wordCount":5257,"commentCount":0,"image":{"@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/#primaryimage"},"thumbnailUrl":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika-1024x832.png","articleSection":["Programming","Projects"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/","url":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/","name":"Vibe Coding Adventure II: 2 Vibe 2 Code - Tamius&#039; sacred texts","isPartOf":{"@id":"https:\/\/stuff.tamius.net\/sacred-texts\/#website"},"primaryImageOfPage":{"@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/#primaryimage"},"image":{"@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/#primaryimage"},"thumbnailUrl":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika-1024x832.png","datePublished":"2026-10-03T10:35:42+00:00","dateModified":"2026-10-03T10:46:32+00:00","author":{"@id":"https:\/\/stuff.tamius.net\/sacred-texts\/#\/schema\/person\/4677d05a4f45974f27cd21481c561c21"},"breadcrumb":{"@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/#primaryimage","url":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika.png","contentUrl":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-content\/uploads\/2026\/09\/slika.png","width":1141,"height":927,"caption":"slika"},{"@type":"BreadcrumbList","@id":"https:\/\/stuff.tamius.net\/sacred-texts\/2026\/10\/03\/vibe-coding-adventure-ii-2-vibe-2-code\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/stuff.tamius.net\/sacred-texts\/"},{"@type":"ListItem","position":2,"name":"Vibe Coding Adventure II: 2 Vibe 2 Code"}]},{"@type":"WebSite","@id":"https:\/\/stuff.tamius.net\/sacred-texts\/#website","url":"https:\/\/stuff.tamius.net\/sacred-texts\/","name":"Tamius&#039; sacred texts","description":"... containing one of the weirdest mix of pointless topics.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/stuff.tamius.net\/sacred-texts\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/stuff.tamius.net\/sacred-texts\/#\/schema\/person\/4677d05a4f45974f27cd21481c561c21","name":"Tamius Han","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/1ce12569905c4aff5d48778af8527565f1175c254ad56cc5e5221666ff1e222b?s=96&d=blank&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/1ce12569905c4aff5d48778af8527565f1175c254ad56cc5e5221666ff1e222b?s=96&d=blank&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1ce12569905c4aff5d48778af8527565f1175c254ad56cc5e5221666ff1e222b?s=96&d=blank&r=pg","caption":"Tamius Han"},"url":"https:\/\/stuff.tamius.net\/sacred-texts\/author\/tamius-han\/"}]}},"_links":{"self":[{"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/posts\/1914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/comments?post=1914"}],"version-history":[{"count":12,"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/posts\/1914\/revisions"}],"predecessor-version":[{"id":1945,"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/posts\/1914\/revisions\/1945"}],"wp:attachment":[{"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/media?parent=1914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/categories?post=1914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stuff.tamius.net\/sacred-texts\/wp-json\/wp\/v2\/tags?post=1914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}