rt-541

projects / porting halo armor

Porting Halo armor into Zero Company

This is a how-it's-done write-up, not a portfolio. The goal of the project is a direct port of the original assets, or a kitbash of them where a new piece is needed. None of the base art is mine.

The armor is the ODST set from Halo: Reach by Bungie. The fine surface detail comes from Halo: Campaign Evolved by Halo Studios. The game it goes into is Star Wars Zero Company by Bit Reactor, with Respawn Entertainment and Lucasfilm Games, published by Electronic Arts. Those studios made the art. Scripts here convert it and rebuild its texture maps; they don't replace it.

What's mine is the method and the design decisions: what to keep, what to rebuild, how wear should behave, and when a result is good enough.

Where it stands: work in progress, with one set so far. The rigged torso draws in the game on the game's own material. The rebuilt textures have only been seen in offline renders, because my armor material still crashes the game. That's covered below.

The weapons get the same treatment in Porting and kitbashing Halo weapons.

Before and after

All offline renders with the same lights and cameras, on an approximation of the game's shader. "Before" is the Reach textures with the colour fixes applied. "After" is the same mesh with the rebuilt maps.

ODST armor with Reach textures, full body
Before: Reach textures
ODST armor with rebuilt textures, full body
After: rebuilt maps
Chest close-up with Reach textures
Chest, before. Reach's grime is painted into the colour.
Chest close-up with rebuilt textures
Chest, after. The grime moves to its own layer.
Helmet close-up with Reach textures
Helmet, before
Helmet close-up with rebuilt textures
Helmet, after
Zero Company clone armor, full body, as the quality reference
The bar to meet: Zero Company's own armor in the same setup. This is the game's art, shown for reference.
ODST armor recoloured grey and white through the tint mask
A second palette through the tint mask, with no repaint. Emulated offline, not yet in the game.

On the real character

These are test screenshots from the game, not finished work. Only the torso is swapped here. The helmet, the legs and the material are still the game's clone armor, so this proves the mesh, rig and cook, and not the look.

In-game screenshot of a clone trooper wearing the ODST torso with the game's clone material
The O1 torso on a real trooper, animating. The clone paint lands in the wrong places because its mask doesn't match these UVs.
The same in-game trooper with the torso turned red
The same torso with red pushed through the game's colour parameter. The tint system reaches the mesh, patchily for now.

Tools

Halo: Reach Mod Tools
The source. The official editing kit gives the Reach tags: the ODST armor, its rig, and the shader data that says what each surface is made of.
Foundry
A Blender add-on that imports Halo tags. It also gives scripts access to ManagedBlam, which is how the Reach shader data gets read.
Blender
Rigging, UVs, bakes and renders, run headless from Python so every step can be repeated. Cycles for the bakes and the comparison renders.
CUE4Parse
A library for reading Unreal game files. Small exporters built on it read Zero Company, to learn how its armor is put together, and Halo: Campaign Evolved, for its detail textures.
UE4SS
Runs Lua inside the game. It dumped the type data needed to read the game files, and it runs the test probe, the remote test driver and the wear driver.
Unreal Engine 5.6.1 and SWZCModKit
The engine version the game uses, built from source, plus the community mod kit by klukule. Editor commandlets do the import and the cook, and UnrealPak packs the result.
Python and NumPy
The compositor that builds the texture maps, the area masks and the checks that run after every build.
Reclaimer, Index and model-viewer
For the reference library only: Reclaimer read Halo Infinite, Wildenhaus's Index read Halo 2 Anniversary, and model-viewer shows the pieces in a browser so I can compare them and try out sets.
Claude Code
An agent team writes and runs the scripts under my direction, with separate agents reviewing each step. I make the design calls and judge the results by eye.

The rules that made it work

Keep the shapes
Reach's shapes, plate layout and markings stay as they are. The rework changes how the armor is built and textured, not its design.
Measure the target first
Before changing anything, read what the game actually does: how many meshes, which maps, what texture density. Most of the early mistakes came from guessing.
No colour in the base map
The game paints armor with a tint mask and colour pickers. Paint baked into the base colour breaks that, so the base is a flat neutral and colour lives in the mask.
Passing tests is not the same as looking right
Every step has automated checks, and I still look at the result. The worst failure on this page passed all 25 of its tests.
One variable at a time
When something breaks, change one thing, test, and write down the result. Each test session backs up the game saves, checks them by hash and restores them afterwards.

From the source game into the mod

  1. 1. Pull the source

    The armor comes out of the Reach tags through Foundry into Blender, on the marine rig. Sets are grouped by the slots Zero Company uses. This page follows one ODST set, called O1. I also pulled about 775 armor pieces from across the series into a browsable library to compare against. That library is reference only.

  2. 2. Read the target

    Zero Company builds a suit from five skinned meshes (helmet, torso, arms, legs, boots), with one material each, on a 240-bone armor skeleton. Each part gets four maps: colour, a mask for roughness and metal, a normal map, and a tint mask. A new set has to fit that shape or the game's colour and wear systems never reach it.

  3. 3. Fit it to the body

    The set is scaled by 0.923 to match the game's height, then the Halo rig is swung joint by joint onto the game's reference pose. Skin weights move across through a bone map. The helmet gets a test: rays from every vertex of the game's head must hit the inside of the helmet. As first fitted, 144 of 22,112 vertices poked through. A small shift and a 2 percent scale took that to zero.

  4. 4. Make the plates rigid

    Halo hangs most plates on one bone. My first fit spread them across the game's twist bones, so hard armor bent like cloth. Now each plate sits on one bone: 71 plates in all, while cloth and gloves stay soft. Where a plate meets cloth, the seam copies the plate's weights so it can't crack open.

  5. 5. Sort out the knee pads

    A knee pad spans a joint, so no single bone suits it. I built four versions and rendered them in every pose. The answer was already in the game: its armor skeleton has a helper bone for knee pads, driven by the game's own animation blueprint.

    Knee pad split at the joint, with its texture smearedKnee pad fixed to the calf, standing away from the kneeKnee pad on the helper bone, sitting over the knee
    Left: split at the joint, which smears the pad. Middle: all on the calf, which swings off the knee and shows the open shell. Right: on the game's helper bone, which is the one I kept. The renders emulate the game's driver.
  6. 6. Cook and pack

    An editor commandlet imports the meshes in Unreal against a kit copy of the game's skeleton. The cook and UnrealPak then produce an override pak. An install script refuses to run if the pak would clash with another mod, and it puts the mod list back byte for byte afterwards.

  7. 7. Find out what each surface is

    Reach's shader tags say which faces are painted plate, polymer, cloth, webbing, rubber, leather or visor. A script turns that into area masks, so the new textures come from Reach's own data and not from guesses.

    The armor in flat colours, one colour per material area
    Material areas read from Reach's shader data, shown as flat colours on the model.
  8. 8. Give the textures room

    Reach ran at about 4.8 pixels per centimetre on the body. Zero Company runs at about 41. New UVs keep Reach's island shapes, give mirrored pieces their own space, and favour plates. Plates now reach about 30 pixels per centimetre, on 4K maps for torso and legs and 2K for the rest.

    Checker pattern on the armor with Reach's UVsChecker pattern on the armor with the new UVs
    Checker test on the chest. Left: Reach's UVs, where materials overlap and the square size jumps between them. Right: the new UVs, one map per part with no overlap, so the squares are more even and every pixel belongs to one spot on the armor.
  9. 9. Rebuild the maps

    This is a rebuild from the original art, not an upscale. Reach's normal map is carried across exactly. Ambient occlusion and curvature are baked from the mesh. The fine detail comes from Halo: Campaign Evolved's tiling fabric, webbing, rubber, polymer and metal textures, used at their real-world size. Base colour is a flat neutral, and the tint mask is built from Reach's own change-colour data. Markings are redrawn sharp at full resolution from Reach's outlines.

  10. 10. Add wear as separate layers

    There are three layers, each with its own trigger. Dirt rises with distance moved and can be cleaned off. Carbon scoring rises with hits taken. Battle damage rises in three steps with health lost, and a knockdown jumps to the next step. It can't be cleaned. The design is mine; the runtime driver is still being extended to all three.

  11. 11. Test it in the game

    A small UE4SS mod takes commands from a file: load a save, swap a material, set a colour, take a screenshot. A test can then run with nobody at the PC. Saves are backed up first and checked by hash afterwards.

Wear, one layer at a time

Offline emulation of the three layers at full strength. Paint shows through dirt and carbon, and battle damage cuts down to what's underneath. Markings and the visor stay readable.

Chest with the dirt layer
Dirt, from distance moved
Chest with the carbon scoring layer
Carbon scoring, from hits taken
Chest with the battle damage layer
Battle damage, from health lost
Chest with all three wear layers
All three together
Battle damage step one, close up Battle damage step two, close up Battle damage step three, close up
Battle damage steps 1 to 3, close up. This is version two and still under review.

What was hard

It looked wrong and I couldn't say why
The first build didn't sit right next to the game's armor and I couldn't tell why, so I measured instead of guessing. Texture density was about a tenth of the game's, Reach's lighting and paint were baked into the colour maps, gloss had flattened into an even sheen, and the armor skipped the game's armor material altogether. Tints, wetness and decals did nothing. That finding is why this became a rework and not a quick fix.
A colour-space mistake
The cloth came in far too bright because a colour texture was treated as linear data, and a specular mask had been turned into roughness, which flattened every highlight. Correcting both gave a much better match, and that corrected version became the look target. It's the "before" in the comparisons below.
Armor that bent
I saw it in the first renders: the plates flexed with the body. The cause was my own weighting, not the source, because Halo already rigs those plates almost entirely to single bones. Rigid plates fixed it.
Crumpled meshes from Campaign Evolved
Helmets came out at 70 to 310 triangles. The exporter was reading the low-detail fallback meshes, not the Nanite data. A newer CUE4Parse with Nanite reading switched on gave 5,000 to 18,000 triangles.
Comparing the wrong things
An early comparison put Reach ODST armor against Campaign Evolved marines, which is not a fair test. Looking across the real sets showed Campaign Evolved has no true ODST set or helmet. The fix was a clear split: Reach's design, with Campaign Evolved-level texture quality. A separate Campaign Evolved-style marine look is planned.
Battle damage that looked like snow
Version one thresholded noise into scratches. All 25 tests passed. I looked at it and it was an even dust of white specks with no real scratches or gouges. Tiny specks measured up to 1,208 per 100 square centimetres. Version two draws marks on purpose: grouped scratches, gouges with a floor, walls and a raised lip, and chips only on outward edges. Specks fell below 2 per 100 square centimetres, and a new check would catch this failure next time. I'm still judging how version two looks.
The material that crashes the game
This one is not solved. The wear design needs my own armor material, and that material crashes the game the moment it draws, in the graphics code that binds textures and parameters. The child of the game's material crashes, and so does a bare master of my own with plain textures. The game's own material draws fine on the same mesh, and so does my simpler weapon material, which clears the mesh and the rig. The plain-texture crash clears virtual textures. So I started from the weapon material that works and added one feature at a time. Base, colour, normal, tint, damage and two-sided all drew. The crash came back at masked blending. That's one crash so far, and I don't know yet why masked would do it, so the next test has to confirm it.
A test tool that needed its own review
The first version of the remote test mod worked, then failed review. It could have reached save functions by a side route, and a killed session would have left it installed. It took three review rounds to close those holes.
ODST armor as first imported, with cloth too bright
First import, with the colour-space error in the cloth
ODST armor with corrected cloth and gloss
Cloth and gloss corrected: the look target

Personal, non-commercial fan project, with nothing to download. The armor is a direct port of art from Halo: Reach by Bungie, with surface detail from Halo: Campaign Evolved by Halo Studios. The reference library also draws on Halo: Combat Evolved, Halo 2, Halo 3 and Halo 3: ODST by Bungie, Halo 4 and Halo Infinite by 343 Industries, and Halo 2 Anniversary by Saber Interactive and 343 Industries. Reference renders and test screenshots show art from Star Wars Zero Company by Bit Reactor, Respawn Entertainment and Lucasfilm Games, published by Electronic Arts. Not affiliated with or endorsed by Microsoft, Xbox Game Studios, Halo Studios, Bungie, Electronic Arts, Bit Reactor, Respawn Entertainment, Lucasfilm or The Walt Disney Company. Halo is a trademark of Microsoft Corporation. Star Wars is a trademark of Lucasfilm Ltd.