485 lines
30 KiB
Markdown
485 lines
30 KiB
Markdown
# MetaCrate
|
||
|
||
MetaCrate is a test-driven, clean native Rust reimplementation of
|
||
[LibreMetaverse](https://github.com/cinderblocks/libremetaverse). LibreMetaverse
|
||
is a behavioral and API reference only: the finished project must not load,
|
||
host, bind to, invoke, or ship the .NET implementation. The current
|
||
stage is a compiling structural shell: crate boundaries mirror the .NET library
|
||
projects, public C# type names have Rust declarations, every upstream NUnit
|
||
invocation has a traceable catalog entry, and every sample/tool project has a
|
||
Rust binary target. Types, StructuredData, Imaging, PrimMesher, the MeshFoundry rendering adapter, and
|
||
the main assembly's packet/message/asset/primitive wire-data, core
|
||
runtime/networking, avatar-facing manager, world/social/service manager, RLV,
|
||
LSL tools, Utilities, Vivox, and WebRTC slices now have complete callable,
|
||
failure-only signatures. The independent downstream fixture compiles every
|
||
cataloged type and member with zero exclusions, and all 1,289 NUnit invocations
|
||
now have reviewed Rust parity cases. Production behavior implementation is the
|
||
next stage.
|
||
|
||
A case counts as translated only when an explicit Rust test body calls the
|
||
mapped API and retains the upstream identity and body hash. The parity ledger
|
||
now contains zero pending or unreviewed cases.
|
||
|
||
The source snapshot, compatibility rules, dependency research, and ordered
|
||
implementation plan are in [RUSTREWRITE.md](RUSTREWRITE.md).
|
||
|
||
The authoritative compiled .NET surface is checked in as
|
||
[`api/public-api.json`](api/public-api.json). Every type and member has a
|
||
reviewed Rust destination in [`api/RUST-TYPES.tsv`](api/RUST-TYPES.tsv) and
|
||
[`api/RUST-MAPPING.tsv`](api/RUST-MAPPING.tsv); [`api/README.md`](api/README.md)
|
||
documents deterministic regeneration and validation.
|
||
All API crates expose the same typed `Error` for fallible unimplemented members;
|
||
infallible shims use `libremetaverse_types::unimplemented_api!` so placeholders
|
||
cannot look like successful behavior.
|
||
|
||
Building MetaCrate requires Rust 1.96 or newer.
|
||
|
||
```sh
|
||
cargo build --workspace
|
||
cargo test --workspace --no-run
|
||
python3 tools/generate_rust_mapping.py --check
|
||
python3 tools/generate_api_shims.py --check
|
||
python3 tools/check_test_parity.py
|
||
python3 tools/audit_red_suite.py
|
||
```
|
||
|
||
### Optional codec features
|
||
|
||
The default build needs no system image-codec library. It includes the
|
||
project-owned TGA and DDS implementations; the default `dds-bc67` feature uses
|
||
the pure-Rust `bcdec_rs` dependency for BC6H and BC7. Build without BC6H/BC7
|
||
support with `cargo build -p libremetaverse --no-default-features`.
|
||
|
||
The currently available opt-in codec backends are:
|
||
|
||
| Capability | Feature | Build command | External prerequisite |
|
||
| --- | --- | --- | --- |
|
||
| Raw J2K and JP2 decoding/encoding through OpenJPEG | `libremetaverse/jpeg2000` | `cargo build -p libremetaverse --features jpeg2000` | OpenJPEG 2.5.4 or newer |
|
||
| BMP, GIF, ICO, JPEG, PNG, WBMP, and WebP decoding through Skia | `libremetaverse-imaging-skia/skia` | `cargo build -p libremetaverse-imaging-skia --features skia` | A matching rust-skia binary cache, or the documented native source-build tools |
|
||
|
||
Run their focused test suites with:
|
||
|
||
```sh
|
||
cargo test -p libremetaverse-imaging --features jpeg2000
|
||
cargo test -p libremetaverse-imaging-skia --features skia
|
||
```
|
||
|
||
`cargo build --workspace --all-features` enables both optional backends and
|
||
therefore requires both sets of native prerequisites. Platform installation,
|
||
offline-build, cache, and redistribution details are in the
|
||
[`OpenJPEG adapter guide`](crates/libremetaverse-openjpeg/README.md) and
|
||
[`Skia adapter guide`](crates/libremetaverse-imaging-skia/README.md).
|
||
|
||
An independent optional `rust-j2k` backend is planned but has not been
|
||
implemented yet. There is deliberately no enablement command for it today;
|
||
the existing `jpeg2000` feature always selects the OpenJPEG backend.
|
||
|
||
`tests/upstream-tests.json` is the machine-readable NUnit parity catalog.
|
||
Translated tests live in hand-written Rust files with the `parity-case` marker
|
||
documented in `tests/PARITY.md`; `python3 tools/generate_surface.py --check`
|
||
verifies the catalog against the pinned adjacent LibreMetaverse checkout without
|
||
overwriting those files.
|
||
|
||
Running `cargo test --workspace` is intentionally red during the shim stage.
|
||
|
||
## Native implementation progress
|
||
|
||
### Milestone 04
|
||
|
||
Milestone 04 is complete. `libremetaverse-types` now provides
|
||
native UUID, incremental CRC-32, little-endian floating-point byte helpers,
|
||
Vector2/Vector3/Vector3d/Vector4 arithmetic and serialization, Color4 color
|
||
conversion, Ray storage, Quaternion rotation/interpolation/serialization, and
|
||
Matrix4 construction, transforms, inversion, and decomposition. UUID protocol
|
||
bytes use explicit network order while `compat::Guid` conversions preserve the
|
||
mixed-endian .NET byte-array layout. Vector, color, and normalized quaternion
|
||
byte encodings are explicitly little-endian and do not depend on host
|
||
architecture. Matrix4 preserves LibreMetaverse's row-major storage, row-vector
|
||
transform direction, and translation in the fourth row; quaternion components
|
||
are stored as `(x, y, z, w)` and products use the reference Hamilton-product
|
||
direction. All Types enum discriminants retain their C# widths, extensible
|
||
protocol flags preserve unknown bits, and the native conversion layer covers
|
||
numeric and floating-point byte order, UTF-8
|
||
and hex text, hashes and PBKDF2, timestamps, IP addresses, region handles, enum
|
||
metadata, and cross-platform OS detection. The Types collections,
|
||
including duplicate-preserving multi-value and synchronized double-key maps,
|
||
bounded LRU/MRU caches, deterministic absolute and sliding expiration, and
|
||
hierarchical token-bucket throttling are native Rust as well. Cache and bucket
|
||
tests use injected monotonic clocks, and concurrency invariants run without
|
||
sleep-based timing. All 45 Types and all 942 mapped members now resolve to
|
||
native implementations; no generated Types shims remain.
|
||
|
||
### Milestone 05
|
||
|
||
Milestone 05 now has a native, format-neutral OSD value model with structural
|
||
equality and hashing, permissive `LibreMetaverse` conversion defaults, explicit
|
||
integer/date byte order, synchronized snapshot-based arrays and maps, and
|
||
bounded parser dispatch. OSD map order is intentionally unspecified at the
|
||
public model boundary; encoders must choose and document any stable ordering
|
||
they require. Untrusted dispatch limits input bytes, nesting depth, decoded
|
||
nodes, and aggregate binary allocation before returning a value. The native
|
||
Binary LLSD codec covers every reference marker, both accepted headers, exact
|
||
numeric and date byte order, seekable stream overloads, and position-bearing
|
||
errors for malformed or truncated input. Its parser and encoder enforce the
|
||
same byte, depth, node, and allocation bounds; map keys are encoded in sorted
|
||
order to make output stable despite the model's intentionally unordered maps.
|
||
The bounded Notation LLSD codec preserves UTF-16 length-prefix semantics, the
|
||
reference escape rules and accepted scalar spellings, base64, base16 and
|
||
length-prefixed binary forms, and both compact and formatted output. Malformed
|
||
notation reports UTF-16 offsets with parser context, while input, output,
|
||
nesting, node, and aggregate allocation limits apply to untrusted text.
|
||
The native XML LLSD codec covers the wrapper and inner-element APIs, all scalar
|
||
and container elements, namespace-local names, XML declarations, comments,
|
||
CDATA, entity decoding, and the reference's nonstandard Linden processing
|
||
instruction handling. Serialization is compact and deterministic for maps.
|
||
DTD declarations and named entity expansion are disabled; input, output,
|
||
nesting, node, and aggregate allocation limits are enforced with byte-positioned
|
||
parse errors.
|
||
JSON conversion is explicit rather than a derived Serde mapping: integral
|
||
width coercion, empty strings, binary arrays, typed values, and the reference's
|
||
default omission rules retain their C# behavior. Its reader rejects duplicate
|
||
properties and enforces byte, depth, node, and allocation limits while compact
|
||
output uses System.Text.Json-compatible escaping and stable map-key ordering.
|
||
The private OSD Protobuf schema is implemented directly with fixed field tags,
|
||
ZigZag `int32`, little-endian IEEE-754 fixed64 values, 16-byte UUIDs, bounded
|
||
length-delimited containers, and wire-type-aware unknown-field skipping. The
|
||
schema remains an internal compatibility format; native encoders emit stable
|
||
sorted maps and accept the exact optional LLSD Protobuf header.
|
||
Cross-format conversion follows the reference's format-specific boundaries:
|
||
|
||
| Format | Round-trip behavior |
|
||
| --- | --- |
|
||
| Binary LLSD | All regular OSD variants are lossless; raw `OSDLlsdXml` is unsupported. |
|
||
| Notation LLSD | All regular OSD variants are lossless; raw `OSDLlsdXml` is unsupported. |
|
||
| XML LLSD | Regular variants are lossless; raw `OSDLlsdXml` is injected as an element and therefore decodes as that element's ordinary OSD value. |
|
||
| JSON OSD | Booleans, integers, reals, nonempty strings, maps, and arrays retain structure; UUID, date, and URI become strings, binary becomes an integer array, and undefined, empty strings, and raw XML become JSON `null`. |
|
||
| Protobuf OSD | Regular variants are lossless within the reference schema's date range and whole-second precision; raw `OSDLlsdXml` maps to undefined. |
|
||
|
||
Checked-in malformed corpora and bounded deterministic mutations exercise all
|
||
five parsers without an external fuzzing runtime. They cover truncation, tags,
|
||
lengths, payloads, delimiters, nesting, entity rejection, contextual errors,
|
||
and the parser resource limits. Every encoder sorts map keys where necessary,
|
||
so serialization is deterministic across platforms.
|
||
|
||
### Milestone 06
|
||
|
||
Milestone 06 starts with a native `ManagedImage`: top-left-origin,
|
||
byte-per-sample planar storage has an explicit width-byte row stride, with gray
|
||
stored in the red plane and optional color, alpha, and bump planes. Checked
|
||
constructors and resizers cap decoded images at 4096 by 4096 worth of pixels,
|
||
codec adapters cap buffered encoded input at 64 MiB, and canonical
|
||
interleaving accepts explicit row strides without exposing codec-library types
|
||
through the core abstraction.
|
||
The native TGA/Pfim-compatible path decodes uncompressed and RLE true-color,
|
||
grayscale, and indexed TGA data with all descriptor orientations, plus bounded
|
||
legacy and DX10 DDS packed luminance/RGB(A) layouts and BC1 through BC7 blocks.
|
||
TGA output preserves the reference header, BGR(A) order, descriptor choice,
|
||
alpha-only expansion, and deterministic trailing padding. File and stream
|
||
inputs are capped before decoding, and all dimensions, packed rows, palettes,
|
||
packets, masks, and block indices use checked arithmetic with positioned parse
|
||
errors.
|
||
Legacy and DX10 BC1 through BC5 decoding is built in. The default `dds-bc67`
|
||
feature adds BC6H/BC7 decoding through the safe, pure-Rust `bcdec_rs` crate;
|
||
disabling default features removes that optional dependency and makes those
|
||
two formats return a typed unsupported-format error.
|
||
JPEG 2000 is available through the opt-in `jpeg2000` feature. It provides raw
|
||
J2K and JP2 lossless/lossy encoding and decoding, preserves one through five
|
||
component order, precision, signedness, and alpha metadata until explicit byte
|
||
conversion, and bounds encoded input, output, dimensions, and decoded samples.
|
||
The compatibility encoder reproduces CoreJ2K's four-plane RGB/alpha view,
|
||
including its alpha-only and opaque-alpha substitutions. See
|
||
[`crates/libremetaverse-openjpeg/README.md`](crates/libremetaverse-openjpeg/README.md)
|
||
for OpenJPEG prerequisites, licensing, and deployment details. Default builds
|
||
do not discover or link OpenJPEG.
|
||
The optional Skia adapter decodes BMP, GIF, ICO, JPEG, PNG, WBMP, and WebP into
|
||
the same checked planar representation. Its `skia` feature uses pinned
|
||
rust-skia binary-cache configurations on macOS, Linux, and Windows, normalizes
|
||
premultiplied color at the imaging boundary, and keeps encoded input, decoded
|
||
dimensions, strides, and allocations bounded. See
|
||
[`crates/libremetaverse-imaging-skia/README.md`](crates/libremetaverse-imaging-skia/README.md)
|
||
for native prerequisites, cache/source-build controls, licenses, and packaging
|
||
details. Default workspace builds do not compile or link Skia.
|
||
Primitive profile and path meshing is implemented in native Rust from the
|
||
pinned `PrimMesher.cs` reference. It covers checked linear, flexible, and
|
||
circular extrusion; profile cuts and hollows; twist, taper, shear, skew,
|
||
radius, and revolutions; cap and side winding; normals, UVs, viewer faces, and
|
||
prim-face indexing. Geometry allocation and index arithmetic are bounded, and
|
||
identical finite inputs produce deterministic mesh output on every supported
|
||
platform.
|
||
Sculpt maps are sampled through the same checked imaging abstraction and can
|
||
produce plane, sphere, torus, and cylinder topology with reference seam,
|
||
mirror, inversion, LOD, normal, UV, and viewer-face behavior. Native viewer
|
||
indexing deduplicates vertices per prim face, while bounded Wavefront OBJ
|
||
ingestion preserves object/group output and position/UV/normal associations.
|
||
Malformed dimensions, channel layouts, topology, and indices return typed
|
||
errors without partial meshes or panics.
|
||
The milestone-owned feature matrix, rendering-data contract, reproducible
|
||
audit, cross-platform CI commands, bounds, and large-input performance
|
||
baselines are documented in
|
||
[`docs/imaging-meshing.md`](docs/imaging-meshing.md).
|
||
The controlled audit aggregates every expected failure by standardized C#
|
||
member ID and rejects unrelated fixture, assertion, compile, or symbol errors.
|
||
|
||
### Milestone 07
|
||
|
||
The deterministic, Rust-only source-data generator framework and its complete
|
||
pinned input inventory are documented in
|
||
[`codegen/README.md`](codegen/README.md).
|
||
The first native data generator now parses the pinned protocol template into a
|
||
checked-in catalog covering all 483 packets, 905 blocks, exact field widths,
|
||
repetition rules, flags, IDs, and frequencies. It supplies the public
|
||
`PacketType`, deterministic lookup tables, and real default construction and
|
||
sizing behavior for every mapped packet/block while validating the complete
|
||
shape against the pinned compiled C# API catalog. The generated native packet
|
||
codec implements the reference header frequencies and IDs, flags, sequences,
|
||
appended ACKs, little-endian fields, big-endian ports, fixed and length-prefixed
|
||
data, block repetition, zerocoding, bounded decoding, and MTU packet splitting.
|
||
Golden-byte tests and generated round trips cover every packet type without
|
||
requiring the C# toolchain at build or test time.
|
||
The native XML generators also emit all 672 visual parameters and all 21 tree
|
||
and 6 grass definitions from the pinned character and foliage inputs. Generated
|
||
types preserve ranges, defaults, groups, wearables, color/alpha data, driven
|
||
relationships, skeletal/volume morphs, and every foliage rendering property.
|
||
Schema validation rejects malformed or ambiguous input, while sorted visual-ID
|
||
and source-indexed foliage lookups preserve the ordering observable in the
|
||
reference APIs and packet bytes.
|
||
The remaining avatar-data generators emit the full 133-bone/26-collision-volume
|
||
skeleton hierarchy, both masculine and feminine versions of the default and
|
||
updated 11-slot attention tables, and all 24 genepool archetypes with 3,360
|
||
visual-parameter values. Native skeleton traversal, alias lookup, expanded mesh
|
||
joint lists, custom XML loading, attention indexing, and archetype lookup now
|
||
implement the mapped behavior directly in Rust. Each checked-in catalog retains
|
||
its own input hash and license provenance.
|
||
|
||
### Milestone 08
|
||
|
||
The native client core now provides the exact grouped `Settings` defaults from
|
||
the golden C# implementation, validates endpoints, durations, limits, cache
|
||
policy, and download policy, and exposes typed configuration and lifecycle
|
||
errors. `GridClient` construction and drop have no network side effects and do
|
||
not create an async runtime. Explicitly composed services share a cancellation
|
||
token and are shut down idempotently in network, manager, HTTP, then rate-limiter
|
||
order. Injected clocks support deterministic tests, while `Debug` output omits
|
||
endpoint values and service internals. The ownership and executor requirements
|
||
are documented in [`docs/client-core.md`](docs/client-core.md).
|
||
The native Tokio UDP layer now implements the C# packet buffers and throttle
|
||
encoding plus bounded socket receive, coordination, and single-writer tasks.
|
||
It assigns wrapping protocol sequences, aggregates and consumes ACKs, retries
|
||
reliable packets with duplicate suppression, preserves zerocoding and the
|
||
1,200-byte MTU contract, applies independent task/texture/asset token buckets,
|
||
and exposes payload-free transport statistics. All queues, peer state,
|
||
zerocode expansion, ACK state, and reliable windows have explicit limits;
|
||
linked cancellation and final drop release every socket task. The executor,
|
||
wire, backpressure, retry, and security contracts are documented in
|
||
[`docs/udp-transport.md`](docs/udp-transport.md).
|
||
The native network manager now layers ordered packet and CAPS callback
|
||
registries, typed RAII subscriptions, synchronized simulator collections,
|
||
cancellable connection events, ACK-gated circuit setup, current-simulator and
|
||
seed-capability selection, CAPS `EnableSimulator`, UDP `DisableSimulator`, ping
|
||
handling, typed region-handshake replies, two-interval keepalive detection, and
|
||
deterministic disconnect reasons on that transport. Callback lists are
|
||
snapshotted before invocation, and manager/transport workers retain no dropped
|
||
client owner. The ownership,
|
||
dispatch, lifecycle, and fake-server verification contracts are documented in
|
||
[`docs/network-manager.md`](docs/network-manager.md).
|
||
The capability transport is now native Rust as well. `HttpCapsClient` supports
|
||
the C# GET/POST/PUT/PATCH/DELETE and LLSD overloads through an injectable
|
||
`reqwest`/fake-handler boundary, with HTTPS, bounded redirects, gzip/deflate,
|
||
streaming progress, cancellation, explicit request/response/decompression
|
||
limits, and rejection of outbound non-HTTP capability URIs. The per-category
|
||
oldest-first token buckets retain the reference defaults and cap-name mapping.
|
||
The download manager adds a bounded queue and concurrency gate, canonical-URI
|
||
deduplication, subscriber progress fanout, shared cancellation, and transient
|
||
retry handling while preserving permanent 401/403/404/410 failures. Capability
|
||
URLs and tokens are absent from errors and diagnostics. Ownership, limits,
|
||
injection, and offline fake-server coverage are documented in
|
||
[`docs/caps-http.md`](docs/caps-http.md).
|
||
Login is implemented against that transport with the C# password-hashing and
|
||
token rules, viewer/channel/platform fields, start-location normalization,
|
||
bounded redirects, cancellation, and typed status transitions. Native response
|
||
parsing populates session, simulator, inventory, buddy, account-benefit, and
|
||
service fields before the initial UDP circuit and seed capability are installed.
|
||
Credentials and session/capability tokens are redacted from diagnostics, and
|
||
offline fake login/simulator tests cover success, rejection, redirect, timeout,
|
||
and cancellation cleanup. The login contract is documented with the network
|
||
lifecycle in [`docs/network-manager.md`](docs/network-manager.md).
|
||
Region handoff and logout now follow the same packet-level lifecycle as the
|
||
golden implementation: a promoted simulator receives `UseCircuitCode` and
|
||
`CompleteAgentMovement`, while blocking, asynchronous, and nonblocking logout
|
||
send `LogoutRequest`, validate `LogoutReply`, preserve callback ordering, and
|
||
perform bounded idempotent teardown. Shutdown cancels login/logout work before
|
||
closing every simulator and worker, clears session and capability secrets, and
|
||
allows the manager to reconnect cleanly afterward. Loopback fake-server tests
|
||
cover handoff, reconnect, reply, timeout, cancellation, and repeated shutdown.
|
||
Seed-cap discovery and `EventQueueGet` are native Rust too: the full reference
|
||
capability list is posted as LLSD/XML, accepted URIs are rate-categorized, and
|
||
bounded long polls preserve ack IDs, reconnect retries, shutdown `done`, and
|
||
event order. Typed Linden messages share the CAPS dispatch registry; unknown
|
||
messages remain observable and then use the generated caps-to-packet catalog so
|
||
packet handlers receive them through the same bounded pipeline as UDP traffic.
|
||
The milestone gate now drives login, UDP, seed discovery, event-queue region
|
||
enablement, capability download, simulator handoff, and logout through one
|
||
offline fake grid. Native `Simulator.SimStats` uses atomic C#-compatible
|
||
counters and receives real UDP and server-stat updates without exposing packet
|
||
payloads or endpoints. The gate asserts token redaction, bounded policies, and
|
||
joined CAPS/download/network tasks; `tools/check_milestone_08.py` prevents owned
|
||
networking stubs or required audit evidence from regressing.
|
||
|
||
### Milestone 09
|
||
|
||
The first world-services slice provides a native non-movement `AgentManager`
|
||
over the milestone 08 transport. Chat, instant messages and conferences,
|
||
gestures, animation, viewer effects, balance and payments, profiles, notes,
|
||
picks, classifieds, display names, language/access/preferences, experiences,
|
||
viewer reporting, benefits, attachment resources, mute lists, and nav-mesh
|
||
status now use their C#-compatible LLUDP or capability paths. Incoming state is
|
||
updated before callbacks, and callbacks run outside synchronization locks.
|
||
Gesture assets have a native version-2 parser and executor with bounded HTTP
|
||
and UDP download paths. An offline fake grid verifies capability discovery and
|
||
the resulting chat, animation, and sound packets. The ownership, cancellation,
|
||
limits, and compatibility rules are documented in
|
||
[`docs/agent-manager.md`](docs/agent-manager.md).
|
||
|
||
Native movement now covers all control flags, camera frame math, periodic and
|
||
manual `AgentUpdate`, flying/crouching/jumping/sitting/standing, always-run,
|
||
FOV, and autopilot packets. Teleport requests and UDP/CAPS progress messages
|
||
share cancellation-safe waiters, while region handoffs use a bounded,
|
||
diagnosable crossing state machine with recovery to the old simulator. Paused
|
||
time tests and a loopback fake grid verify exact wire fields and clean worker
|
||
shutdown. The compatibility and lifecycle contract is documented in
|
||
[`docs/agent-movement.md`](docs/agent-movement.md).
|
||
|
||
Native inventory now preserves the complete item/folder model hierarchy,
|
||
permissions, concrete subclasses, parent/descendant counts, link resolution,
|
||
root/library semantics, system-folder lookup, and C# sort flags. Local mutation
|
||
is transport-independent and observer callbacks run after locks are released.
|
||
The versioned 64 MiB-bounded cache validates complete snapshots before install
|
||
and uses same-directory temporary replacement with rollback. The compatibility
|
||
and persistence contract is documented in
|
||
[`docs/inventory.md`](docs/inventory.md).
|
||
|
||
Native asset models now enforce bounded format decoding, real JPEG 2000 and Ogg
|
||
Vorbis codec boundaries, client-owned capability and LLUDP downloads, complete
|
||
small/Xfer and two-stage capability uploads, independent cancellation for
|
||
deduplicated HTTP subscribers, and atomic size-pruned disk caching. The ownership,
|
||
correlation, and corruption contracts are documented in
|
||
[`docs/assets.md`](docs/assets.md).
|
||
|
||
Deterministic OAR/tar IO, bounded GLTF/GLB and Collada conversion, material
|
||
resolution, and opt-in mesh pricing/upload now use the same native asset and
|
||
capability layers. Their archive safety, offline determinism, and live-upload
|
||
boundaries are also documented in [`docs/assets.md`](docs/assets.md).
|
||
|
||
The client-owned `InventoryManager` now implements the packet-level create,
|
||
update, move, copy, remove, fetch, search, give, rez/derez, script-state, and
|
||
task-inventory workflows. Callback IDs and concurrent item/task waiters are
|
||
bounded and cancellation-safe; generated multi-block packets retain the UDP
|
||
codec's MTU-aware splitting. Capability replies and UDP replies are validated
|
||
before store reconciliation, and legacy task inventory uses a 16 MiB-bounded
|
||
`ReplyTaskInventory`/`RequestXfer` state machine. Focused translated and native
|
||
fake-packet tests cover correlation, stale replies, offers, bulk completion,
|
||
capability task inventory, and malformed transfer sizes.
|
||
|
||
The client-owned `InventoryAISClient` implements Inventory/Library API v3
|
||
category, child, link, item, outfit, orphan, and trash resources with exact
|
||
LLSD XML request shapes and `COPY` destination headers. Parsed objects,
|
||
side-effect removals, and folder versions are validated and reconciled through
|
||
one atomic store transaction; cancellation and malformed responses cannot
|
||
partially mutate the cache. Focused compatibility and injected-HTTP tests cover
|
||
link correction, endpoint recording, error isolation, and metadata updates.
|
||
|
||
The milestone closes with one deterministic cross-manager fake-grid scenario
|
||
and a reproducible owned-test runner. The scenario covers authenticated agent
|
||
state, movement and handoff, shared inventory/AIS state, assets and appearance,
|
||
avatar/animesh and object entry points, land and discovery caches, social,
|
||
estate, experience and marketplace construction, ordered events, redacted
|
||
diagnostics, clean logout, and root cancellation. The complete audit and test
|
||
boundary is documented in
|
||
[`docs/world-milestone-gate.md`](docs/world-milestone-gate.md).
|
||
|
||
Native appearance state now tracks layered wearables and attachment points,
|
||
sends the inventory-backed wearable and attachment LLUDP messages, and exposes
|
||
worn queries by slot, item, and point. The client-owned Current Outfit Folder
|
||
service resolves inventory links, preserves layer descriptions, serializes
|
||
concurrent mutations through a cancellation-aware gate, and compensates failed
|
||
link or attachment replacement without publishing partial local state.
|
||
Composite policies make pure decisions from snapshots and receive committed
|
||
changes after synchronization is released. The behavior and transaction
|
||
boundaries are documented in [`docs/appearance.md`](docs/appearance.md).
|
||
|
||
The appearance service now completes cached, local, and server-side baking for
|
||
all 11 bake targets. It parses wearable parameters and texture indices,
|
||
downloads and decodes texture inputs through a bounded provider abstraction,
|
||
composites color/alpha/bump layers, uploads JPEG2000 bakes, builds the complete
|
||
appearance packet, and handles cache and forced-rebake messages without locks
|
||
crossing awaits or callbacks. First-login outfit setup performs a bounded
|
||
library copy and transactional COF application with monotonic progress,
|
||
cancellation, and compensation. Exact mappings, hashes, generated visual data,
|
||
pixels, packet/event payloads, and recovery behavior are covered by focused
|
||
tests and documented in [`docs/appearance.md`](docs/appearance.md).
|
||
|
||
Native land services now correlate parcel overlays, properties, access lists,
|
||
owners, dwell, remote lookups, and bounded script-resource capabilities while
|
||
maintaining the simulator's four-metre parcel map. The 16×16 terrain codec
|
||
handles normal and rectangular large-region patches, wind layers, and four-slot
|
||
PBR material overrides. Extended and legacy environment LLSD paths preserve
|
||
parcel-versus-region URI rules, and sound packets retain identity, gain,
|
||
position, and queue flags. Packet/capability selection, state-before-event
|
||
ordering, cancellation, limits, and live-operation safety are documented in
|
||
[`docs/land.md`](docs/land.md).
|
||
|
||
Estate administration, experience preferences, marketplace listings, and
|
||
abuse reporting now use native owner-message, capability, event, cache, and
|
||
legacy-packet paths. Exact schedules, list deltas, folder roles, report fields,
|
||
cancellation, and explicit live-operation gates are documented in
|
||
[`docs/world-services.md`](docs/world-services.md).
|
||
|
||
Grid and directory discovery now use native LLUDP map and search requests,
|
||
correlated bounded reply events, expiring region indexes, coarse-location
|
||
deltas, and exact region-handle math. SLURL parsing covers location and
|
||
application forms with stable escaping, while interest-list modes and unknown
|
||
simulator features are preserved through LLSD capabilities. The cache,
|
||
pagination, cancellation, and compatibility contracts are documented in
|
||
[`docs/discovery.md`](docs/discovery.md).
|
||
|
||
### Milestone 10
|
||
|
||
The native `SimpleRenderer` is the milestone's deterministic reference
|
||
pipeline for legacy prim and decoded sculpt-map geometry. It converts checked
|
||
PrimMesher output into shared faceted and simple meshes, preserves prim-face
|
||
texture/material metadata, supplies finite normals and UVs, applies default or
|
||
planar texture transforms, and reports bounded failures with the source
|
||
primitive UUID. It deliberately does not fetch or decode mesh assets; that
|
||
surface remains with MeshFoundry. Supported topology, 16-bit geometry budgets,
|
||
determinism, and the asset boundary are documented in the
|
||
[`SimpleRenderer` guide](crates/libremetaverse-rendering-simple/README.md).
|
||
|
||
The native `MeshFoundry` pipeline builds on that reference path for prims and
|
||
sculpts, and adds bounded packed-LLSD mesh assets, deterministic LOD fallback,
|
||
terrain and convex hulls, independent UV domains, generated or stored normals
|
||
and tangents, inherited material metadata, mirror/invert transforms, and
|
||
rigged-mesh skin matrices and normalized weights. A large executable fixture
|
||
reports decode allocations and timing without replacing correctness gates. The
|
||
format, ownership, error, and tangent-output contracts are documented in the
|
||
[`MeshFoundry` guide](crates/libremetaverse-rendering-mesh-foundry/README.md).
|
||
|
||
The native RLV layer parses bounded chat messages into typed clear, action,
|
||
restriction, and query directives, then provides independent thread-safe
|
||
restriction, inventory-map, folder-lock, camera, blacklist, and permission
|
||
providers without network I/O. Its callback-driven service dispatches typed
|
||
actions and queries through `Send + Sync` host adapters, integrates completed
|
||
inventory and agent services through their public boundaries, and reports
|
||
inventory, attachment, outfit, chat, sit, and object-source lifecycle events.
|
||
It
|
||
preserves source casing, folder paths, separators, numeric channels, UUIDs, and
|
||
attachment/wearable aliases while exposing canonical behavior names and
|
||
source-located typed errors. All 119 restriction names from the pinned
|
||
LibreMetaverse snapshot are covered, and deterministic malformed-input
|
||
mutations exercise the parser without an external fuzzing runtime. Immutable
|
||
snapshots and post-lock update events make concurrent policy reads
|
||
deterministic; cancellation and resource limits are checked before callbacks,
|
||
and no callback runs under an internal lock. The grammar, state precedence,
|
||
normalization rules, service orchestration, limits, and ownership boundary are
|
||
documented in the
|
||
[`RLV protocol guide`](crates/libremetaverse-rlv/README.md).
|