From a67a228c6b35752c69db5029d49c9e4ae95e62c4 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 14 Jun 2026 16:07:33 +0100 Subject: [PATCH] Persist mining tool state in typed snapshots --- .voidbot/state/aetheria.cc | Bin 85691 -> 85610 bytes Aetheria.State.Smoke/Program.cs | 16 +++++++++++++- Aetheria.State.Unity.Smoke/Program.cs | 20 ++++++++++++++++-- .../AetheriaRuntimeCommitLogApplier.cs | 5 ++++- .../AetheriaRuntimeStateDocuments.cs | 9 ++++++++ Assets/Scripts/Gameplay/ActionGameManager.cs | 11 ++++++++++ .../Runtime/AetheriaRuntimeCatalogSnapshot.cs | 11 +++++++++- .../Runtime/AetheriaRuntimeCatalogStore.cs | 10 +++++++-- .../AetheriaRuntimeStateCommitDocument.cs | 9 ++++++++ docs/aetheria-perfect-machine-map.md | 6 +++++- 10 files changed, 89 insertions(+), 8 deletions(-) diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index ddac8ac586dfdadad6aefb25529af4c0b98fe5a2..dcaaeb5f9f306a7fcfc161de4c92471a874e63e5 100644 GIT binary patch delta 655 zcmaKqJ!n%=6vsJj+8T9GYmDPXW1+}vlg4~tle9^LgHXv}Db^0&zIRQozISi9_cju` zDY`kx1J9zf&_%Znf@qs4vHNVo(h=|5S>A^=vk^H=BZLC3B53(_@NL%j1HJu4SZj zac2?kU1+a{Clzb!Sy9rhx_<`33C6xH+^((6qa8OzW2S*y3*+=`H0y@lVf|M zf5hw2YC_4ssw#Lr2j|w-R%!o)thR;W9t+;mqXRA#v8Cs6LmqPGI+}1{B(bTGg4@(3 zERfBRXc46JWMcVW{x0ClCS1zhUJ0iyS9Xc^i?A%z`_y=mE+ztQ$ delta 812 zcmbV~PiPZS5XPA_6;r6@p!E+FU!VxZq=`wJ)HY3D9X))y-yCXao;lfAhY1^L;blw))>Z?SK6u z63a|wvtyauspUs-(ESj(AAs?3AJ~1jLQwF*-YA3Ho1@X~(I`w7Xe$i^LlTwUlm@1h z!7U4AN@=c!{g^ZMK;(lZ-2k(iSEYmWgXg*7=xe(LkAGl3R65vWBokquF34T1x1)r?JfLJF_Xd z7Pcp_nQl91vK3tAEn!RM56&b#EW+77#T)dw2v^}d8pu_WqtxDOQ3E z?9fyR(#LvgtZO43+Nbpr+#L+t8r)b#Iy?)PVS}7m82MKU{~tlr^&n*)QpY*1nZj%G4v)*M@*Vx5&<@`CqP!Z?%2&6I6j zZ+AkvhK3(=jT_qibn;wcexVB$+tm@h+`VJ)HbT`om~cP-JmEgMI0W-_r3^>@3V6K? zkK?a;I#8kl7lKQj@NbzORN!4e^10xc_t1?hI3dk diff --git a/Aetheria.State.Smoke/Program.cs b/Aetheria.State.Smoke/Program.cs index 5652cae12..2d289adf4 100644 --- a/Aetheria.State.Smoke/Program.cs +++ b/Aetheria.State.Smoke/Program.cs @@ -284,6 +284,16 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s ResourceScannerRange = 500.0, ResourceScannerMinimumDensity = 0.2, ResourceScannerScanDuration = 3.5 + }, + new AetheriaBehaviorStateSnapshot + { + OwnerKind = "equipment", + OwnerIndex = 0, + BehaviorIndex = 2, + BehaviorKind = "MiningTool", + MiningToolAsteroidBeltId = "smoke:body", + MiningToolAsteroidIndex = 3, + MiningToolRange = 275.0 } ], StatGrids = @@ -547,7 +557,7 @@ await using (var reopened = await AetheriaStateNode.OpenAsync(statePath, "aether entitySnapshot.WeaponStates[0].BehaviorKind != "LockWeapon" || entitySnapshot.WeaponStates[0].LockProgress != 0.65 || entitySnapshot.WeaponStates[0].LockTargetEntityKey != entityKey.ToString() || - entitySnapshot.BehaviorStates.Length != 2 || + entitySnapshot.BehaviorStates.Length != 3 || entitySnapshot.BehaviorStates[0].BehaviorKind != "AetherDrive" || entitySnapshot.BehaviorStates[0].AetherDriveAxisX != 0.5 || entitySnapshot.BehaviorStates[0].AetherDriveRpmY != 900.0 || @@ -557,6 +567,10 @@ await using (var reopened = await AetheriaStateNode.OpenAsync(statePath, "aether entitySnapshot.BehaviorStates[1].ResourceScannerAsteroidIndex != 2 || entitySnapshot.BehaviorStates[1].ResourceScannerScanTime != 1.25 || entitySnapshot.BehaviorStates[1].ResourceScannerScanDuration != 3.5 || + entitySnapshot.BehaviorStates[2].BehaviorKind != "MiningTool" || + entitySnapshot.BehaviorStates[2].MiningToolAsteroidBeltId != "smoke:body" || + entitySnapshot.BehaviorStates[2].MiningToolAsteroidIndex != 3 || + entitySnapshot.BehaviorStates[2].MiningToolRange != 275.0 || entitySnapshot.StatGrids.Length != 1 || entitySnapshot.StatGrids[0].Values.Length != 4) { diff --git a/Aetheria.State.Unity.Smoke/Program.cs b/Aetheria.State.Unity.Smoke/Program.cs index facd73adb..971cec91d 100644 --- a/Aetheria.State.Unity.Smoke/Program.cs +++ b/Aetheria.State.Unity.Smoke/Program.cs @@ -513,6 +513,16 @@ try ResourceScannerRange = 500.0, ResourceScannerMinimumDensity = 0.2, ResourceScannerScanDuration = 3.5 + }, + new AetheriaRuntimeBehaviorStateCommit + { + OwnerKind = "equipment", + OwnerIndex = 6, + BehaviorIndex = 0, + BehaviorKind = "MiningTool", + MiningToolAsteroidBeltId = "smoke:body", + MiningToolAsteroidIndex = 3, + MiningToolRange = 275.0 } }, StatGrids = new[] @@ -633,7 +643,7 @@ try entity.WeaponStates[3].BehaviorKind == "LockWeapon" && entity.WeaponStates[3].LockProgress == 0.65 && entity.WeaponStates[3].LockTargetEntityKey == "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" && - entity.BehaviorStates.Length == 6 && + entity.BehaviorStates.Length == 7 && entity.BehaviorStates[0].BehaviorKind == "Sensor" && entity.BehaviorStates[0].Pinging && entity.BehaviorStates[0].PingRadius == 1200.0 && @@ -655,6 +665,10 @@ try entity.BehaviorStates[5].ResourceScannerAsteroidIndex == 2 && entity.BehaviorStates[5].ResourceScannerScanTime == 1.25 && entity.BehaviorStates[5].ResourceScannerScanDuration == 3.5 && + entity.BehaviorStates[6].BehaviorKind == "MiningTool" && + entity.BehaviorStates[6].MiningToolAsteroidBeltId == "smoke:body" && + entity.BehaviorStates[6].MiningToolAsteroidIndex == 3 && + entity.BehaviorStates[6].MiningToolRange == 275.0 && entity.WeaponGroups.Length == 1 && entity.StatGrids.Length == 2 && entity.StatGrids.Any(grid => grid.Name == "temperature" && grid.Values.Length == 2 && grid.Values[1] == 281.0) && @@ -710,12 +724,14 @@ try packageEntities[0].WeaponStates[2].AmmoIntervalProgress != 0.6 || packageEntities[0].WeaponStates[3].LockProgress != 0.65 || packageEntities[0].WeaponStates[3].LockTargetEntityKey != "global:aetheria.run_state.smoke-run.zone.0.entity.0.v1" || - packageEntities[0].BehaviorStates.Count != 6 || + packageEntities[0].BehaviorStates.Count != 7 || packageEntities[0].BehaviorStates[3].CapacitorCharge != 7.5 || packageEntities[0].BehaviorStates[4].AetherDriveRpmY != 900.0 || packageEntities[0].BehaviorStates[4].AetherDriveMaximumRpm != 2400.0 || packageEntities[0].BehaviorStates[5].ResourceScannerTargetBodyId != "smoke:body" || packageEntities[0].BehaviorStates[5].ResourceScannerScanDuration != 3.5 || + packageEntities[0].BehaviorStates[6].MiningToolAsteroidBeltId != "smoke:body" || + packageEntities[0].BehaviorStates[6].MiningToolRange != 275.0 || packageEntities[0].StatGrids.Count != 2 || packageEntities[0].StatGrids.All(grid => grid.Name != "temperature" || grid.Values.Count != 2 || grid.Values[1] != 281.0)) { diff --git a/Aetheria.State/AetheriaRuntimeCommitLogApplier.cs b/Aetheria.State/AetheriaRuntimeCommitLogApplier.cs index fdf325764..2105fb259 100644 --- a/Aetheria.State/AetheriaRuntimeCommitLogApplier.cs +++ b/Aetheria.State/AetheriaRuntimeCommitLogApplier.cs @@ -504,7 +504,10 @@ public static class AetheriaRuntimeCommitLogApplier ResourceScannerScanTime = state.ResourceScannerScanTime, ResourceScannerRange = state.ResourceScannerRange, ResourceScannerMinimumDensity = state.ResourceScannerMinimumDensity, - ResourceScannerScanDuration = state.ResourceScannerScanDuration + ResourceScannerScanDuration = state.ResourceScannerScanDuration, + MiningToolAsteroidBeltId = state.MiningToolAsteroidBeltId ?? "", + MiningToolAsteroidIndex = state.MiningToolAsteroidIndex, + MiningToolRange = state.MiningToolRange }) .ToArray(); } diff --git a/Aetheria.State/Documents/AetheriaRuntimeStateDocuments.cs b/Aetheria.State/Documents/AetheriaRuntimeStateDocuments.cs index 82da58689..1aebc97f5 100644 --- a/Aetheria.State/Documents/AetheriaRuntimeStateDocuments.cs +++ b/Aetheria.State/Documents/AetheriaRuntimeStateDocuments.cs @@ -757,6 +757,15 @@ public sealed class AetheriaBehaviorStateSnapshot [Key(36)] public double ResourceScannerScanDuration { get; set; } + + [Key(37)] + public string MiningToolAsteroidBeltId { get; set; } = ""; + + [Key(38)] + public int MiningToolAsteroidIndex { get; set; } = -1; + + [Key(39)] + public double MiningToolRange { get; set; } } [MessagePackObject] diff --git a/Assets/Scripts/Gameplay/ActionGameManager.cs b/Assets/Scripts/Gameplay/ActionGameManager.cs index 0ed741c36..f5480677f 100644 --- a/Assets/Scripts/Gameplay/ActionGameManager.cs +++ b/Assets/Scripts/Gameplay/ActionGameManager.cs @@ -916,6 +916,17 @@ public class ActionGameManager : MonoBehaviour ResourceScannerScanDuration = resourceScanner.ScanDuration }; } + else if (behavior is MiningTool miningTool) + { + state = new AetheriaRuntimeBehaviorStateCommit + { + MiningToolAsteroidBeltId = miningTool.AsteroidBelt == Guid.Empty + ? "" + : miningTool.AsteroidBelt.ToString("D"), + MiningToolAsteroidIndex = miningTool.Asteroid, + MiningToolRange = miningTool.Range + }; + } if (state == null) continue; diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs index e7f2cc0f8..b136ba0ac 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs @@ -1104,7 +1104,10 @@ namespace GameCult.Aetheria.State.Unity double resourceScannerScanTime, double resourceScannerRange, double resourceScannerMinimumDensity, - double resourceScannerScanDuration) + double resourceScannerScanDuration, + string miningToolAsteroidBeltId, + int miningToolAsteroidIndex, + double miningToolRange) { OwnerKind = ownerKind; OwnerIndex = ownerIndex; @@ -1143,6 +1146,9 @@ namespace GameCult.Aetheria.State.Unity ResourceScannerRange = resourceScannerRange; ResourceScannerMinimumDensity = resourceScannerMinimumDensity; ResourceScannerScanDuration = resourceScannerScanDuration; + MiningToolAsteroidBeltId = miningToolAsteroidBeltId; + MiningToolAsteroidIndex = miningToolAsteroidIndex; + MiningToolRange = miningToolRange; } public string OwnerKind { get; } @@ -1182,5 +1188,8 @@ namespace GameCult.Aetheria.State.Unity public double ResourceScannerRange { get; } public double ResourceScannerMinimumDensity { get; } public double ResourceScannerScanDuration { get; } + public string MiningToolAsteroidBeltId { get; } + public int MiningToolAsteroidIndex { get; } + public double MiningToolRange { get; } } } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs index ca4230738..7199f3c9d 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogStore.cs @@ -894,7 +894,10 @@ namespace GameCult.Aetheria.State.Unity var resourceScannerRange = ReadFieldDouble(ref reader, behaviorFields, 34); var resourceScannerMinimumDensity = ReadFieldDouble(ref reader, behaviorFields, 35); var resourceScannerScanDuration = ReadFieldDouble(ref reader, behaviorFields, 36); - SkipRemaining(ref reader, behaviorFields, 37); + var miningToolAsteroidBeltId = ReadFieldString(ref reader, behaviorFields, 37); + var miningToolAsteroidIndex = ReadFieldInt32(ref reader, behaviorFields, 38); + var miningToolRange = ReadFieldDouble(ref reader, behaviorFields, 39); + SkipRemaining(ref reader, behaviorFields, 40); behaviorStates[behavior] = new AetheriaRuntimeBehaviorStateSnapshot( ownerKind, ownerIndex, @@ -932,7 +935,10 @@ namespace GameCult.Aetheria.State.Unity resourceScannerScanTime, resourceScannerRange, resourceScannerMinimumDensity, - resourceScannerScanDuration); + resourceScannerScanDuration, + miningToolAsteroidBeltId, + miningToolAsteroidIndex, + miningToolRange); } return behaviorStates; diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs index b2837b3ea..b3d0df802 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeStateCommitDocument.cs @@ -806,5 +806,14 @@ namespace GameCult.Aetheria.State.Unity [Key(36)] public double ResourceScannerScanDuration { get; set; } + + [Key(37)] + public string MiningToolAsteroidBeltId { get; set; } = ""; + + [Key(38)] + public int MiningToolAsteroidIndex { get; set; } = -1; + + [Key(39)] + public double MiningToolRange { get; set; } } } diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 5f2775c9a..26909caa8 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -173,7 +173,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. thrust, RPM, maximum RPM, and thrust-direction rows, so rotor simulation state is no longer trapped inside live behavior memory. Resource scanners publish target body id, asteroid index, scan timer, range, minimum density, - and scan duration rows. + and scan duration rows. Mining tools publish asteroid belt id, asteroid + index, and evaluated range rows. `RuntimeEntityBlueprint` still exists for construction/loadout projection, but those live hull grids and session scalars are not blueprint fields and cannot be restored by the old blueprint projector path. @@ -811,6 +812,9 @@ First Aetheria surfaces to publish: - Done: extend behavior state rows for ResourceScanner target body, asteroid index, scan timer, range, minimum density, and duration, so scanner progress is typed state instead of live-only behavior memory. + - Done: extend behavior state rows for MiningTool asteroid belt id, + asteroid index, and range, so active mining target state is typed + snapshot/readback state. - Done: cut live simulation grids out of `RuntimeEntityBlueprint`; loadout and construction templates no longer capture or restore temperature, armor, max-armor, or hull-conductivity state.