<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Builds on ErrorZap</title><link>https://errorzap.com/tags/builds/</link><description>Recent content in Builds on ErrorZap</description><image><title>ErrorZap</title><url>https://errorzap.com/og.png</url><link>https://errorzap.com/og.png</link></image><generator>Hugo</generator><language>en-US</language><copyright>ErrorZap</copyright><lastBuildDate>Thu, 05 Nov 2026 09:00:00 -0700</lastBuildDate><atom:link href="https://errorzap.com/tags/builds/index.xml" rel="self" type="application/rss+xml"/><item><title>Packaging Is the Final Boss</title><link>https://errorzap.com/posts/packaging-is-the-final-boss/</link><pubDate>Thu, 05 Nov 2026 09:00:00 -0700</pubDate><guid>https://errorzap.com/posts/packaging-is-the-final-boss/</guid><description>The game worked, the archive looked complete, and one wrong launcher path made a good build appear dead.</description><content:encoded><![CDATA[<p>Building the thing was not the hard part.</p>
<p>The playable version existed. Levels loaded. Controls worked. Assets were present. Then I zipped it up, tested the package like a normal person, and the launcher could not find the executable.</p>
<p>The build was good. The box was lying about where I had put it.</p>
<h2 id="source-trees-forgive-what-packages-expose">Source trees forgive what packages expose</h2>
<p>During development, tools know a lot about their environment. The editor knows the project root. Build scripts inherit working directories. Asset paths accidentally resolve because the entire source tree is nearby. A developer launches the right executable from muscle memory.</p>
<p>A release archive knows none of that.</p>
<p>It has a directory structure and whatever instructions survived the copy.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>archive/
</span></span><span style="display:flex;"><span>  README.txt        says: run Game.exe
</span></span><span style="display:flex;"><span>  build/
</span></span><span style="display:flex;"><span>    windows/
</span></span><span style="display:flex;"><span>      Game.exe      actual location
</span></span></code></pre></div><p>That two-level disagreement can make hours of correct work look broken.</p>
<h2 id="test-from-the-package-boundary">Test from the package boundary</h2>
<p>The only honest packaging test begins with the exact artifact a user receives.</p>
<ol>
<li>Copy the archive to a clean temporary directory.</li>
<li>Extract it using an ordinary tool.</li>
<li>Follow the included instructions literally.</li>
<li>Launch without the editor, source tree, or developer environment.</li>
<li>Verify the first useful interaction, not merely process creation.</li>
</ol>
<p>For a game, that might mean reaching the menu, starting a level, moving, saving, and exiting. For a desktop app, it means the actual window and core action. For a script bundle, it means the double-click path does something useful on a machine that does not know your habits.</p>
<h2 id="manifests-beat-assumptions">Manifests beat assumptions</h2>
<p>A package should carry a small machine-readable inventory:</p>
<ul>
<li>expected launcher path;</li>
<li>required runtime files;</li>
<li>asset directories;</li>
<li>version and build identifier;</li>
<li>checksums for critical files;</li>
<li>supported platform;</li>
<li>known optional components.</li>
</ul>
<p>Validation can then assert that the archive matches the manifest before anyone downloads it.</p>
<p>This catches nested executables, missing DLLs, empty asset folders, wrong line endings, and instructions copied from an earlier layout.</p>
<h2 id="the-first-archive-check-can-also-be-wrong">The first archive check can also be wrong</h2>
<p>There is a delightful second trap: the validator itself may assume the wrong layout.</p>
<p>A package scanner once accused a valid build of missing its launcher because it searched only the archive root. The launcher was nested where the build system intentionally placed it. The test failed, but the product was not defective. The acceptance contract was.</p>
<p>That is why failures need diagnosis, not obedience. A red check is evidence that an expectation and reality disagree. You still have to determine which one is wrong.</p>
<h2 id="shipping-is-a-separate-engineering-phase">Shipping is a separate engineering phase</h2>
<p>Developers often treat packaging as clerical work performed after the real engineering. Packaging is where implicit knowledge is removed. It tests whether the artifact can survive without the person who built it standing nearby.</p>
<p>The final boss is not the compiler. It is the clean machine, the literal user, and the archive that has forgotten everything you know.</p>
]]></content:encoded></item></channel></rss>