62 lines
3.6 KiB
Markdown
62 lines
3.6 KiB
Markdown
# Appearance, wearables, and the Current Outfit Folder
|
|
|
|
`AppearanceManager` owns the client-visible wearable and attachment snapshots.
|
|
Wearables retain their inventory item, asset, asset type, and wearable slot. A
|
|
clothing slot accepts at most 60 ordered layers; body parts are single-value
|
|
slots and replace an existing value of the same type. Sending the outfit emits
|
|
the native `AgentIsNowWearing` packet from a snapshot, then publishes the
|
|
appearance event after the send. Wearable reply and appearance subscribers are
|
|
also snapshotted before invocation, so no state or subscriber lock is held
|
|
during a callback.
|
|
|
|
Attachment calls preserve the inventory owner, name, description, permission
|
|
masks, flags, and requested attachment point in
|
|
`RezSingleAttachmentFromInv`. Add versus replace is encoded in the attachment
|
|
point field, and replace removes only objects at the selected non-default
|
|
point. `DetachAttachmentIntoInv` is keyed by inventory item ID. Queries expose
|
|
the same state by item, item ID, and attachment point.
|
|
|
|
## Current Outfit Folder ownership
|
|
|
|
`CurrentOutfitFolder` discovers the `CurrentOutfit` system folder from the
|
|
inventory store unless an explicit folder has been supplied. Its contents are
|
|
links: link UUIDs identify COF entries and link asset UUIDs identify the worn
|
|
inventory objects. Resolution first consults committed local link targets and
|
|
then the inventory store. This keeps successful mutations immediately
|
|
queryable while an asynchronous inventory reply is still being reconciled.
|
|
|
|
Clothing link descriptions encode the wearable type followed by a two-digit
|
|
layer number. Add chooses the first free layer, preserves existing layers, and
|
|
rejects a 61st layer. Replace removes the selected wearable type before
|
|
allocating its new layers. Body-part and attachment descriptions remain empty,
|
|
matching the reference link format. Folder ancestry and recursive outfit
|
|
discovery are cycle-safe and bounded to 256 nodes.
|
|
|
|
Mutations pass through a one-permit asynchronous operation gate. Waiting for
|
|
the gate is cancellation-aware, but the gate is not an inventory/state lock;
|
|
network awaits never retain a synchronous lock. Cancellation is checked while
|
|
planning and before committing. Once a commit begins, it completes or runs its
|
|
compensation before reporting the result, preventing a cancellation race from
|
|
leaving a half-written outfit.
|
|
|
|
Outfit changes create replacement links before removing old links. If removal
|
|
fails, new links are removed and old link descriptions are recreated. Attach
|
|
creates its COF link before executing the rez request; replacement removes the
|
|
displaced links only after the new attachment succeeds. A later failure
|
|
detaches the new item and restores displaced attachments. Detach similarly
|
|
restores the attachment if its COF link cannot be removed. The local shadow is
|
|
changed only after those network steps succeed.
|
|
|
|
`ICurrentOutfitPolicy` remains a pure decision/reporting boundary. Composite
|
|
policies use a stable subscriber snapshot, consult every policy for attach and
|
|
detach decisions, and invoke reports in registration order. Policy locks are
|
|
released before callbacks and committed changes are reported exactly once.
|
|
|
|
Focused compatibility coverage lives in `current_outfit_folder_semantics`,
|
|
`current_outfit_policy_semantics`, the COF link-description cases, and the
|
|
issue-relevant appearance cases. Native recording fakes additionally prove
|
|
create/remove compensation, create-before-attach ordering, replacement state,
|
|
layer preservation, and cancellation before backend interaction. Texture
|
|
baking, visual-parameter synthesis, and texture upload are a separate
|
|
appearance pipeline and are not owned by this service slice.
|