One ROLLED attribute slot on an owned gear piece. The wire stores the roll as an EquipAttrLibTable ROW id plus a 0–100 roll PERCENTILE — not an attribute id/value pair. Resolve via IGameDataEquip.GetAttrLibRow(LibRowId): each returned entry’s displayed stat is floor(Percentile * (Max - Min) / 100 + Min) (the game’s own formula in equip_attr_parse_vm.lua; verified against the live gear sheet 2026-06-12).
True when the roll came from EquipAttr.equip_attr_set (the current spec’s set): its row id keys the v2 SCHOOL lib table (GetSchoolAttrLibRow), not the v1 table. Resolving it against v1 returned a colliding row’s wrong attrs (in-world 2026-06-13).
One ROLLED attribute slot on an owned gear piece. The wire stores the roll as an EquipAttrLibTable ROW id plus a 0–100 roll PERCENTILE — not an attribute id/value pair. Resolve via IGameDataEquip.GetAttrLibRow(LibRowId): each returned entry’s displayed stat is floor(Percentile * (Max - Min) / 100 + Min) (the game’s own formula in equip_attr_parse_vm.lua; verified against the live gear sheet 2026-06-12).
True when the roll came from EquipAttr.equip_attr_set (the current spec’s set): its row id keys the v2 SCHOOL lib table (GetSchoolAttrLibRow), not the v1 table. Resolving it against v1 returned a colliding row’s wrong attrs (in-world 2026-06-13).