From d462ec694218c43d2322cd06b5a3c3d38e048b05 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 14 Jun 2026 15:32:41 +0100 Subject: [PATCH] Persist entity cargo contents in typed snapshots --- .voidbot/state/aetheria.cc | Bin 86413 -> 86679 bytes Aetheria.State.Smoke/Program.cs | 23 ++++++++++++++ Aetheria.State.Unity.Smoke/Program.cs | 28 ++++++++++++++++++ .../AetheriaRuntimeCommitLogApplier.cs | 5 +++- .../AetheriaRuntimeStateDocuments.cs | 9 ++++++ Assets/Scripts/Gameplay/ActionGameManager.cs | 23 ++++++++++++++ .../Runtime/AetheriaRuntimeCatalogSnapshot.cs | 11 ++++++- .../Runtime/AetheriaRuntimeCatalogStore.cs | 10 +++++-- .../AetheriaRuntimeStateCommitDocument.cs | 9 ++++++ docs/aetheria-perfect-machine-map.md | 5 ++++ 10 files changed, 119 insertions(+), 4 deletions(-) diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index 92e2cc499028a80ed598a80f95df987296c5f1cf..9e23691720084b851c7fe634d766c40a494b598c 100644 GIT binary patch delta 1646 zcma)7J!~9B6xP^|m4Gl3gjgVipCW@4x(`-0sX~ zX7|jdIe|qe4Gt^}>bb7vveUyGo|BpC&##T7+wh*~7`%Oitb|@6{G-_Fi^$ zYHnhsxpiu4@6;5jRp%YbVxK8aD@?>ZPAe`|9a-_D+vTEDX;U}WCYmAdk;~@bBAH*x zzXKH>ly|_DBF1FxY`X#F;jiS=Yl#5YXKpu=T*T(Li{!+In5R-GvRf2SW!A#5&ZE)s z4*3_K2OdzZc}Ik{9bjpR1%(vcr9t+>#%$l#N{X*G|GGd%5K*^FI}8+~UJK6-Z1_y$ z|8i49f`>Sbm^TJ3kkpe&3_NBb=s?DL0kp(^J?twjixN9T3Ja+oE3S6U)-rjq51Typ zZN6eX-a{3k#dIXQ44m6iFpvsVf?|iP(h3q5DI@}#VwH%dwzqb6P*BaKIQVnJ=Nfd( zg8;cP4MN7)K8ykuGiWCmt|J&O5|-1#o_&oNZLQdcFws~#&sMC%1XC2#aNy9P0sT0I zwvr*N6(6wQIzu6>a)I1rsuZR$253Pe?V}il@FfM1t&bRbWC5dYka%1?W%>HF$C0PC z4+>`fdYvqp->;J6{lBjyaf0v)&9Mj~E&yZg1SgEzY8)Xfm%cNO&ER9ioxiHRYdmlWm5Oa_sW*ws|K(^5h3Ch?(aq!gfAz&TqrrGWf zvu_r|(JZ70!qtGb!+hC8g$ADBI2z<@R{|B(K998XJr%Am)iu`EUv1q{tbK4Zd-(oR z_A`Al`|j4`eFT?#)p7N=xNP2CjXM+49i$&pl^)zIIFD_ToqWji30SQe&?sWU8<_XB zZErcChE|w-lB11*HfI5vtH5$8+rRo!_T&1Td2pG`kY+Zwabg7`rZm^sp;*+i5Gs7A zG)Bf3bkxLrbB?@y<3>5PaqN+j)+y*RU^$6^qvi8Hhk@(7xO;fx%^z=&aJrdqwYgO% zPcKuYQTYF;F#@IwuNS@>dfAZUUpL4}{IlO6mu9x}#GO)l^TaB7-c(mf?bzVyKcD?F y`Rw3q(w>>DN!qVM@faY?>%0Urj@1%#=QI}wGx{wN_Y3ooHsLO=HBVO zcV0T(1c~56T*wG_CrGJ+BJD;4b)j9jQm8wL3k7$I3m5(Yo;&Z&qjBSI`0ku@zVn^$ z9DD!h2ltLX{B-2_%*^HKOU;X|i?=>xr;6`K-mj49nG%sl?hcW;5*ZtW8 zNQKS&Ud*H97bfh3D{NxiMS+f``&sUQ$Cb+M!UAi|x*)urMQK76>+U6xjSkQ2z=aRK z^tK}rH~^H~(M{M2v3T_J3+oVbfxu&h+|ME8J`izTG3rGemIkfd$f%VB-;mswnYl_# zHi^ixOp?gVL$UBz?HrMUSc(7@cruQ8s!_Xq2^a}3;u_{4MV!~|lPm1>F5sP14*r2| z7RP08eKne&85BB_;^3dHFw&q+MDM<&j6xd9pQJGwgk?#zM20{Dlqpo7C&}@H&RP7tz0-6veZx&$&i|k1nF3MpmL6eOgjp1WjrRI)uEj!-ii9(Zu0aX%p^Tgur@SgkX;fuj$KrT zd)qXc;^Eg5SDk)b% ztK^h(3rFp9ztk(`iY)84u5Q^l+o&yF=V_^qawQJ!wTs+8z0B4aB#fd?V2s`n|-v(zOA4Ot-*nN#(uoU entity.Children.IndexOf(bay.DockedShip)) + .ToArray() ?? Array.Empty(), ChildEntityIndices = entity.Children? .Select(child => zone.Entities.IndexOf(child)) .Where(index => index >= 0) @@ -795,6 +800,24 @@ public class ActionGameManager : MonoBehaviour }; } + private static AetheriaRuntimeCargoBayLoadoutCommit[] ProjectRuntimeCargoBays(IEnumerable bays) + where TBay : EquippedCargoBay + { + return bays? + .Select(bay => new AetheriaRuntimeCargoBayLoadoutCommit + { + Items = bay.Cargo? + .Select(slot => new AetheriaRuntimeLoadoutItemSlotCommit + { + X = slot.Value.x, + Y = slot.Value.y, + Item = ProjectLoadoutItem(slot.Key) + }) + .ToArray() ?? Array.Empty() + }) + .ToArray() ?? Array.Empty(); + } + private static AetheriaRuntimeBehaviorStateCommit[] ProjectBehaviorStates(Entity entity) { var states = new List(); diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs index 43b29d93c..cdb8439d0 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs @@ -783,7 +783,10 @@ namespace GameCult.Aetheria.State.Unity IReadOnlyList activeConsumables, IReadOnlyList behaviorProgress, IReadOnlyList weaponStates, - IReadOnlyList behaviorStates) + IReadOnlyList behaviorStates, + IReadOnlyList cargoContents, + IReadOnlyList dockingBayContents, + IReadOnlyList dockingBayAssignments) { Name = name; Kind = kind; @@ -813,6 +816,9 @@ namespace GameCult.Aetheria.State.Unity BehaviorProgress = behaviorProgress; WeaponStates = weaponStates; BehaviorStates = behaviorStates; + CargoContents = cargoContents; + DockingBayContents = dockingBayContents; + DockingBayAssignments = dockingBayAssignments; } public string Name { get; } @@ -843,6 +849,9 @@ namespace GameCult.Aetheria.State.Unity public IReadOnlyList BehaviorProgress { get; } public IReadOnlyList WeaponStates { get; } public IReadOnlyList BehaviorStates { get; } + public IReadOnlyList CargoContents { get; } + public IReadOnlyList DockingBayContents { get; } + public IReadOnlyList DockingBayAssignments { get; } } public sealed class AetheriaRuntimeActionBarBindingSnapshot diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs index 52e6fabde..76da4267b 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs @@ -532,7 +532,10 @@ namespace GameCult.Aetheria.State.Unity var behaviorProgress = ReadFieldBehaviorProgress(ref reader, fields, 21); var weaponStates = ReadFieldWeaponStates(ref reader, fields, 22); var behaviorStates = ReadFieldBehaviorStates(ref reader, fields, 23); - SkipRemaining(ref reader, fields, 24); + var cargoContents = ReadFieldCargoBayLoadouts(ref reader, fields, 24); + var dockingBayContents = ReadFieldCargoBayLoadouts(ref reader, fields, 25); + var dockingBayAssignments = ReadFieldInt32Array(ref reader, fields, 26); + SkipRemaining(ref reader, fields, 27); return new AetheriaRuntimeEntitySnapshot( name, kind, @@ -561,7 +564,10 @@ namespace GameCult.Aetheria.State.Unity activeConsumables, behaviorProgress, weaponStates, - behaviorStates); + behaviorStates, + cargoContents, + dockingBayContents, + dockingBayAssignments); } private static Vector2Value ReadFieldVector2(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 3b3fa66e8..6eb706a2c 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs @@ -570,6 +570,15 @@ namespace GameCult.Aetheria.State.Unity [Key(28)] public IReadOnlyList BehaviorStates { get; set; } = Array.Empty(); + + [Key(29)] + public IReadOnlyList CargoContents { get; set; } = Array.Empty(); + + [Key(30)] + public IReadOnlyList DockingBayContents { get; set; } = Array.Empty(); + + [Key(31)] + public IReadOnlyList DockingBayAssignments { get; set; } = Array.Empty(); } [MessagePackObject] diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 350bc437a..70751b7f6 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -157,6 +157,9 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. facts needed for restore: item key, quality, durability, and quantity. 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 + placement do not need a bespoke `.zone` or runtime-blueprint save payload. Equipped-item and active-consumable behaviors that intentionally expose `IProgressBehavior` now publish typed progress rows keyed by owner kind, owner index, behavior index, behavior kind, and progress value. @@ -807,6 +810,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 cargo bay contents, docking bay contents, and docking bay + child assignments in typed entity snapshots. - Remaining: add typed documents/mappers for runtime object graphs, typed behavior factory construction, remaining behavior-private state not covered by progress, weapon, sensor, radiator, reactor, or capacitor rows,