From afc7dc3134f9e182d80a046fa3b897143b0744bf Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 16 Jun 2026 03:43:21 +0100 Subject: [PATCH] Route docked ship selection through checkpoints --- .voidbot/state/aetheria.cc | Bin 143833 -> 144421 bytes Aetheria.State.Verify/Program.cs | 54 +++++++++++++++++++ Assets/Scripts/Gameplay/ActionGameManager.cs | 17 ++++++ Assets/Scripts/UI/Menu/InventoryPanel.cs | 5 +- docs/aetheria-perfect-machine-map.md | 8 ++- 5 files changed, 80 insertions(+), 4 deletions(-) diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index 9029284c77741b46292b56d075bba93665a74d36..a71310eb60c1b9f2b2fe149d252b36f1da961958 100644 GIT binary patch delta 1138 zcmZWp%}Z2K6z`4ZS0E$?TA>#t&9Kq&1D#oAlZatorW;q?d2^h(`sUu(z4tjyi-uM$ zA}HQs{(!!yjlvK{n`qHKXq6Nc64;_exk?Q>_c?DQ+zfNi@7&+-oZmV3ecEVvy4kS$ zEYdU_OT@;aLu0Y|N7ga_edK;6G8`KSBBJJYH8K)J8frTuU7O|J+E-u7i`y&G|M=}e z{nQ0vFG1R0-EH&#ZVy?#er%^bsz56;Npo!@>fgMsm{w580`IXQQLIZk?G$8EhJYG&V*=o?|aTVv#t4qjv#{ z=A}WRkz_WDsEd^o>YxDJa)p94p@aj=WK%+#=8~SHr&$WgnUf|d33Q3%vq(TB*n)HP zgSf(Bb^$9C3(Nsxi!>NEgpf|SI%*t4)CH+oU^(5ZG}&cfgX)5dfJ4m&l*ZSs*5aF_ zz!7r~NUDHZI2+s4W5%^_Va2vRQ}Rq_jU_~Ra)H{$eVh{BUIK8#UM>SlOUjiiq$bMF zLXP%_l~;;!sbm*%xezqrbOgBSc8 zTPFg}nQKaT(uPE(iiDDOzj-j`9L09?LYg)0H)lM~hRsK9m6!=Cb?cFGeUeq_&Ay(e=ktBM2+ z602xLG=si1#BeDF$;v zP*y-Hpi*d~Y(6p82|!0Y(b?Cww=nHQ?u{H&fIQouEy;DE!9@RY21#u7;NY;d@$H{G zu0b0f$3Vc|Xy1ZFG0nvBDk#PB7lEP~ngXAbCq=DPG41?=y3{qw)(6z<^x)zCuiB2TumImLkCZ`- zKZV&N548q4LuXE~hbD)w@wNQQWksxsq~a!pYtFZc2x44Pt__%ovS_Q1Le6r)6{99j z=id@Rar8dx>HSmZhi@KuD`$pj !actionGameManager.Contains(symbol, StringComparison.Ordinal)) + .ToArray(); + + if (missingSymbols.Length > 0) + { + throw new InvalidOperationException( + "Docked current-ship selection no longer has a gameplay-owned checkpoint commit primitive: " + + string.Join(", ", missingSymbols)); + } + + var inventoryPanelPath = Path.Combine(root, "Assets", "Scripts", "UI", "Menu", "InventoryPanel.cs"); + var forbiddenSymbols = new[] + { + "GameManager.CurrentEntity =", + "GameManager.DockingBay.DockedShip =" + }; + + var hits = File.ReadLines(inventoryPanelPath) + .Select((line, index) => new { LineNumber = index + 1, Line = line }) + .Where(line => forbiddenSymbols.Any(symbol => line.Line.Contains(symbol, StringComparison.Ordinal))) + .Select(line => $"{Path.GetRelativePath(root, inventoryPanelPath)}:{line.LineNumber}: {line.Line.Trim()}") + .ToArray(); + + if (hits.Length > 0) + { + throw new InvalidOperationException( + "InventoryPanel still owns direct docked current-ship mutation: " + + string.Join("; ", hits)); + } + + var inventoryPanel = File.ReadAllText(inventoryPanelPath); + if (!inventoryPanel.Contains("GameManager.CommitDockedCurrentShip", StringComparison.Ordinal)) + { + throw new InvalidOperationException("InventoryPanel no longer routes current-ship selection through ActionGameManager."); + } +} + static string ExtractMethodBody(string source, string methodName) { var signature = "private void " + methodName + "()"; diff --git a/Assets/Scripts/Gameplay/ActionGameManager.cs b/Assets/Scripts/Gameplay/ActionGameManager.cs index d5449e5b8..93c00996b 100644 --- a/Assets/Scripts/Gameplay/ActionGameManager.cs +++ b/Assets/Scripts/Gameplay/ActionGameManager.cs @@ -1336,6 +1336,23 @@ public class ActionGameManager : MonoBehaviour return true; } + public bool CommitDockedCurrentShip(Ship ship) + { + if (ship == null || + !ship.IsPlayerShip || + DockedEntity == null || + DockingBay == null || + !DockedEntity.Children.Contains(ship)) + { + return false; + } + + CurrentEntity = ship; + DockingBay.DockedShip = ship; + QueueRunCheckpoint("docked-current-ship"); + return true; + } + private static AetheriaRuntimeLoadoutTemplateSnapshot CreateRuntimeLoadoutTemplateSnapshot( AetheriaRuntimeLoadoutTemplateCommit template) { diff --git a/Assets/Scripts/UI/Menu/InventoryPanel.cs b/Assets/Scripts/UI/Menu/InventoryPanel.cs index 02b331af4..e929132e3 100644 --- a/Assets/Scripts/UI/Menu/InventoryPanel.cs +++ b/Assets/Scripts/UI/Menu/InventoryPanel.cs @@ -119,9 +119,8 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler { if(_displayedEntity is Ship ship) { - GameManager.CurrentEntity = ship; - GameManager.DockingBay.DockedShip = ship; - Current.targetGraphic.color = ToggleEnabledColor; + if (GameManager.CommitDockedCurrentShip(ship)) + Current.targetGraphic.color = ToggleEnabledColor; } else { diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index b4b311a33..8d67c313f 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -1406,6 +1406,10 @@ First Aetheria surfaces to publish: cargo-to-cargo, cargo-to-equipment, equipment-to-cargo, or equipment-to-equipment movement and then refresh display. uGUI still owns the presentation shell for now, not the inventory mutation. + - Done: route docked current-ship selection through + `ActionGameManager.CommitDockedCurrentShip`. `InventoryPanel` may request + a selected docked player ship and update the button color, but gameplay + owns `CurrentEntity`, `DockingBay.DockedShip`, and the typed checkpoint. - Replace the next concrete uGUI screen with an Eve-owned surface. - Move the staged packages into the Eve repo once its worktree is clean, then import them back into Aetheria from Eve instead of carrying a local copy. @@ -1733,7 +1737,9 @@ cargo/equipment movement, gameplay owns the move and queues the checkpoint. Trade purchases follow the same rule: UI requests the purchase, gameplay owns credit changes, cargo transfer, ship creation, and checkpoint. Runtime loadout restore follows the same rule: UI requests restoration, gameplay owns -instantiation, credits, dock assignment, current entity, and checkpoint. Any +instantiation, credits, dock assignment, current entity, and checkpoint. Docked +current-ship selection follows the same rule: UI requests selection, gameplay +owns `CurrentEntity`, `DockingBay.DockedShip`, and checkpoint. Any predicate that still needs legacy DTO objects must earn that dependency by using behavior objects or simulation-only methods that typed facets do not yet expose.