Ramblings of a Tampa engineer

After blogging about a Halo 2 Mappack I made (Phantom Mappack) and then my more in depth blogs about the decade old patchers & map editors I wanted to archive the actual mods of the past.

This idea was created in the form of Halo Depot (GitHub) - a site that could hold all the patches off the past with one key advantage - it wouldn't suck.

My greatest gripe with all the other sites that remained were full of either forced sign ups, ads before download, forced 30s delays or even just flat out not working links. So the goal was Halo Depot was to be very easy. We'd have a minimal site with no accounts needed and a very easy upload system requiring only the patch of the mod.

I've blogged about the types of patch files, but what is important to note again is that a specific type of Halo 2 patch - Serenity has the ability to directly embed the author, description and image of the mod.

MrMurder's Nightwinder 2 in Serenity v3.3

So if a mod took the extra time and produced an enhanced patch file it could be used to patch the clean map itself (to produce the map) as well as patching the main menu to add the mod to the list.

Now obviously, Halo Depot isn't interested in patching main menu files, but it can read that same data to automatically produce a mod page for that patch file. It isn't much, but it has the benefit of being entirely pain free. Just upload the patch and done!

MrMurder's Nightwinder 2 in Halo Depot

To make the page a bit more populated, I added some helpful information like name of the original map file, type of patch and even the platform intended for the patch. This would be for the future expansion to other Halo games and platforms.

I spent some time ensuring all the proper structure data tags were properly filled. This resulted in all the weird formats that all social sites depended on.

<title>Sunnision by xheadshotmastax</title>
<meta name="description" content="An abandoned station found by grunts is now a bloody battle field for a new civil war. Prepare to die in paradise.">
<meta property="og:title" content="Sunnision by xheadshotmastax" />
<meta property="og:description" content="An abandoned station found by grunts is now a bloody battle field for a new civil war. Prepare to die in paradise." />
<meta property="og:image" content="https://www.halodepot.com/storage/images/SERENITY-image-6d5a9a07-d43b-43cd-b6ac-f0de1605e7bf.png" />
<meta name="twitter:title" content="Sunnision by xheadshotmastax" />
<meta name="twitter:image0" content="https://www.halodepot.com/storage/images/SERENITY-image-6d5a9a07-d43b-43cd-b6ac-f0de1605e7bf.png" />
<meta name="twitter:description" content="An abandoned station found by grunts is now a bloody battle field for a new civil war. Prepare to die in paradise." />
<script type="application/ld+json">{"@context":"https:\/\/schema.org","@type":"WebPage","name":"Sunnision by xheadshotmastax","description":"An abandoned station found by grunts is now a bloody battle field for a new civil war. Prepare to die in paradise.","image":"https:\/\/www.halodepot.com\/storage\/images\/SERENITY-image-6d5a9a07-d43b-43cd-b6ac-f0de1605e7bf.png"}</script>

So I was pretty happy - it seemed my first few tests worked well, but then I quickly learned that only about 7% of the Halo 2 mods I had archived were even viable.

Most weren't even .serenity patches instead in .sppf or .ppf and the few remaining .serenity patches did not have the required properties for me - author, mod name, description and image.

So I decided to expand Halo Depot to a multi-platform tool known as Assembly. As Halo versions continued being released into the wild it became obvious that a cross-game and platform tool was needed. The most known and popular being Assembly.

This patcher learned from Serenity and offered the ability to directly embed very helpful information into the patch so it was off to adding support for it.

I hit two things that ended up just killing my drive to work on this project. The first being just the size of the patch files in later games. Halo 2 patches usually capped out around ~70mb at the absolute max - most ranged from kilobytes to a few megs.

Most of my test patches for various Halo games in Assembly ranged from 110mb to 240mb - it was insane. Quickly I realized my bills of uploading content to AWS for transfer and hosting was going to be a bit more than I wanted to pay for a site that would earn no revenue.

However, I wanted to continue to test how good my plugin system could support another patch type. I kept getting stuck reading the patch format with constant out of bounds errors while trying to read the mod image.

// Screenshot
$length = $this->reader->readUInt32();
if ($length > 0) {
    $imageData = $this->reader->readBytes($length);
}
AssemblyPatch.php - HaloDepot

I couldn't figure out what was wrong. I was stepping through the bytes block by block in a hex editor and every looked fine.

So I thought I would look back at the code that generated this in Assembly.

// Write screenshot
if (patch.Screenshot != null)
{
    writer.WriteInt32(patch.Screenshot.Length);
    writer.WriteBlock(patch.Screenshot);
}
else
{
    writer.WriteInt32(0);
}
AssemblyPatchWriter.cs - Assembly

So I realized that I used an unsigned int32 read, while the software was writing signed 32 int for the block size. This didn't make much sense since a file size can't be negative, but either way - it still didn't work.

Under the hood, Halo Depot used a php package for reading/writing binary files - called php-binary-reader. Funny enough there was a bug report - "ReadInt32 with not aligned byte" which seemed to explain my issues.

This package was pretty abandoned - not having any work since 2017. It worked so I wasn't complaining, but working on the project was another story. Coverage and tests suffered with my updated versions of PHP so I set off to update it to the latest and greatest of everything.

This took far longer than I thought since I was taking the chance to really learn pack/unpack functions in PHP which have remained semi unchanged since Perl. Once everything was updated with GitHub Actions and 100% coverage and PHP7.4 features I realized I was an idiot. I never fixed the reason I forked the package in the first place.

At this point with the disappointment that most legacy Halo 2 mods were not compatible, recent Halo games having insane patch sizes and a low level bug in my binary reader - I gave up.

PHP isn't the language for binary reading and deciding to storing large assets on AWS where I get billed for transfer and storage vs just a flat $5/month Linode wasn't smart either. So with that, here are some screenshots of the project.

You’ve successfully subscribed to Connor Tumbleson
Welcome back! You’ve successfully signed in.
Great! You’ve successfully signed up.
Success! Your email is updated.
Your link has expired
Success! Check your email for magic link to sign-in.