diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index c286ac588..abd2372b1 100644 Binary files a/.voidbot/state/aetheria.cc and b/.voidbot/state/aetheria.cc differ diff --git a/Aetheria.State/README.md b/Aetheria.State/README.md index 781f45dec..6f23f55a8 100644 --- a/Aetheria.State/README.md +++ b/Aetheria.State/README.md @@ -91,6 +91,9 @@ Unity runtime commit DTOs also carry typed `ItemKey`/`HullItemKey` fields for loadout items, action-bar targets, body resources, entity hulls, and active consumables. Their old `*LegacyId` fields remain import/export compatibility only; the commit applier prefers typed keys whenever present. +The package runtime catalog snapshot indexes items by canonical item key; Unity +gameplay, HUD, inventory, trade, ship, and zone helper lookups use `ItemKey` +directly instead of deriving `ItemId` and searching by legacy GUID. The old generic `RuntimeCatalogLink` abstraction, `ItemManager.GetData` hydration path, vague `ItemInstance.Data` identity field, and old `RuntimeItemReference.Projection` cache have been deleted; runtime item facts diff --git a/Assets/Scripts/Gameplay/ActionBarSlot.cs b/Assets/Scripts/Gameplay/ActionBarSlot.cs index 904785c3e..ef942590b 100644 --- a/Assets/Scripts/Gameplay/ActionBarSlot.cs +++ b/Assets/Scripts/Gameplay/ActionBarSlot.cs @@ -169,10 +169,7 @@ public class ActionBarGearBinding : ActionBarBinding private static AetheriaRuntimeCatalogItem FindTypedGearItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } public override void Activate() diff --git a/Assets/Scripts/Gameplay/ActionGameManager.cs b/Assets/Scripts/Gameplay/ActionGameManager.cs index 5e4eda815..e3e8da81c 100644 --- a/Assets/Scripts/Gameplay/ActionGameManager.cs +++ b/Assets/Scripts/Gameplay/ActionGameManager.cs @@ -249,8 +249,7 @@ public class ActionGameManager : MonoBehaviour private ItemInstance CreateLoadoutItem(AetheriaRuntimeLoadoutItemSnapshot item) { - var legacyId = ParseLegacyIdFromReferenceKey(item.ItemKey, "aetheria.item_definition"); - var typedItem = RuntimeCatalog?.FindItemByLegacyId(legacyId); + var typedItem = RuntimeCatalog?.FindItem(item.ItemKey); if (typedItem == null) return null; @@ -1648,10 +1647,7 @@ public class ActionGameManager : MonoBehaviour AetheriaRuntimeCatalogItem FindTypedActionBarItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } var bindings = RuntimePlayerSettings.InputSettings.ActionBarInputs.OrderBy(i => i) diff --git a/Assets/Scripts/Gameplay/EntityInstance.cs b/Assets/Scripts/Gameplay/EntityInstance.cs index 9beca9af3..a0f0b860f 100644 --- a/Assets/Scripts/Gameplay/EntityInstance.cs +++ b/Assets/Scripts/Gameplay/EntityInstance.cs @@ -62,10 +62,7 @@ public class EntityInstance : MonoBehaviour private static AetheriaRuntimeCatalogItem FindTypedHull(ItemInstance hull) { - var itemId = hull?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(hull?.ItemKey ?? ""); } private static Shape ToShape(int width, int height, IReadOnlyList cells) diff --git a/Assets/Scripts/Gameplay/ShipInstance.cs b/Assets/Scripts/Gameplay/ShipInstance.cs index f22e37d89..7e960ccf9 100644 --- a/Assets/Scripts/Gameplay/ShipInstance.cs +++ b/Assets/Scripts/Gameplay/ShipInstance.cs @@ -142,9 +142,6 @@ public class ShipInstance : EntityInstance private static AetheriaRuntimeCatalogItem FindTypedItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } } diff --git a/Assets/Scripts/UI/HUD/SchematicDisplay.cs b/Assets/Scripts/UI/HUD/SchematicDisplay.cs index f77e2d2fa..482755bb2 100644 --- a/Assets/Scripts/UI/HUD/SchematicDisplay.cs +++ b/Assets/Scripts/UI/HUD/SchematicDisplay.cs @@ -144,10 +144,7 @@ public class SchematicDisplay : MonoBehaviour private static AetheriaRuntimeCatalogItem FindTypedWeapon(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - var typedItem = itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + var typedItem = ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); return typedItem != null && !string.IsNullOrWhiteSpace(typedItem.WeaponType) ? typedItem : null; @@ -288,9 +285,6 @@ public class SchematicDisplay : MonoBehaviour private static AetheriaRuntimeCatalogItem FindTypedItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } } diff --git a/Assets/Scripts/UI/Menu/InventoryMenu.cs b/Assets/Scripts/UI/Menu/InventoryMenu.cs index 948aa4bad..7c023dcc4 100644 --- a/Assets/Scripts/UI/Menu/InventoryMenu.cs +++ b/Assets/Scripts/UI/Menu/InventoryMenu.cs @@ -219,10 +219,7 @@ public class InventoryMenu : MonoBehaviour private static AetheriaRuntimeCatalogItem FindTypedInventoryItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } private static int2 RotateTypedShapeCell( diff --git a/Assets/Scripts/UI/Menu/InventoryPanel.cs b/Assets/Scripts/UI/Menu/InventoryPanel.cs index affd7fb52..58aa630d9 100644 --- a/Assets/Scripts/UI/Menu/InventoryPanel.cs +++ b/Assets/Scripts/UI/Menu/InventoryPanel.cs @@ -932,10 +932,7 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler private static AetheriaRuntimeCatalogItem FindTypedInventoryItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } public bool CanDropItem(ItemInstance item) diff --git a/Assets/Scripts/UI/Menu/TradeMenu.cs b/Assets/Scripts/UI/Menu/TradeMenu.cs index ad11db3d4..f87a29287 100644 --- a/Assets/Scripts/UI/Menu/TradeMenu.cs +++ b/Assets/Scripts/UI/Menu/TradeMenu.cs @@ -393,13 +393,7 @@ public class TradeMenu : MonoBehaviour private static AetheriaRuntimeCatalogItem FindTypedTradeItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - if (itemId == Guid.Empty) - { - return null; - } - - return ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } private static double GetTypedBehaviorNumber(TradeRow row, BehaviorFilter behaviorFilter, AetheriaRuntimeBehaviorFieldMetadata field) @@ -469,8 +463,6 @@ public class TradeMenu : MonoBehaviour public AetheriaRuntimeCatalogItem TypedItem { get; } - public Guid LegacyId => Item?.ItemId ?? Guid.Empty; - public string ItemKey => Item?.ItemKey ?? ""; public string Name => !string.IsNullOrWhiteSpace(TypedItem?.Name) ? TypedItem.Name : "Unknown Item"; diff --git a/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs b/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs index 32c02f5f7..8e697db32 100644 --- a/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs +++ b/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs @@ -418,10 +418,7 @@ public class PropertiesPanel : MonoBehaviour private static AetheriaRuntimeCatalogItem FindTypedPropertyItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } private void AddEquippableItemProperties(EquippableItem item, Func statValueFunction) diff --git a/Assets/Scripts/Zone Display/ZoneRenderer.cs b/Assets/Scripts/Zone Display/ZoneRenderer.cs index 33f81f562..d0933f547 100644 --- a/Assets/Scripts/Zone Display/ZoneRenderer.cs +++ b/Assets/Scripts/Zone Display/ZoneRenderer.cs @@ -604,10 +604,7 @@ public class ZoneRenderer : MonoBehaviour private static AetheriaRuntimeCatalogItem FindTypedZoneItem(ItemInstance item) { - var itemId = item?.ItemId ?? Guid.Empty; - return itemId == Guid.Empty - ? null - : ActionGameManager.RuntimeCatalog?.FindItemByLegacyId(itemId.ToString("D")); + return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? ""); } } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs index 56b585e46..5289e9f79 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs @@ -9,6 +9,7 @@ namespace GameCult.Aetheria.State.Unity public sealed class AetheriaRuntimeCatalogSnapshot { private readonly Dictionary _itemsByLegacyId; + private readonly Dictionary _itemsByKey; private readonly Dictionary _corporationsByLegacyId; private readonly Dictionary _nameFilesByLegacyId; @@ -26,6 +27,9 @@ namespace GameCult.Aetheria.State.Unity _itemsByLegacyId = items .Where(item => !string.IsNullOrWhiteSpace(item.LegacyId)) .ToDictionary(item => item.LegacyId, StringComparer.OrdinalIgnoreCase); + _itemsByKey = items + .Where(item => !string.IsNullOrWhiteSpace(item.ItemKey)) + .ToDictionary(item => item.ItemKey, StringComparer.OrdinalIgnoreCase); _corporationsByLegacyId = corporations .Where(corporation => !string.IsNullOrWhiteSpace(corporation.LegacyId)) .ToDictionary(corporation => corporation.LegacyId, StringComparer.OrdinalIgnoreCase); @@ -49,6 +53,11 @@ namespace GameCult.Aetheria.State.Unity return TryGet(_itemsByLegacyId, legacyId); } + public AetheriaRuntimeCatalogItem? FindItem(string itemKey) + { + return TryGet(_itemsByKey, itemKey); + } + public AetheriaRuntimeCorporation? FindCorporationByLegacyId(string legacyId) { return TryGet(_corporationsByLegacyId, legacyId); @@ -142,6 +151,7 @@ namespace GameCult.Aetheria.State.Unity string compoundCommodityCategory) { LegacyId = legacyId; + ItemKey = string.IsNullOrWhiteSpace(legacyId) ? "" : $"aetheria.item_definition:legacy:{legacyId}"; Name = name; Category = category; Description = description; @@ -192,6 +202,7 @@ namespace GameCult.Aetheria.State.Unity } public string LegacyId { get; } + public string ItemKey { get; } public string Name { get; } public string Category { get; } public string Description { get; } diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 77190137b..88dba9479 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -631,7 +631,10 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. references are also typed-key-first (`AmmoItemKey`/`ItemKey`), with `AmmoType`/`Item` only derived GUID compatibility. Runtime commit DTOs now publish item and hull identity through `ItemKey`/`HullItemKey`, with legacy - ID fields demoted to compatibility; + ID fields demoted to compatibility. The package runtime catalog snapshot now + indexes items by canonical item key, and Unity gameplay/UI/zone helper + lookups resolve `ItemKey` directly rather than deriving legacy GUIDs for + `FindItemByLegacyId`; there is no remaining `ItemInstance.Data` identity/backing field. The reader interface for this bridge is named `IRuntimeItemCatalogReader` and exposes only typed catalog row lookup. Behavior @@ -1342,6 +1345,10 @@ First Aetheria surfaces to publish: Loadout items, action-bar targets, body resources, entity hulls, cargo contents, and active consumables now prove typed-key ownership in the Unity smoke by carrying intentionally stale legacy IDs. + - Done: add package runtime catalog lookup by canonical item key and move + Unity gameplay, HUD, inventory, trade, ship, and zone helper lookups off + `ItemId`/`FindItemByLegacyId` detours. Legacy item lookup remains only as + a catalog/migration compatibility API. - Done: delete the dead `ItemManager.GetRuntimeItemProjection` bridge after loadout generation stopped hydrating selected typed rows into `EquippableItemData` merely to instantiate equipment.