I still vividly remember the day at the Halo World Championship 2025, when Halo Studios announced Halo: Campaign Evolved. New graphics, more missions, and a dive towards Unreal Engine instead of Slipspace. Lots to be excited about!
Naturally, when the game first became available, I just had to get it and start playing through the campaign. Now, despite the fact that some folks can complain about the fact that there is no multiplayer, this was not a major detractor for me - I’ve always been a campaign-first kind of guy.
But if you know me, you also know that I love looking under the hood of the released Halo games - just think of how much time I spent on random Halo API explorations. When I got the build installed on my local machine, the first question I had was “What can I tinker with in this game?”

You can watch the video if you want a more hands-on explanation:
Unreal Engine rules everything around me #
The first stop was, of course, the install folder. Halo: Campaign Evolved sits in your Steam library under steamapps/common/Halo Campaign Evolved, and the moment you open it you can tell what you’re dealing with:
Halo Campaign Evolved/
├── Engine/
├── DigitalExtras/
└── Meteorite/
├── Binaries/Win64/HaloCampaignEvolved.exe
└── Content/Paks/
That Meteorite folder is the interesting part - it’s clearly the codename for the game, and it shows up everywhere (including the REST APIs, where it’s referred to as mtr). The build string baked into the executable spells the whole thing out, if you had any doubts:
5.5.4-2026.06.26.1097863.1-Rel-i343-Meteorite-2606-CU2
Unreal Engine 5.5.4 (I am pretty positive that’s what this is, but it’s conjecture), built on June 26, changelist 1097863, from a branch called Rel-i343-Meteorite. The i343 prefix is also unsurprisingly popping up everywhere - you’ll see paths like Engine/Plugins/i343/BlamEngine scattered through the binary, which is a delightful detail if you are a diehard Halo fan. The classic Halo “Blam” engine (or, whatever pieces of it remain - I have no clue) now lives as an Unreal plugin.
With UE, all the game content lives in Meteorite/Content/Paks, and there’s a lot to unpack (hah!) there. A keen eye will spot two file types:
.pak- the classic Unreal package format.utocand.ucas- the newer IoStore container format that UE5 uses for most cooked assets
For my exploration, I started with .pak files only - that was more than enough, as it turns out. To extract content from it, I used repak from Truman Kilen.

This is a third-party tool, right? Is it OK for me to use it on my machine?
While these tools do what they were designed to do and I have no reason to believe they are in any way, shape, or form malicious, I cannot vouch for their safety and reliability! As with any external project (mine included, by the way), always exercise caution and define the trust boundaries where you want to run them. When I was experimenting with extraction using repak, I ran everything through isolated containers with mounted data folders.
repak needs an Oodle decompressor to do anything useful, since that’s what the containers are compressed with. You can often get the required decompressor library from Steam games that bundle it in the distribution themselves.
The file that I wanted to unpack first is pakchunk0-Windows.pak (roughly two and a half GB in size). Because I saw that quite a few settings in the game in %LOCALAPPDATA% and within its own folder uses *.ini, I decided to intentionally narrow down my search to those files.
One repak list later:
$ repak list pakchunk0-Windows.pak | grep -i '\.ini$' | wc -l
145
That means there are 145 configuration files, in plain text, inside the PAK. Including one that caught my attention right away:
Meteorite/Config/DefaultGame.ini
My hunch was that it contained some default game state that controls its general behavior. Because I have no intimate knowledge of how everything works here, this seemed like a reasonable starting point, so I extracted it.
$ repak get pakchunk0-Windows.pak "Meteorite/Config/DefaultGame.ini" > DefaultGame.ini
This resulted in 27 KB of internal settings. There’s a lot there that I won’t really list here, since it’s mostly irrelevant to what I wanted to talk about in this blog post. However, about two thirds of the way down, this came up:
[/Script/Meteorite.DebugMenuSettings]
bEnableDebugMenuBetaNonShipping=True
bEnableDebugMenuReleaseNonShipping=True
I wonder what this would do? Look at those two key names, but split them into logical parts:
A pretty good guess here is that there are different builds of the game available - Debug, Development, Test, Shipping. The retail copy you buy is a Shipping build. And the game’s own config only enables the debug menu for NonShipping builds.
Which raises the obvious question: if there’s a NonShipping variant of these flags, is there a Shipping one? You don’t need any special tooling to answer that - the flag names are sitting in the game executable as plain ASCII. Point PowerShell at it:
Select-String -Path "HaloCampaignEvolved.exe" -Pattern "bEnableDebugMenu\w+" -Encoding ascii -AllMatches |
ForEach-Object { $_.Matches.Value } | Sort-Object -Unique

That’s a bingo:
bEnableDebugMenuBetaNonShipping
bEnableDebugMenuBetaShipping
bEnableDebugMenuDefaultNonShipping
bEnableDebugMenuDefaultShipping
bEnableDebugMenuReleaseNonShipping
bEnableDebugMenuReleaseShipping
Every build configuration gets a pair - one for non-shipping builds and one for shipping. The config file sets two of them, both on the NonShipping side. The other four, including every single Shipping variant, aren’t mentioned anywhere in the shipped configuration, so they quietly fall back to their default of False. I can probably try and override that behavior.
One INI file at a time #
Because the INI file I was looking at is packaged along other assets, it can’t be edited in place. Now, repacking the container to flip one boolean would likely be possible, but I wanted to exhaust all easy options first.

Wait, wait, wait… Hold on. Why not just repack the PAK? The files aren’t encrypted or signed, so nothing is stopping you from writing a modified DefaultGame.ini back into the container.
I mean - I guess you could? But we probably have a much cleaner path available. The config system is layered - the engine reads a whole hierarchy of .ini files in order, and later layers override earlier ones. The PAK-staged DefaultGame.ini is one of the earlier layers. The last layer, the one that wins, is the writable user directory on my own machine.
For this version of Halo, that location is the following:
%LOCALAPPDATA%\Meteorite\Saved\Config\Windows\
If you’ve launched the game at least once, that folder already exists and already has a GameUserSettings.ini in it holding some of the settings. The game reads and writes it constantly. Recall how I mentioned that I focused on INI files first? This is why.
I’ll call out an important INI formatting rule that I discovered in the process: an Unreal config class reads from the .ini file that matches its config= specifier, and its section header must be [/Script/<Module>.<Class>].
If you get either one wrong - the setting won’t be interpreted correctly and nothing will happen.Because I don’t have access to verbose logs, I couldn’t really tell if something is off until I tinkered with the files and got the setup right by restarting the game a million times.
DebugMenuSettings appeared in DefaultGame.ini, so it’s a Game config class, so the override belongs in Game.ini. Same folder as GameUserSettings.ini.
To make the change, close the game first. Then, create %LOCALAPPDATA%\Meteorite\Saved\Config\Windows\Game.ini and put this in it:
[/Script/Meteorite.DebugMenuSettings]
bEnableDebugMenuDefaultShipping=True
bEnableDebugMenuBetaShipping=True
bEnableDebugMenuReleaseShipping=True
bEnableDebugMenuDefaultNonShipping=True
bEnableDebugMenuBetaNonShipping=True
bEnableDebugMenuReleaseNonShipping=True
Right-click on the file and mark it as read-only, to make sure that the game doesn’t stomp over it.

That’s it - the magic is in. Let’s launch the game!
When you go past the launch screen, you will now see the option to get the debug controls:

See that G Toggle Debug Options at the bottom? That means the configuration took effect. And now, you can do a whole bunch of really fun things.
And of course, you can do some more fancy fancy things, like testing campaign missions or some maps/game variants, that are somehow inaccessible (I haven’t spent enough time digging through this, maybe there is another secret flag).
Now that’s an Easter Egg!