HumankindAssetFramework

Shared schema library (Haf.Schema)

The model schema’s shared fields are defined once, in a netstandard2.0 library both halves inherit — so the editor and the plugin can’t drift on them.

This page owns the field count. It is the only doc that states a number — the count drifted to three different values across four docs before 2026-08-20; everywhere else now says “the shared fields” and links here. Re-check it with grep -cE '^\s+public ' Haf.Schema/HafModelSchema.cs (minus the class declaration line). The real guard is check_schema_parity.sh, not the number written here.

Shape

Both classes inherit, so the shared fields are still used by name (cur.<field>, e.<field>) exactly as before — no call-site changes.

What’s shared, what isn’t

| Fields | Where | |—|—| | 70 identical fields (string/bool/float/int + the position Vector3) | HafModelSchema — one definition, compiler-enforced | | GUIDs | not sharedint[] skel/atlas/clip (editor) vs sa,sb,sc,sd (plugin): different runtime shapes | | Bake-time-only (size, convertGrid, stripParts, …) | ModelDef only | | Runtime state (resolved handles, *AnimId, session flags, poll dicts) | ModelEntry only |

The plugin’s primary parse is generic: ParseModels deserializes each model with m.ToObject<ModelEntry>(), so every name-matching field (all 70 shared + any plugin-own config) maps automatically — no hand-list. Only two shapes stay explicit: the GUID arrays (one JSON array skel[] → four ints sa/sb/sc/sd, etc.) and position (a UnityEngine.Vector3, which Newtonsoft can’t deserialize — its normalized property self-references — so the key is stripped from the object before ToObject and re-pinned by hand). The per-entry regex fallback (for malformed JSON) still hand-lists every field; check_schema_parity.sh asserts it covers the GUID hand-list + every shared field, and that everything it reads is a field the baker writes. A missing key falls to the field’s initializer in HafModelSchema — the one authoritative default for both halves.

Adding a field

Serialization

Build & deploy

HafModelSchema builds to Haf.Schema.dll (netstandard2.0), referenced by the plugin via a ProjectReference (Private=true), so dotnet build emits it into bin/Release alongside the plugin. The plugin depends on it — BepInEx won’t load the plugin without Haf.Schema.dll in BepInEx/plugins/, so deploy both with tools/deploy-plugin.sh. The editor consumes the same DLL from editor/Plugins/Haf.Schema.dll.