Give any Humankind unit — or district, pawn prop, or projectile — your own 3D model, texture, and sound. No executable patching, no per-model code. (Formerly ENC Access Proof.)
HAF augments Humankind with custom assets. You bake
an ordinary model (.glb / .fbx / .obj / .blend) in the HAF Authoring Tools — a suite of Unity editor
windows: the Model Factory (the model itself), the Animation Lab (clips + behaviors), the District
Factory, Prop Lab, Projectile Lab, and Unit Retexture / Sound Studio — and a data-driven BepInEx plugin
injects the result onto the live game: correct geometry, correct texture, its own animation, and movement
audio, all driven by a JSON registry. Adding a model is just baking it — there is no code to write per model.
What HAF changes. Until now, giving a Humankind unit a different look meant reskinning the existing (human) models, swapping their gear, or remapping a unit onto a donor unit — always a variation on something the game already ships. HAF lets a unit be a genuinely custom model — a ship, vehicle, creature, or mech, animated and textured — within the engine's bounds (rotation-only animation, a shared GPU vertex budget). One honest note for authors: you supply the model. HAF is the pipeline, not an art library — bring a licensed download, a commission, or your own build, and baking + injecting it (correct orientation, texture, animation, isolation) is HAF's job.
It's multi-mod by design. The runtime merges asset packs from many mods at once, so any modder ships their own config + assets and joins without editing anyone else's files. ENC is the reference pack (a set of modern-era units); a stranger's pack loads and merges right alongside it, with conflicts detected and reported. The aim is to make a custom Humankind unit something anyone willing to take some effort can build. See Multi-Mod.md.
Custom units ride the game's own GPU-instanced renderer, so repeated instances are cheap — the mesh-buffer/asset cost is per distinct model type, not per unit on screen (each visible instance still carries the game's normal render/cull cost).
Two halves, one contract. The HAF Authoring Tools (bake, in the Unity editor) and a runtime plugin (inject, in the game) talk only through a small JSON pack registry — so the tooling and the injector stay fully decoupled, and the registry is the public API other mods build against. ("Model Factory" names one window of the suite — the historical first one; in-editor the whole suite lives under
Tools ▸ HAF.)
HAF adds custom content in six places. Four inject custom assets; two retune units the game already ships, with no bake and nothing to undo but a deleted line. Each is proven in-game with a shipped example.
| Axis | What it does | Assets? | Deep dive |
|---|---|---|---|
| Units | Replace a unit's whole 3D model — static or animated, with per-model runtime behaviors | bake | Factory-Manual · Animated-Models |
| Districts | A district's on-map building — own model and texture, on every tile it's built (other districts untouched), auto-leveled | bake | District-Visuals |
| Wonders | A player-authored Artificial Wonder with a custom model, rendered through the game's native wonder pipeline (no donor district) | bake | Wonder-Spike |
| Pawn props | Weapons & gear on a pawn's attachment slots — no whole-model replacement | bake | Pawn-Props |
| Projectiles | The munition mesh a unit fires | bake | Projectiles |
| Formations | How many models a unit fields and how they're arranged | data only | Formations |
| Unit size | How big any unit renders (vanilla included), incl. era-based scaling | data only | Unit-Size |
Formations + unit size together cover both halves of R.E.D.-style rebalancing — count and scale.
Animation, audio, and retexturing are cross-cutting — a unit model can carry its own baked animation, engine or custom-WAV movement sound, and a runtime-hot-loaded skin or tint, all from the same JSON registry, no code.
Custom unit models
- Static or animated model replacement from GLB / glTF / OBJ / FBX /
.blend, correctly oriented, textured, and placed (at the waterline for ships). Shipped examples include a zeppelin, an LCAC hovercraft, a USS Zumwalt cruiser, and a RAH-66 Comanche. - Heavy, single-sided, and multi-material meshes handled — a built-in vertex reducer, a winding fix + double-sided fallback for CAD "sketch" meshes, height-based UVs, and an N-material atlas packer.
- Strip parts at bake time — delete named objects (and children) from your source mesh before baking.
Animation
- A model plays its own baked animation — tick Animated, press Bake. A drone spins its own propellers; the M114 howitzer plays the animator's full recoil cycle (real bone translation, not rotation-only).
- State-driven characters — a rigged character idles standing, runs while moving, holds a combat stance in battle, plays an after-move settle, and fires its attack animation when it shoots. Proven with a full 62-bone humanoid soldier; five clips per model, switched live by the runtime.
- Fire-on-attack — a baked clip plays once, on the unit's combat action (e.g. a howitzer barrel that elevates only when it bombards), via Humankind's own combat event bus.
- Turret aim — a turret yaws to track its target by retargeting the engine's own aim slot (no per-frame trig).
- A static model becomes a moving vehicle — no Blender knowledge — the Vehicle Lab probes a raw model into parts; mark what moves (wheels, caterpillar tracks, turret + gun, or a helicopter's main + tail rotor) and it generates the rigged, spin-animated source the bake consumes. Its probe also classifies interior parts (escape-ray sampling: provably-never-visible cockpit gear, engine guts) so hidden geometry is stripped before it costs shared GPU vertex budget — 28% of the test helicopter's vertices.
- Borrow or freeze the donor's motion — strip your model's rotor and the donor's spinning rotor shows through; or Freeze donor animation to pin a rigid model still while it glides tile-to-tile.
- Fly the donor's animation on YOUR rig — Use donor animation clip plays the donor's complete original motion (a helicopter's hover bob, main rotor, canted tail fan) natively on your baked skeleton: the plugin rebases the rig to the donor's rest conventions and the Vehicle Lab authors rotor bones as axle frames, so the clip channels land exactly on your parts. Plus eased, banked turns on move orders instead of the engine's facing snap, and terrain hugging — skim low over open country, climb only for built city districts (all live-tunable). The measured engine contract: docs/Donor-Clip-Flight.md.
- Turn first, aim true, fire second — any unit with a turn rate (HAF models via the Factory, vanilla units via a Formation Lab link, or whole categories — human / land / turret / hover / ship — from one panel) sweeps to its new heading instead of the engine's instant facing snap, and an attack waits for the pivot: recoil, muzzle flash, shot sound, smoke and shell all hold on one shared clock and land together — aimed at the true bearing, not vanilla's hex-quantized angle. docs/Turn-Ease.md.
- Real gunnery, even in battles — vanilla never turns a vehicle's hull in battle (turret-slot aiming only); HAF's battle hull-aim lays a turretless vehicle on its actual target, the gun elevates with range to a configurable max, the muzzle chain fires from the barrel end (gun-local offset that rides aim + elevation), and after the shot the unit stays laid, settling on the nearest clean facing toward where it fired. A Turret bone yaws; a Gun bone elevates — configured in the Animation Lab. docs/Turn-Ease.md.
Textures
- Correct, isolated skins out of the box — glTF/OBJ V-convention reconciled, off-tile UVs shifted back in range, and each model gets a private layer so its skin never bleeds onto the donor.
- Bake-time skin tuning — albedo brightness/saturation, a keep-black toggle for glass canopies, and atlas sizing (256–2048, DXT1) that keeps each shipped skin ~0.1–2 MB.
- Runtime retexture / recolour without a bake — a hot-loaded PNG or a live desaturate + RGB adjust, per unit, free on the vertex budget. Works on baked custom models too.
Audio
- Unit movement audio — restores the engine sound re-loaded units lose, playing the game's own sound by name (F8 Dump Sound Catalog lists all ~845), or any custom WAV as a spool-up → loop → spool-down sequence.
- Creature voices — silence a borrowed animal donor's Wwise voice and add your own idle growl and attack roar (camera-anchored, jittered, one-voice-per-stack).
- Game-wide sound overrides — the Game Sound Lab silences (and, reserved, replaces) any vanilla Wwise event —
music, UI, ambience — by name, authored into
haf_sounds.json, with in-game F8 audition to hear an event before you target it. Aimed at soundscape-overhaul mods. See Game-Sound-Lab.md.
Multi-mod & tooling
- Pack merging — the runtime merges any number of third-party packs from
haf_packs/: duplicate-modIdrejection,dependsOnvalidation, topological load order, declared overrides, and ahaf_load_report.txtof every decision. - Guided authoring — Pick-driven clip/bone/hide fields, an embedded interactive 3D preview, auto-detected game and Blender paths, and an in-game F8 scan/feedback window.
- Backup & Restore — a guarded, additive snapshot of everything ENCReload's git doesn't track.
- Headless CLI — re-bake a model and run the full Humankind mod build + deploy from the command line (Unity batch mode), reusing the exact code the editor buttons call — so scripts, CI, or an AI agent can drive HAF without the GUI. See Headless-CLI.md.
Polishing: moving caterpillar tracks (treadize) run in-game, with a remaining idle micro-twitch to smooth out; the death / battle-start war-cry creature voices are built and awaiting in-game verification. See CHANGELOG.md.
The full story — how each capability was proven and the war stories behind it — is in CHANGELOG.md. The complete capability list and known limitations are in Capabilities.md.
Editor — the Model Factory (baker/, Tools ▸ HAF ▸ Model Factory): pick a target unit + a model file, set
transform / size / shading, Bake. Static models bake an Amplitude Skeleton on the proven single-bone vehicle rig +
a packed atlas; ticking Animated takes a parallel path (UniversalBaker.BuildAnimated) that keeps the model's own
armature + clip (Blender slims it, then bakes Skeleton + ClipCollection + atlas, with the clip isolated in a
per-model anim/ subfolder). ModelRegistry writes haf_models.json into the auto-detected BepInEx/config.
Runtime — UniversalInject (Patches/): one patch, any number of models. Reads the registry, registers each baked
skeleton, and on AddOn.Load repoints the matching pawn by self-discovery (reads the host's body-mesh name, renames
ours to match); the skin rides a private layer clone. For animated models it also injects the ClipCollection and,
via a PawnManager.AddPawnEntry hook, drives the pawn's pose onto the clip — matched by pawn descriptor and
normalizing the skeleton id, so every instance plays it.
Founding insight (credit: CalmBreakfast): for a static swap, keep the unit's real skeleton and swap only the mesh —
injecting a mismatched skeleton hangs the GPU skinning. The animated work showed the corollary: a properly baked
custom Skeleton + ClipCollection (built through the SDK's own tooling) can be injected and played without the
hang — the danger was malformed skeletons, not custom ones per se.
| Layer | Technology |
|---|---|
| Runtime plugin (this repo) | BepInEx 5.4 plugin in C#, targeting .NET Framework 4.7.1 (the game's Mono runtime); builds with just the .NET SDK (dotnet build, no Unity needed) |
| Game patching | Harmony (0Harmony) runtime patches against the game's Amplitude.Mercury assemblies — no executable modification |
| Registry parsing | Newtonsoft.Json (shipped with the game, via mod.io) — UnityEngine.JsonUtility silently returns empty objects under the game's Mono runtime |
| Editor tooling (ENCReload) | Unity 2021.3.1f1 (Humankind's own engine version) + the official Amplitude modding SDK, which bakes the native Skeleton / ClipCollection / mesh / atlas assets; editor scripts mirrored here in baker/ |
glbconv converter |
Standalone C# console app on .NET 8 (self-contained single-file exe — adopters need no .NET install), built on SharpGLTF |
| Model-prep scripts | Python run headless inside Blender (blender -b --python …, bpy API) — rigging, decimation, clip extraction |
| Editor ↔ runtime contract | A plain JSON registry (haf_models.json) — the only thing the two halves share |
Built to work on a stranger's machine, not just the author's:
- Auto-detects the game. No hardcoded paths — the Factory finds Humankind via Steam's library config (with a manual override in a Settings panel for odd layouts). Blender is auto-located too.
- No .NET install needed. The GLB/glTF converter ships as a self-contained single-file
glbconv.exethat carries its own runtime — adopters don't need a .NET SDK or runtime. - One injection path. A single
UniversalInjectdrives every model from the registry, so there's one code path to understand and one to trust. - Guided, not guessy. Clip / bone / hide-donor fields are Pick-driven (read from the model + the plugin log); a Settings panel shows the detected Blender path with an in-UI override; every feature that needs Blender warns before a failed bake; and an embedded interactive 3D preview shows the baked model right in the window.
Model files aren't committed — download each per its license, point the Factory's Model file at it, and bake (the
converter extracts it into Assets/FactorySource/<name>/, which stays out of the shipped mod). Authors + licenses in
CREDITS.md (CC-BY requires attribution).
All code, scripts, and docs in this repo are MIT (LICENSE) — fork the plugin, vendor the injection
path, build on it. Two things the MIT grant does not cover, because they aren't ours: the game internals the docs
describe (decompiled Amplitude.* code remains Amplitude Studios' property; the required game DLLs are gitignored
and must be copied from your own install), and any 3D model you bake (each stays under its own license — see
CREDITS.md). The ENC mod's own game-data content lives in the
ENCReload repo and is all-rights-reserved there.
The plugin reads <Humankind>\BepInEx\config\haf_models.json — ENC's base pack (one entry per model: pawn description,
skeleton + atlas GUIDs, transform, shading flags; animated entries add clip + animated/animClip/animateBones),
wrapped with pack metadata (schemaVersion/modId). It then merges any additional packs in BepInEx/config/haf_packs/*.json
and writes a haf_load_report.txt of what loaded. The Factory writes ENC's registry and auto-detects the path; the
field-by-field breakdown is in the Factory Manual and the pack format in Multi-Mod.md.
The plugin's own cfg (…\community.humankind.haf.cfg) — press F8 in-game for a scan/feedback window.
📖 Docs site: https://sswelm.github.io/HumankindAssetFramework/ — the full documentation as a browsable static
site, generated from /docs.
For AI agents: the machine-readable entry point is
llms.txt— fetch it raw athttps://raw.githubusercontent.com/sswelm/HumankindAssetFramework/master/llms.txt. It maps the whole doc set with links that resolve to public raw Markdown, so an agent can crawl everything with no authentication.
The full documentation set, grouped by task (get started · author · ship a pack · internals · project), is indexed in docs/README.md. The fastest starting points:
- Find the right tool: Editor-Tools.md — every authoring window under
Tools ▸ HAF, what it does, and what it writes. - Add a model: Factory-Manual.md — every field, the static + animated workflows, troubleshooting.
- Animate a model: Animated-Models.md — can HAF import your model? The plain-language answer.
- Ship your own pack: Multi-Mod.md — the pack format and the
haf_packs/drop folder. - Everything it does: Capabilities.md — the full capability list + known limitations.
- Project history: CHANGELOG.md — the dated milestone log and the war stories.
HAF is a working, in-game-proven framework. All six axes ship with a verified example, the runtime merges packs from multiple authors, and the ENC reference pack drives a roster of modern-era units. The plugin is stable, has a unit-test suite over its pure-data layer plus an in-game smoke harness, and a full documentation set.
The remaining work is productizing the authoring tools for third-party distribution — the framework itself is done; this is packaging:
- Neutral naming — drop the "ENC" prefix (→
HumankindModelFactory) across the editor tooling. - Package scaffolding — a Unity
package.json/ asmdef and single-DLL plugin packaging. - An install guide + quickstart for adopters bringing their own models.
Already in place toward that goal: zero-config path auto-detection, the self-contained converter (no .NET dependency), one consolidated injection path, full multi-material GLB support, one-click animated import, bake-time skin controls, configurable atlas sizing + bundle slimming, the multi-mod pack loader, and an MIT license on all code.