Building the thing was not the hard part.

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.

The build was good. The box was lying about where I had put it.

Source trees forgive what packages expose

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.

A release archive knows none of that.

It has a directory structure and whatever instructions survived the copy.

archive/
  README.txt        says: run Game.exe
  build/
    windows/
      Game.exe      actual location

That two-level disagreement can make hours of correct work look broken.

Test from the package boundary

The only honest packaging test begins with the exact artifact a user receives.

  1. Copy the archive to a clean temporary directory.
  2. Extract it using an ordinary tool.
  3. Follow the included instructions literally.
  4. Launch without the editor, source tree, or developer environment.
  5. Verify the first useful interaction, not merely process creation.

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.

Manifests beat assumptions

A package should carry a small machine-readable inventory:

  • expected launcher path;
  • required runtime files;
  • asset directories;
  • version and build identifier;
  • checksums for critical files;
  • supported platform;
  • known optional components.

Validation can then assert that the archive matches the manifest before anyone downloads it.

This catches nested executables, missing DLLs, empty asset folders, wrong line endings, and instructions copied from an earlier layout.

The first archive check can also be wrong

There is a delightful second trap: the validator itself may assume the wrong layout.

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.

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.

Shipping is a separate engineering phase

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.

The final boss is not the compiler. It is the clean machine, the literal user, and the archive that has forgotten everything you know.