From 4891c7fafcdac715ed3ee4b821746b3f2fd82c44 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 15 Jun 2026 00:49:54 +0100 Subject: [PATCH] Resolve runtime catalog items by typed keys --- .voidbot/state/aetheria.cc | Bin 91948 -> 92479 bytes Aetheria.State/README.md | 3 +++ Assets/Scripts/Gameplay/ActionBarSlot.cs | 5 +---- Assets/Scripts/Gameplay/ActionGameManager.cs | 8 ++------ Assets/Scripts/Gameplay/EntityInstance.cs | 5 +---- Assets/Scripts/Gameplay/ShipInstance.cs | 5 +---- Assets/Scripts/UI/HUD/SchematicDisplay.cs | 10 ++-------- Assets/Scripts/UI/Menu/InventoryMenu.cs | 5 +---- Assets/Scripts/UI/Menu/InventoryPanel.cs | 5 +---- Assets/Scripts/UI/Menu/TradeMenu.cs | 10 +--------- .../UI/Properties Panel/PropertiesPanel.cs | 5 +---- Assets/Scripts/Zone Display/ZoneRenderer.cs | 5 +---- .../Runtime/AetheriaRuntimeCatalogSnapshot.cs | 11 +++++++++++ docs/aetheria-perfect-machine-map.md | 9 ++++++++- 14 files changed, 34 insertions(+), 52 deletions(-) diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index c286ac588a130bb497459f0610b1a82eda9ab672..abd2372b19b9b1f80628a9392d8bae26e2995a53 100644 GIT binary patch delta 1696 zcmZuyU1%It6n64cTcNcC>Z*u2P=rRZv)h>Frz)jMs;(AOQ}bYqKX+$NcCVS4JKTF` zlP$c3LAPV{p+*RvBLF;78krAb34DUuqE7)fnAe7<=W8>{{m2U#54V3ycP>5L z$+xJiACG)oMMX13BH|tkvZ;WkQXnFau;FSf6ptG46zw$)Pno%?>yQg}yc{ka4nWaI z1&P88Ta9ors^S(veJ(rb>7f1iZn>%U#SCiArx`;=qfq0Z4Xog~67q&*nu`cL5yteZ z&I3d1`Aao-O=G0!)Ap~X#lC)2&@gI=DA#7p>5%JAHj&h@#4+#{D9s5su5zV;5fS@Z z#8SLLc&UMM;WEk=%8F_-Ndz~L)V8opo4OPvr6dBvB(Tc_wOQ0}vKE38KG(1}*uM-!KPdEmrGKvc3BW zY2Fla4wuxAcTKKWzx~p2Cepue4HlCACo%4|4~UBGN7H++mDZE*zV91;;v(@$oMez# zCPBH*q_ro7f%0QnCaf4Kf&`Yu~YCwGoLJ2iKJ78S8rHHkM0sv!sO zBshz~{^^aoEUJ^~?Ke-ElG7tEn!JJ(E2;=&p2WR(f&vO??s)eGwn$Y{*s^iD`+n6~ zT>tsc*@s-$#^<1VMgwbAP@z~xh?!F8Z*-13e>rzsNSC{xA9cp=%e$5-bRk8yY=!Us zbJQ8^ylSgYA^FaeJl2`DdG1Y#I*}3C_`)jJ(}ISo0$b8#U@t%>Grhr2Vv?F^ggWAD zb>=N2Vau+$oSIqLAO|)`31e@%M9vnM-I;cUJe*x;g`xH&-OQK;mhx#YPam~NWO{q8 zbne{qqNsAGNPe%CO?nR6$euNlm{6t8&HKC82b@O+?Cn1`KDqFrW)1S<>lL3a(vq}Estc1wYMLiVN<{)Ty)$#(o7>FXJH7YL z8)x+@E(M{?;z76l1MNb1XxtSSU5FqWTr{Oi-APNSi!OWa%)HkhQrx_GoO?Lu`@8q% z#_)~bhkv*>@baOlV}}pbre|kYE;_sNTLa%zm6@Y6w$l0VjI%9I22HO#Q#OtajSYNu zzk6V4`PcTlb7%rooPkP&;Squ-qlg>e1|wL*3}h-$>43-AbrMBPWt;8gEn0P=8q7lt zLZ;v`r7|#Cj6N*Vpe4*EK2E~0`VS3`p|9VEu#HXTWw5wVm4K-NLCg$ydB{x$Jc^|< z6Zob5fD~a?yXu9EM|Yezd*CZTb;*307`x?o!D1Yq>zMNlmtvl&c`ke|n(Y_#%}YO9 zMlBQN;R{+mBDqX>LIq(@HeI`JP-x<`xp`Vxxm;$vAd)@;`rJrm{fv2tkfPrtJGcNc z92V;kOKlFuN|I@s`pADW8d$^7uL-z@cFeS{!KchyV@(7%;h_(fpf=1P=t!=S-?j<; zaXL1@zzdNHD4{$DfPnklGeB}BG{{9zNJ}9Nu*6jLr&6sE1g=LQKo*)H%g_Hf+P=LY zDO(1NLS~9oEntHaXChxO^jP$Pc=U3%#VOMj^fJ>{3xO%vg*8}0j3HGtPc*GWQIR!h zR1(T3iA)2l=l`V}e8pP`ERMsBL^6RcwX>=Lr5Qa^k+AF9cT9MJRLj`VcVC+R`ZAfm zSw7NI>ICdPU@1)D+BTr#y*ZcmM6b-`IHr zTQ9n~7}g{qSJ!WiI&TlJKicOUIKHEQoc}Sn zuX+z>CyV#6<9^}X?3Jb_doO3wFHIMvzs@*cjg(_%kK_*q_pF;$=a(J5t|OBxj{%fq B3_}0_ 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.