Resolve runtime catalog items by typed keys

This commit is contained in:
Meta Vens 2026-06-15 00:49:54 +01:00
commit 4891c7fafc
14 changed files with 34 additions and 52 deletions

Binary file not shown.

View file

@ -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<T>` abstraction, `ItemManager.GetData`
hydration path, vague `ItemInstance.Data` identity field, and old
`RuntimeItemReference.Projection` cache have been deleted; runtime item facts

View file

@ -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()

View file

@ -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)

View file

@ -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<AetheriaRuntimeShapeCell> cells)

View file

@ -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 ?? "");
}
}

View file

@ -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 ?? "");
}
}

View file

@ -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(

View file

@ -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)

View file

@ -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";

View file

@ -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<PerformanceStat, float> statValueFunction)

View file

@ -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 ?? "");
}
}

View file

@ -9,6 +9,7 @@ namespace GameCult.Aetheria.State.Unity
public sealed class AetheriaRuntimeCatalogSnapshot
{
private readonly Dictionary<string, AetheriaRuntimeCatalogItem> _itemsByLegacyId;
private readonly Dictionary<string, AetheriaRuntimeCatalogItem> _itemsByKey;
private readonly Dictionary<string, AetheriaRuntimeCorporation> _corporationsByLegacyId;
private readonly Dictionary<string, AetheriaRuntimeNameFile> _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; }

View file

@ -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<T>` bridge
after loadout generation stopped hydrating selected typed rows into
`EquippableItemData` merely to instantiate equipment.