From f785f8e350c366ff288aedabe9ec095d2c7fc549 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 14 Jun 2026 17:13:16 +0100 Subject: [PATCH] Persist item enabled state in typed snapshots --- .voidbot/state/aetheria.cc | Bin 86260 -> 86094 bytes Aetheria.State.Smoke/Program.cs | 8 ++++++-- Aetheria.State.Unity.Smoke/Program.cs | 10 ++++++++-- .../AetheriaRuntimeCommitLogApplier.cs | 6 ++++-- .../AetheriaRuntimeStateDocuments.cs | 6 ++++++ Assets/Scripts/Gameplay/ActionGameManager.cs | 11 ++++++++--- .../Runtime/AetheriaRuntimeCatalogSnapshot.cs | 8 ++++++-- .../Runtime/AetheriaRuntimeCatalogStore.cs | 18 +++++++++++++----- .../AetheriaRuntimeStateCommitDocument.cs | 3 +++ docs/aetheria-perfect-machine-map.md | 6 ++++-- 10 files changed, 58 insertions(+), 18 deletions(-) diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index 4fedda7f760bbde19d09fc00dc722a9a5d3230fd..6714b531d07866ef6be01ffb69dbcd2f4c9cd029 100644 GIT binary patch delta 1777 zcmZ`)O^6&t6sF^De$W*|FhN*CsVFSiy))TgXR~I*IFS&E>n1^26{+cdGgEGNRi~cEC}Aj2KyxV6H(WoK}aHai1&aZo)!-tz2@LeP+wL5%w!W!GrTU|_w&A2_1CB4 zKYucQ{p!Al=Nt7CjryXuFf*GuEoU;lvu}H(_`E3|O~pf3hQ-+vdGX*FaSm@!joq3W za~2mSpQWICAQ^R;hR6j@+aUz5(o{nhKkB?Wv2qqakm5sjcgcBt5DFTIL{9_PO!tZ6 zG*&&KNryogDDMkDq%7L~>~ztZ#2^(@T9MY}gvGIe7;Q={8qqx|l5UUaehdLAFo>Z= zd=W)VtLKPMx!^~bPs8#+K_dI{r1Mnv=Sk;y>*I?kD5BwXkVx8Qp`j>v$T$$n144bx zHi1ZpDB~nR?VAWE6Vws`QLM{psFt$jW#{P{jpMM-c(;^aC?sv_ZxF_{Aff4HIWn$v z`rZB~1~*<5grgf0@PrgW;v-toz8xkIORT%ds9&|s4G@x0q9CRc&Ci=^(d~xFiXuu( z`^J`b)hr_`dMPjiq=8EUgMHSj}sDQ&Z~9{V$Cjjfov|VUj{0?=z$f>@nqCgH09y z@-@0Y+WuTZXLl_-yyCpJdc&%6^X%ad4ihC+{OV=A*YerEoG-;$G@)tZieZ(Kp<%^f z(rfz3?Cy&5%v(2Yj7^I3MRS$k!#Gy0m&?{8J*}v+-m;5lpe`6Y4N$*=nUpUKzAadr z05gzP=k-i5ev#QnoGLk@kr zG{?JOE-xRtqQ%|(O&)T40qq$4Jdrz$ z`$^jZevn@N_t@|qnW<;5o^eJBb93fl`E7V&u6lmb2<6(EjL;9XCeGrF!cY8jaM@)pBjJny$StjM3)$ zk>SlF!)U7h`eDMY%e5d5F_vp3nA7H-b&MsJ$H9x}Vz1HY@8Dzy>rh(ZbDTzCsn)Pd z47S~XGo0UnjU<6_6-28wQ~8#9MEDQ?YV@&iz_k&^n(_c6K3U>pSaTDQHHi}lZN@N> zZH9dzxyFRj&<{Ogm4>hm*IZH#$gWo5l3V0;O-V>D$EV8og@ubKkxB|mJUkbAc8*Y& z7wGY4C(xUFunB#iXu(bV(+PBN>c>S0$#@ml1&|-ts{mV2h2(@>%H$Zs?a;_VaLEv>EcV&305pEN@jD>`)T<%ke+DxQJlC+{v=SO>gp9yWK zc_Im*z6VWSVU;);1QTYL#m+Pkg(E&h~-@tv=xtyyb~ijuW)XprQsp z+iKf5&15xs%HEl)GIRgHSAi^8G08sOwf+rw^WjI)qs!yb1M*U|v9dS*?}h(L)>Y*%_JH%~`!4>TY$%`CCm6HSoxR)#kl{eJdP^xKCHyEs=E zy|8Fu-yCRL36f^pMuCA|>w_&M4n_NCkBwBBvXZBR2uCaDUrl#*ISa%X&f@o{k+b(` z84_K&KDsqxiS qr_nFv;?!iicy1n 0) - equippable.Durability = (float)item.Durability; + if (instance is EquippableItem equippable) + { + equippable.Enabled.Value = item.Enabled; + if (item.Durability > 0) + equippable.Durability = (float)item.Durability; + } return instance; } @@ -524,7 +528,8 @@ public class ActionGameManager : MonoBehaviour ItemDefinitionLegacyId = item.ItemId == Guid.Empty ? "" : item.ItemId.ToString("D"), Quality = item is CraftedItemInstance crafted ? crafted.Quality : 1.0, Durability = item is EquippableItem equippable ? equippable.Durability : 1.0, - Quantity = item is SimpleCommodity commodity ? commodity.Quantity : 1 + Quantity = item is SimpleCommodity commodity ? commodity.Quantity : 1, + Enabled = item is not EquippableItem enabledItem || enabledItem.Enabled.Value }; } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs index e858486bb..56b585e46 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs @@ -636,18 +636,20 @@ namespace GameCult.Aetheria.State.Unity public sealed class AetheriaRuntimeLoadoutItemSnapshot { - public AetheriaRuntimeLoadoutItemSnapshot(string itemKey, double quality, double durability, int quantity) + public AetheriaRuntimeLoadoutItemSnapshot(string itemKey, double quality, double durability, int quantity, bool enabled) { ItemKey = itemKey; Quality = quality; Durability = durability; Quantity = quantity; + Enabled = enabled; } public string ItemKey { get; } public double Quality { get; } public double Durability { get; } public int Quantity { get; } + public bool Enabled { get; } } public sealed class AetheriaRuntimeLoadoutItemSlotSnapshot @@ -973,7 +975,7 @@ namespace GameCult.Aetheria.State.Unity public sealed class AetheriaRuntimeEntityItemSlotSnapshot { - public AetheriaRuntimeEntityItemSlotSnapshot(int x, int y, string itemKey, double quality, double durability, int quantity) + public AetheriaRuntimeEntityItemSlotSnapshot(int x, int y, string itemKey, double quality, double durability, int quantity, bool enabled) { X = x; Y = y; @@ -981,6 +983,7 @@ namespace GameCult.Aetheria.State.Unity Quality = quality; Durability = durability; Quantity = quantity; + Enabled = enabled; } public int X { get; } @@ -989,6 +992,7 @@ namespace GameCult.Aetheria.State.Unity public double Quality { get; } public double Durability { get; } public int Quantity { get; } + public bool Enabled { get; } } public sealed class AetheriaRuntimeEntityStatGridSnapshot diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs index c2cf52761..28301d210 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs @@ -769,14 +769,16 @@ namespace GameCult.Aetheria.State.Unity var quality = ReadFieldDouble(ref reader, slotFields, 2, 1); var durability = ReadFieldDouble(ref reader, slotFields, 3, 1); var quantity = ReadFieldInt32(ref reader, slotFields, 4); - SkipRemaining(ref reader, slotFields, 5); + var enabled = ReadFieldBool(ref reader, slotFields, 5, true); + SkipRemaining(ref reader, slotFields, 6); slots[slot] = new AetheriaRuntimeEntityItemSlotSnapshot( position.X, position.Y, itemKey, quality, durability, - quantity <= 0 ? 1 : quantity); + quantity <= 0 ? 1 : quantity, + enabled); } return slots; @@ -1058,6 +1060,11 @@ namespace GameCult.Aetheria.State.Unity return index < fields && reader.ReadBoolean(); } + private static bool ReadFieldBool(ref MessagePackReader reader, int fields, int index, bool fallback) + { + return index >= fields ? fallback : reader.ReadBoolean(); + } + private static long ReadFieldInt64(ref MessagePackReader reader, int fields, int index) { return index >= fields ? 0 : reader.ReadInt64(); @@ -1220,13 +1227,14 @@ namespace GameCult.Aetheria.State.Unity var quality = ReadFieldDouble(ref reader, itemFields, 1, 1); var durability = ReadFieldDouble(ref reader, itemFields, 2, 1); var quantity = ReadFieldInt32(ref reader, itemFields, 3); - SkipRemaining(ref reader, itemFields, 4); - return new AetheriaRuntimeLoadoutItemSnapshot(itemKey, quality, durability, quantity); + var enabled = ReadFieldBool(ref reader, itemFields, 4, true); + SkipRemaining(ref reader, itemFields, 5); + return new AetheriaRuntimeLoadoutItemSnapshot(itemKey, quality, durability, quantity, enabled); } private static AetheriaRuntimeLoadoutItemSnapshot EmptyLoadoutItem() { - return new AetheriaRuntimeLoadoutItemSnapshot("", 1, 1, 1); + return new AetheriaRuntimeLoadoutItemSnapshot("", 1, 1, 1, true); } private static IReadOnlyList ReadFieldLoadoutItemSlots(ref MessagePackReader reader, int fields, int index) diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs index 655e93363..3367fbc56 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs @@ -184,6 +184,9 @@ namespace GameCult.Aetheria.State.Unity [Key(3)] public int Quantity { get; set; } = 1; + + [Key(4)] + public bool Enabled { get; set; } = true; } [MessagePackObject] diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index e90de0da0..0032d88f6 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -158,8 +158,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. contact rows for gathered information, hostility, and visible classification, and active consumable item/timer rows. Entity equipment, cargo-bay, and docking-bay slot rows preserve item-instance - facts needed for restore: item key, quality, durability, and quantity. Those - facts are no longer discarded when pending checkpoint commands become + facts needed for restore: item key, quality, durability, quantity, and enabled + state. Those facts are no longer discarded when pending checkpoint commands become canonical `AetheriaEntitySnapshot` documents or package readback DTOs. Cargo bay contents, docking bay contents, and docking bay child assignments also persist as typed snapshot rows, so inventories and docked-child @@ -850,6 +850,8 @@ First Aetheria surfaces to publish: - Done: preserve entity snapshot item-instance facts for equipment, cargo-bay, and docking-bay slot rows: item key, quality, durability, and quantity now survive canonical state and Unity package readback. + - Done: preserve item enabled state on typed loadout items and entity item + slots, so disabled equipment is no longer only runtime blueprint state. - Done: preserve cargo bay contents, docking bay contents, and docking bay child assignments in typed entity snapshots. - Done: preserve aggregate entity visibility and visibility-source count in