Add appearance tint syncing (appearance v3)

Introduce tint syncing for skin/complection/makeup/beard by adding RemoteAppearanceTint and a tints vector, and bump appearance payload version to 3. Parse/emit tints in networking and update fake server/client test payloads. Capture live Player/NPC tintingData during appearance capture. Apply tints to proxies by updating existing entries or reconstructing missing ones via template resolution and MakeTintEntry (game allocator + vtable fixup); unresolved templates are skipped with throttled warnings. Update docs/changelog and add logging for applied tints. Backwards compatible with v1/v2 packets.
This commit is contained in:
2026-06-30 22:07:49 +12:00
parent 5b54db64d4
commit 76fd8772bd
10 changed files with 317 additions and 9 deletions
+11 -3
View File
@@ -74,7 +74,7 @@ Example after server processing:
{ "slot": "headband", "formId": "" }
],
"appearance": {
"version": 2,
"version": 3,
"raceFormId": "00013746",
"height": 1.0,
"morphWeight": { "thin": 0.0, "muscular": 0.0, "large": 0.0 },
@@ -84,7 +84,8 @@ Example after server processing:
"headParts": [],
"morphs": [],
"morphRegions": [],
"facialBoneMorphs": []
"facialBoneMorphs": [],
"tints": []
},
"serverTime": 1780212128.3011043
}
@@ -162,7 +163,7 @@ receivers keep the proxy's existing/default body and face. When present, it is a
best-effort snapshot for male-proxy-compatible runtime visuals:
```text
version Appearance payload version. Current value is 2.
version Appearance payload version. Current value is 3.
raceFormId Hex-string race form ID captured for diagnostics/future use; receivers do not switch proxy race yet.
height NPC height scalar.
morphWeight Body triangle weights: thin, muscular, and large.
@@ -173,12 +174,19 @@ headParts Hex-string `HDPT` form IDs for the sender's current head p
morphs Morph slider values as `{ "id": hex-string, "value": number }` entries.
morphRegions Region morph slider values as a flat array of numbers (added in version 2).
facialBoneMorphs Bone-based facial morphs as `{ "id": hex-string, "position": [x,y,z], "rotation": [x,y,z], "scale": [x,y,z] }` entries (added in version 2).
tints Character tint layers (skin tone, complexion, makeup, beard shade) as `{ "id": number, "type": number, "value": number, "color": hex-string, "swatch": number }` entries (added in version 3). `id` is the race tint-template uniqueID, `type` is the tint entry type (0 mask, 1 palette, 2 texture), and `value` is the 0-255 intensity. `color` (ARGB hex) and `swatch` are present only for palette entries.
```
`morphRegions` and `facialBoneMorphs` are optional and additive. Version 1
senders omit them; receivers must treat their absence as "no change" and keep
existing proxy morph data.
`tints` is optional and additive (added in version 3). Earlier senders omit it;
receivers must treat its absence as "no change". Receivers apply a tint by
matching `id` against an existing proxy tint entry (updating intensity/color in
place) and only reconstruct a missing entry when the proxy race exposes a
matching tint template, skipping unresolved tints rather than failing.
Receivers must treat missing or malformed appearance subfields as non-fatal and
apply only the parts they can resolve locally. Gender is intentionally not part
of this payload yet; female proxy support can add it later.