Add optional apparel sync (equippedItems)

Introduce an optional equippedItems transform extension to snapshot tracked visible apparel slots. Plugin: capture local equipped ARMO form IDs on the game-thread, include equippedItems in transform packets, parse equippedItems on the networking thread, and apply/clear synced apparel on runtime proxies (with defensive logging for missing forms). Server: fake_client parses and prints equippedItems. Docs and protocol updated; changelog and dev-log entry added. Backwards-compatible: equippedItems is optional and empty formId denotes intentional unequip.
This commit is contained in:
2026-06-29 16:02:03 +12:00
parent d0649667f7
commit ad7f287899
13 changed files with 635 additions and 82 deletions
+33
View File
@@ -69,6 +69,10 @@ Example after server processing:
"isJumping": false,
"weaponDrawn": false,
"movementSpeed": 186.4,
"equippedItems": [
{ "slot": "body", "formId": "0001F66A" },
{ "slot": "headband", "formId": "" }
],
"serverTime": 1780212128.3011043
}
```
@@ -92,6 +96,7 @@ isSneaking Optional movement-state flag; defaults to false when missing.
isJumping Optional movement-state flag; defaults to false when missing.
weaponDrawn Optional weapon drawn state; defaults to false when missing.
movementSpeed Optional derived movement speed in game units per second; defaults to 0.0 when missing.
equippedItems Optional full snapshot of tracked visible apparel slots. Each entry has a string `slot` and hex-string `formId`; an empty `formId` means the slot is intentionally unequipped.
serverTime Timestamp added by the server before broadcast.
```
@@ -110,6 +115,34 @@ teleport
Movement state fields are data-only for now. Receivers must treat them as
optional and must not reject older transform packets when they are absent.
Equipment fields are optional and additive. When `equippedItems` is missing,
receivers keep their existing/default proxy appearance. When present, it is a
complete snapshot for the tracked visible apparel slots:
```text
hairTop
hairLong
body
underTorso
underLeftArm
underRightArm
underLeftLeg
underRightLeg
aboveTorso
aboveLeftArm
aboveRightArm
aboveLeftLeg
aboveRightLeg
headband
eyes
scalp
```
The first equipment-sync milestone sends only resolved `ARMO` form IDs and
empty strings for unequipped tracked slots. Power armor, weapon models,
condition, legendary instance data, tint/material overrides, and forms missing
from the receiver load order are outside this packet extension.
### Disconnect Packet
Sent by the server to remaining connected clients when a client disconnects.
+13 -1
View File
@@ -59,8 +59,11 @@ isMoving
isSprinting
isSneaking
isJumping
isCrouching
weaponDrawn
movementSpeed
animationGraphSpeed
equippedItems
lastReceivedLocalTime
```
@@ -71,6 +74,11 @@ Movement state fields are also optional and default to not moving, not
sprinting, not sneaking, not jumping, weapon holstered, and speed `0.0` when
missing.
`equippedItems` is also optional. New clients send it as a complete snapshot of
tracked visible apparel slots with `{ slot, formId }` entries; empty `formId`
values mean that tracked slot is intentionally unequipped. Older clients can
omit the field and receivers keep the proxy's existing/default appearance.
This model proves the data shape and lifecycle before spawning remote actors.
For the current visual milestone, the controller represents only one remote
player and chooses the lowest available `playerId` if more than one remote
@@ -104,6 +112,9 @@ player exists.
resuming smoothing.
- Transform packets include movement state data (`isMoving`, `movementSpeed`,
`isSprinting`, `isSneaking`, `isJumping`, `weaponDrawn`).
- Transform packets can include optional `equippedItems` snapshots for visible
clothing, armor, hats, and eyewear slots. The game-thread proxy controller
applies those snapshots after proxy 3D is loaded.
- The plugin suppresses transform sends and proxy representation in the
`COVault109` solo cell.
- The game-thread proxy controller applies confirmed Havok animation graph
@@ -135,12 +146,13 @@ variable writes drive proxy locomotion visuals.
- Increase concurrent proxy cap beyond four players per client
- Cross-cell actor transfer without respawn (if respawn proves insufficient)
- Power armor and weapon model sync
## Not Required Yet
- Full animation graph sync
- Combat sync
- Inventory sync
- Full inventory sync beyond visible equipped apparel
- Quest sync
- Dialogue sync
- Settlement sync