ExtractLean clamps itemID > TileData.MaxItemValue to 1; MaxItemValue is 0 when
tiledata.mul is missing (CI), so Katana's 0x13FF only survives with client data.
Guard with [SkippableFact] + TileDataRequirement.SkipIfMissing() like other
data-dependent tests. The hue/cliloc assertion needs no data and stays a [Fact].
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
BuildTree previously grew each category's Nodes array by one element per
object via AppendObject/AppendNode, causing O(N^2) array copies across large
categories (e.g. Items.Uncategorized) on every server startup. Leaves are
now accumulated per-category in a List and flushed with a single array
allocation per category via a new AppendNodes helper. AddFallbackForStaleCache
and LoadLegacy are untouched.
Also adds a JSON round-trip test for ObjectIndexFile/ObjectIndexEntry to
guard the gfx/hue property mapping and the Objects = [] initializer against
double-appending on deserialize.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CAGLoader.Load() now reads Data/objects/index.json (BuildTree) and only
falls back to live type instantiation for entries missing from the
cache (stale-cache warning) or when the index file itself is absent
(LoadLegacy, the original categorization.json live-load, moved verbatim).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wraps introspection, categorization sync, and cache-building into a
single file-I/O-free Generate() so the full pipeline is testable
without a shard; GenObjects is a thin command that adds file I/O and
operator messaging on top.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implement DiscoverConstructibleTypes() method with HasConstructibleCtor helper
to enumerate every non-abstract Item/Mobile subclass in AssemblyHandler.Assemblies
that has at least one [Constructible] ctor.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add ObjectIntrospection.ExtractProperties(Type) to extract public instance
properties carrying [CommandProperty] attribute, including inherited ones.
Properties include type via ObjectNaming.FriendlyTypeName, read/write access
levels, readOnly flag, and enum values expanded via Enum.GetNames.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>