From 95bd76ee917360cd2f050807ee2cba70b4574541 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 14 Jun 2026 23:31:54 +0100 Subject: [PATCH] Use typed item keys in behavior item refs --- .voidbot/state/aetheria.cc | Bin 89921 -> 91288 bytes Aetheria.State/README.md | 8 ++++---- .../AetheriaRuntimeItemReference.cs | 5 +++++ .../ServerShared/Behaviors/ConstantWeapon.cs | 6 +++--- .../ServerShared/Behaviors/InstantWeapon.cs | 6 +++--- .../ServerShared/Behaviors/ItemUsage.cs | 7 ++++--- .../Scripts/ServerShared/Behaviors/Weapon.cs | 8 ++++++-- Assets/Scripts/ServerShared/ItemManager.cs | 11 ++++++++-- Assets/Scripts/UI/HUD/SchematicDisplay.cs | 2 +- docs/aetheria-perfect-machine-map.md | 19 ++++++++++++------ 10 files changed, 48 insertions(+), 24 deletions(-) diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index 4481ec5dc81891194ab42bf45114eac1587e0f36..89a4bc4891926e450f629d023ee4fcf26230229b 100644 GIT binary patch delta 2052 zcmcIlO>7%Q6lR;GO#)R))g&|$Vkl}+P`s`Z8sY#gX-rx}LekczQZSIo?s#{|?#yO( z)`_8#L2y8V185J+g%gDWLV$=wF8m%)RdIoGK$f^7uCxaZ91w5z$8nH)-qeHJ-y?F=@SKgVm!RjH5~r1=Z*e!W1_J9wl)~@t{1bN2Pfm5-tK$$ zl%Lre?LK#{*}8XzNSg?X(JHZVopOPwBrX!9Mg(C7@vr!S>tfMpy>yXak28c_mm|!~ zI4~FZWGB_&tVS&#F}{I($pt~O;gKW~t&xWRFgjBy6_F>nM}(wJ;v)=ECR9*|ID@+$ zmUNXmR5n!93&fC=Ghct-a4>aSeo~lv>RD5iaG$~C$ ze1oCpt(w;3v<1u{Pw1ypXqIrp;n+M+Fchq32SL+yXvRk_wFH*X#yqjG(I}ZuV<#XT zP$J4C?}VhOFhLw(Mpz;POYCq9sXO#5k}w}yZ(ThtU`+%P0h81vW5~yK_^p)2kR3SA z7$UGQ0Rh!5j`7N^V$lH~0#I!q7@>}nVjcHaI%XmuoGS$&CoVeX$A?0Z=U`x8M`fEt zrwZEe7^(^G?lkEoU}SmJ%q}3C)DK^Ne5m<*k%JN>0FY=wQJ(|Y0ijq!sn%i%kxgO* zifSFr1u_6lz!FZhdEl7H<#mvft*~@4Wt3Sl2>G3E^9qWNmI2jft=1Nn;;IDK0z#w? zcm>#T8t~O25^mb1x?KVVeQwx<0X2?8gc3He!$1>=5oiNSa`lffGi)x-lbZkAZIiFQ z2i9rLFJU7zR|?^y*Y|Io_}SLNR&D zKi5CJJN&}BFFHP@_3uqQ5Uy+tEiGkkg_b)_gUF`G!LuFSLD-MM&8q3-s67Y5(G9&% z!5Di9t{8rzy-J*wp6tic0!t=nXS^a96mX3i2RTqZASx^cCSMCYJ-Rfn6`RlfZ$48t z(?20~YO0ZzFqKP~I%RUnh(xPFbaGmo-#U2X>fvVcX<>G{TJeGQ>H?9tI^%goaArsaQo^S$)wkAPuhC?tz>j9N$gGyT|Q7Hl9M2-jnUVs0@uu=i$6PG~d+2PX2sgtl3bm6% z#Ydj%yaUzXgQ;r!kJt0ii5nX|;a&MDtMp=YU{N~~zW&-k_}0xHEg!ye^HBKMyZb`@ z%@OS@wHkl{=KI7zoQUOzVyv7&YaPJqAr(#WWHQF{Q69MtmBojuyIs9Dqw zXkV-UgIP?d{diaOXTNszVDe&)7YfUlCAPrD&u-s;yY@@>u7 z1kP|;V_pc_dFgsgRCm8mEr-I#Imx8lhya$O7srslzHOdO(*$CXF!BP)T?mJ+{si-0>4c?Rs`>0 z4=ytmpwpqiFlrEZigAZ7R1{9z|Hk;N0Uk3znMv?_+E6lQ$P|?eFD}iJQ+-wJ!hCJg zO>~Xga{=|&*QT=bza|x0We_8z2^0_AlteB~F`X|Yhx<6qYHg%8gk(69v!>?~)2Yu) zB|bAx&aPTZh8lJxsxV}9cF!8RB21+@kOPi`R+z-==mF|%n36I{gFkS@S;xy&QNeX6 z>7R#29zMr8yH~H(i}x;V41NnqyxvcaPfyP>9~HVP;F|g%xqTCOIYMYu?MDK7Zam>-haG^084GO` 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/ServerShared/AetheriaRuntimeItemReference.cs b/Assets/Scripts/ServerShared/AetheriaRuntimeItemReference.cs index b7df3cabd..df6c7d949 100644 --- a/Assets/Scripts/ServerShared/AetheriaRuntimeItemReference.cs +++ b/Assets/Scripts/ServerShared/AetheriaRuntimeItemReference.cs @@ -38,6 +38,11 @@ public class AetheriaRuntimeItemReference return legacyItemId == Guid.Empty ? "" : $"{LegacyItemDefinitionPrefix}{legacyItemId:D}"; } + public static Guid ToLegacyId(string itemKey) + { + return TryParseLegacyId(itemKey, out var itemId) ? itemId : Guid.Empty; + } + private static bool TryParseLegacyId(string itemKey, out Guid itemId) { itemId = Guid.Empty; diff --git a/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs index 11409bc11..14c256e18 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs @@ -84,7 +84,7 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior OnStopFiring?.Invoke(); return false; } - if (_data.AmmoType != Guid.Empty) + if (!string.IsNullOrWhiteSpace(_data.AmmoItemKey)) { if (_reloading) { @@ -104,10 +104,10 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior if (_data.MagazineSize > 1 && _ammo > 0) _ammo--; else { - var cargo = Entity.FindItemInCargo(_data.AmmoType); + var cargo = Entity.FindItemInCargo(_data.AmmoItemKey); if (cargo != null) { - var item = cargo.GetFirstItem(_data.AmmoType); + var item = cargo.GetFirstItem(_data.AmmoItemKey); if (item is SimpleCommodity simpleCommodity) cargo.Remove(simpleCommodity, 1); diff --git a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs index 85921bae4..f36cc0032 100644 --- a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs @@ -127,12 +127,12 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior } var hasAmmo = true; - if (_data.AmmoType != Guid.Empty) + if (!string.IsNullOrWhiteSpace(_data.AmmoItemKey)) { - var cargo = Entity.FindItemInCargo(_data.AmmoType); + var cargo = Entity.FindItemInCargo(_data.AmmoItemKey); if (cargo != null) { - var item = cargo.GetFirstItem(_data.AmmoType); + var item = cargo.GetFirstItem(_data.AmmoItemKey); if (item is SimpleCommodity simpleCommodity) cargo.Remove(simpleCommodity, 1); } diff --git a/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs b/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs index 949543508..d764f06e2 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs @@ -7,7 +7,8 @@ using System.Linq; [Inspectable, Order(-5)] public class ItemUsageConfig : RuntimeBehaviorConfig { - public Guid Item; + public string ItemKey; + public Guid Item => AetheriaRuntimeItemReference.ToLegacyId(ItemKey); public override Behavior CreateInstance(EquippedItem item) { @@ -36,10 +37,10 @@ public class ItemUsage : Behavior public override bool Execute(float dt) { - var cargo = Entity.FindItemInCargo(_data.Item); + var cargo = Entity.FindItemInCargo(_data.ItemKey); if (cargo == null) return false; - var item = cargo.GetFirstItem(_data.Item); + var item = cargo.GetFirstItem(_data.ItemKey); if (item is SimpleCommodity simpleCommodity) cargo.Remove(simpleCommodity, 1); if (item is CraftedItemInstance craftedItemInstance) diff --git a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs index c7250668a..1b41e2386 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs @@ -43,7 +43,8 @@ public abstract class WeaponConfig : RuntimeBehaviorConfig [InspectablePrefab] public PerformanceStat Visibility = new PerformanceStat(); - public Guid AmmoType; + public string AmmoItemKey; + public Guid AmmoType => AetheriaRuntimeItemReference.ToLegacyId(AmmoItemKey); [InspectablePrefab] public int MagazineSize; @@ -69,9 +70,10 @@ public abstract class Weapon : Behavior, IActivatedBehavior public abstract int Ammo { get; } public DamageType DamageType { get; } public string EffectPrefab { get; } + public string AmmoItemKey { get; } public Guid AmmoType { get; } public int MagazineSize { get; } - public bool UsesAmmo => AmmoType != Guid.Empty; + public bool UsesAmmo => !string.IsNullOrWhiteSpace(AmmoItemKey); public GuidedProjectileTargetMode GuidedProjectileTargeting { get; private set; } public bool HasGuidedProjectileProfile => GuidedProjectileTargeting != GuidedProjectileTargetMode.None; public float4[] GuidedProjectileGuidanceCurve { get; private set; } @@ -102,6 +104,7 @@ public abstract class Weapon : Behavior, IActivatedBehavior _data = data; DamageType = data.DamageType; EffectPrefab = data.EffectPrefab ?? ""; + AmmoItemKey = data.AmmoItemKey; AmmoType = data.AmmoType; MagazineSize = data.MagazineSize; InitializeGuidedProjectileProfile(data); @@ -112,6 +115,7 @@ public abstract class Weapon : Behavior, IActivatedBehavior _data = data; DamageType = data.DamageType; EffectPrefab = data.EffectPrefab ?? ""; + AmmoItemKey = data.AmmoItemKey; AmmoType = data.AmmoType; MagazineSize = data.MagazineSize; InitializeGuidedProjectileProfile(data); diff --git a/Assets/Scripts/ServerShared/ItemManager.cs b/Assets/Scripts/ServerShared/ItemManager.cs index 23c577840..41aa13052 100644 --- a/Assets/Scripts/ServerShared/ItemManager.cs +++ b/Assets/Scripts/ServerShared/ItemManager.cs @@ -185,7 +185,7 @@ public class ItemManager private static void ApplyItemUsageConfig(ItemUsageConfig config, BehaviorPayloadReader reader) { - config.Item = reader.Guid(1, config.Item); + config.ItemKey = reader.ItemKey(1, config.ItemKey); } private static void ApplyMiningToolConfig(MiningToolConfig config, BehaviorPayloadReader reader) @@ -303,7 +303,7 @@ public class ItemManager config.Energy = reader.PerformanceStat(9, config.Energy); config.Heat = reader.PerformanceStat(10, config.Heat); config.Visibility = reader.PerformanceStat(11, config.Visibility); - config.AmmoType = reader.Guid(12, config.AmmoType); + config.AmmoItemKey = reader.ItemKey(12, config.AmmoItemKey); config.MagazineSize = reader.Int(13, config.MagazineSize); config.ReloadTime = reader.Float(14, config.ReloadTime); config.Spread = reader.PerformanceStat(15, config.Spread); @@ -424,6 +424,13 @@ public class ItemManager : fallback; } + public string ItemKey(int key, string fallback = "") + { + return Guid(key) is var itemId && itemId != System.Guid.Empty + ? AetheriaRuntimeItemReference.FromLegacyId(itemId) + : fallback; + } + public T Enum(int key, T fallback) where T : struct { if (!_fields.TryGetValue(key, out var value)) diff --git a/Assets/Scripts/UI/HUD/SchematicDisplay.cs b/Assets/Scripts/UI/HUD/SchematicDisplay.cs index a2f207caa..f77e2d2fa 100644 --- a/Assets/Scripts/UI/HUD/SchematicDisplay.cs +++ b/Assets/Scripts/UI/HUD/SchematicDisplay.cs @@ -256,7 +256,7 @@ public class SchematicDisplay : MonoBehaviour if(x.Weapon.MagazineSize > 1) x.ListElement.AmmoLabel.text = x.Weapon.Ammo.ToString(); else - x.ListElement.AmmoLabel.text = _entity.CountItemsInCargo(x.Weapon.AmmoType).ToString(); + x.ListElement.AmmoLabel.text = _entity.CountItemsInCargo(x.Weapon.AmmoItemKey).ToString(); } } diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 69280230a..97bb73f2b 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -53,8 +53,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. while hosting the CultMesh state node. `Aetheria.State.ApplyPending` remains a bounded local operator applicator for both pending lanes. - Shared item domain state is still partly built around `AetheriaRuntimeItemReference`, - `ItemData`, `RuntimeBehaviorConfig`, derived GUID compatibility in behavior - config and broader simulation paths, and runtime catalog metadata. Dead + `ItemData`, `RuntimeBehaviorConfig`, derived GUID compatibility in broader + simulation paths, and runtime catalog metadata. Dead user-record and galaxy-map-layer catalog roots have been deleted, and surviving runtime DTOs no longer carry legacy catalog group/table annotations. Newtonsoft, JsonKnownTypes, RethinkDB, LiteNetLib client transport, and the broken @@ -624,7 +624,9 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. legacy-GUID compatibility projection. `EquippedCargoBay.ItemsOfType`, consumable activation, action-bar consumable fill/quantity display, item transfer lookup, and trade owned-count rows now use item keys rather than - GUID-owned cargo indexes; + GUID-owned cargo indexes. Weapon ammo and item-use behavior config item + references are also typed-key-first (`AmmoItemKey`/`ItemKey`), with + `AmmoType`/`Item` only derived GUID compatibility; 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 @@ -1203,9 +1205,10 @@ First Aetheria surfaces to publish: `Aetheria.Shared.Unity`; the remaining MessagePack reference is contained in the typed state package's `.cc` reader. - In progress: convert domain references from GUID/base-class patterns to - typed record refs. Item instances and cargo inventory indexes now carry - typed item keys; remaining behavior config and broader simulation paths - still derive legacy GUIDs until those structures move to typed keys. + typed record refs. Item instances, cargo inventory indexes, weapon ammo + references, and item-use behavior references now carry typed item keys; + remaining broader simulation paths still derive legacy GUIDs until those + structures move to typed keys. - Remove runtime dependency on `ItemData` DTOs as item instance owners. 5. Mesh host @@ -1327,6 +1330,10 @@ First Aetheria surfaces to publish: counts from derived `Guid ItemId` keys to typed `ItemKey` strings. GUID behavior-config fields still translate at the cargo boundary until behavior config construction moves to typed item references. + - Done: move weapon ammo and `ItemUsage` config references from GUID fields + to typed item-key fields. `AmmoType` and `Item` remain derived compatibility + properties, but runtime ammo consumption, item use, and HUD ammo counts use + `AmmoItemKey`/`ItemKey`. - Done: delete the dead `ItemManager.GetRuntimeItemProjection` bridge after loadout generation stopped hydrating selected typed rows into `EquippableItemData` merely to instantiate equipment.