From 068bc116221fa50d22faa930a2565a81a29831ce Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 15 Jun 2026 18:51:59 +0100 Subject: [PATCH] Bypass configs for no-payload behaviors --- .voidbot/state/aetheria.cc | Bin 122261 -> 123629 bytes Aetheria.State/README.md | 3 + .../AetheriaRuntimeItemCatalog.cs | 1 + .../ServerShared/Behaviors/Behaviors.cs | 41 +++++++++- .../Scripts/ServerShared/Behaviors/Cockpit.cs | 17 +--- .../ServerShared/Behaviors/HeatStorage.cs | 17 +--- .../Scripts/ServerShared/Behaviors/Switch.cs | 17 +--- .../Scripts/ServerShared/Behaviors/Trigger.cs | 17 +--- .../Behaviors/TurretController.cs | 16 +--- Assets/Scripts/ServerShared/ItemManager.cs | 73 +++++++++++------- docs/aetheria-perfect-machine-map.md | 8 ++ 11 files changed, 108 insertions(+), 102 deletions(-) diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index c41f927e13829dbaf89fc90f30d73e7d06f47bbc..31b89ddbd503486b0f1426c1edaa537f0ce071a2 100644 GIT binary patch delta 1906 zcmb_dPiz%M9Cq5Kg;ET~yw(Pk9~G)?-g_-Ae_Crud94blRofCx(*yf<=k1$x-|ll} zw&f*6XuQbte&rPiq?Y54_yllkGdWZ}I|31&cN3HYY2G)Y*GvXW-Y$WYeLZaMPx` zT{ZV^&Ue=RvDEq6sFx`l6~{9y$kU=R!#obt%(Vo#-Yn!RWkU#%MXJtUCasfs&Mcc| zubPg*N~>h=uxCz}nM}h`YRGZval@u*7@uX*ET&Ksnafe`YZx%t(Jwky|M+Y}7%0-ATJymv?$z&8$ z8hMA%VD8n_nJ-4^DGA{{3TzXPl{~~DjF8j|f|bh7IyeIGp1l95CC;4I)NsL~4wY2D zGoGL({5-Nmh+_z_20|1Om}xjBY3VJ)MV|0%&S#F5TqQC?gKgLbbF1|`+u!&Q%zrz zjB0w1>~24~A*JwQIA>I-ZD&a;rF*~|@XNq7G$EIA>iir@HAMCGsI?p9r8+H$;N7XV zTrTb?L?MRA8eHd}F5E96IvW-cEL8WXOE<{Vby`{%*T{||j~z6)|7Ul7B+!8LK70JJ z1G?F`{b1j0N1c{@aOsyFPoR5sjgURTZ+Er?r8_T0(-|#elSZ@}RUdvprm7uH zrl?d+mBR0k4>p!j-FAt->B-IX+Y7wU&p%bAF50U2@A!9>(SJo8m0Xf_Kx zn~7{$Ep?ISo8LHr9$bMOrQH+0YjHzOb(79!t(Xu=5Wa~%D}sN9TGfw3q+@$Lqxud^ zUXg~48kg0rN627(??RF)8AcD~yq)}utBrnR{RN-qBv0=*La9 zi6Lei^as(Ruy~6WArwRrsQWZBy`$mx>^g54d0ELG zkB1_t#3$$4edN?g!efPO8p<7FH>B5k5#`8Ntmn$pyN(1#;(+y6fC$OCkJPcK@#z1iwTyA-H zeCBWG*=`t%w6VR8Qh}=`C3pe@H|@*VAdCVl%7H+gLJ(y@lu+iHhe(PH2x%4QNLmqM z4*{UN1W|zG*9_}mGFhBuupczHK3QOWE@2FPJ|SqxrN(SnEIhF&4Ouh);*5{0#l#)2 zHeF3Qf|XW}J636d1{^{ZxmSW)1W&6FY^6-2lzAl;Y=F2Xcn~3|v5V+f1Fq2Y4Jw1+ zDv-)TD9EvKq;n5F9}<}&H>l5x0;1Jxg!F~BsFT>H-2x4k`qm($J?iA&4N+!!#v ziUJo5a_#t;37b!)&bjCa7h%%J+z6F}Aw5bt;0}^CnP^XxfPM{QNE*?T!CJWy<@1qq zWl85Hwy`-Ik<=!4r&!14!c#6CU+L56nICIT-*}+Wn;(k#g?;gzg|*W+=Rd=NgU5w2 zLY6>S46_Fnl8g~FFa0k>!AnvZD;z^cOahIjw9Sjhu`+%8-$Gm4Gn^nH(!rc)C^?Vp zY;|}&d$u8Y-^B*1BVFueXY%tLYft_jVcRz>En0tZ^r7V?noU=WN7-Ow_5Kj+z16au zj=$7ztu5QGf!bESsfGG>XZxq>8(StringComparer.Ordinal); + Kind = definition?.Kind ?? ""; + Group = definition?.Group ?? 0; + Item = item; + ItemManager = Item.ItemManager; + } + + protected Behavior(RuntimeBehaviorDefinition definition, ConsumableItemEffect consumable) + { + _performanceStats = new Dictionary(StringComparer.Ordinal); + Kind = definition?.Kind ?? ""; + Group = definition?.Group ?? 0; + Consumable = consumable; + ItemManager = consumable.Entity.ItemManager; + } + public float Evaluate(PerformanceStat stat) => Item?.Evaluate(stat) ?? Consumable.Evaluate(stat); public bool TryGetPerformanceStat(string statName, out PerformanceStat stat) { - return !string.IsNullOrWhiteSpace(statName) && - _performanceStats.TryGetValue(statName, out stat); + if (!string.IsNullOrWhiteSpace(statName) && + _performanceStats.TryGetValue(statName, out stat)) + { + return true; + } + + stat = null; + return false; } private static Dictionary CapturePerformanceStats(RuntimeBehaviorConfig config) @@ -159,6 +184,18 @@ public interface IPopulationAssignment int AssignedPopulation { get; set; } } +public sealed class RuntimeBehaviorDefinition +{ + public string Kind { get; } + public int Group { get; } + + public RuntimeBehaviorDefinition(AetheriaRuntimeBehaviorPayload payload) + { + Kind = payload?.Kind ?? ""; + Group = payload?.Group ?? 0; + } +} + [Inspectable] public abstract class RuntimeBehaviorConfig { diff --git a/Assets/Scripts/ServerShared/Behaviors/Cockpit.cs b/Assets/Scripts/ServerShared/Behaviors/Cockpit.cs index f35acd664..89bec6210 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Cockpit.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Cockpit.cs @@ -6,26 +6,13 @@ using System.Collections.Generic; using Unity.Mathematics; using static Unity.Mathematics.math; -[Inspectable] -public class CockpitConfig : RuntimeBehaviorConfig -{ - public override Behavior CreateInstance(EquippedItem item) - { - return new Cockpit(this, item); - } - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new Cockpit(this, item); - } -} - public class Cockpit : Behavior { - public Cockpit(CockpitConfig data, EquippedItem item) : base(data, item) + public Cockpit(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { } - public Cockpit(CockpitConfig data, ConsumableItemEffect item) : base(data, item) + public Cockpit(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { } } diff --git a/Assets/Scripts/ServerShared/Behaviors/HeatStorage.cs b/Assets/Scripts/ServerShared/Behaviors/HeatStorage.cs index b8f52df84..aeeea7538 100644 --- a/Assets/Scripts/ServerShared/Behaviors/HeatStorage.cs +++ b/Assets/Scripts/ServerShared/Behaviors/HeatStorage.cs @@ -6,26 +6,13 @@ using System.Collections.Generic; using Unity.Mathematics; using static Unity.Mathematics.math; -[Inspectable] -public class HeatStorageConfig : RuntimeBehaviorConfig -{ - public override Behavior CreateInstance(EquippedItem item) - { - return new HeatStorage(this, item); - } - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new HeatStorage(this, item); - } -} - public class HeatStorage : Behavior { - public HeatStorage(HeatStorageConfig data, EquippedItem item) : base(data, item) + public HeatStorage(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { } - public HeatStorage(HeatStorageConfig data, ConsumableItemEffect item) : base(data, item) + public HeatStorage(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { } } diff --git a/Assets/Scripts/ServerShared/Behaviors/Switch.cs b/Assets/Scripts/ServerShared/Behaviors/Switch.cs index 368911124..ce9ec9e1e 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Switch.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Switch.cs @@ -4,27 +4,14 @@ using System; using System.Linq; -[Inspectable, Order(-25)] -public class SwitchConfig : RuntimeBehaviorConfig -{ - public override Behavior CreateInstance(EquippedItem item) - { - return new Switch(this, item); - } - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new Switch(this, item); - } -} - public class Switch : Behavior, IActivatedBehavior { public bool Activated { get; set; } - public Switch(SwitchConfig data, EquippedItem item) : base(data, item) + public Switch(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { } - public Switch(SwitchConfig data, ConsumableItemEffect item) : base(data, item) + public Switch(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { } diff --git a/Assets/Scripts/ServerShared/Behaviors/Trigger.cs b/Assets/Scripts/ServerShared/Behaviors/Trigger.cs index 3c60f133a..1080fb15f 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Trigger.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Trigger.cs @@ -4,26 +4,13 @@ using System; using System.Linq; -[Inspectable, Order(-20)] -public class TriggerConfig : RuntimeBehaviorConfig -{ - public override Behavior CreateInstance(EquippedItem item) - { - return new Trigger(this, item); - } - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new Trigger(this, item); - } -} - public class Trigger : Behavior, IActivatedBehavior { public bool _pulled; public bool Pulled => _pulled; - public Trigger(TriggerConfig data, EquippedItem item) : base(data, item) { } - public Trigger(TriggerConfig data, ConsumableItemEffect item) : base(data, item) { } + public Trigger(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { } + public Trigger(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { } public override bool Execute(float dt) { diff --git a/Assets/Scripts/ServerShared/Behaviors/TurretController.cs b/Assets/Scripts/ServerShared/Behaviors/TurretController.cs index b374b313a..718212ed3 100644 --- a/Assets/Scripts/ServerShared/Behaviors/TurretController.cs +++ b/Assets/Scripts/ServerShared/Behaviors/TurretController.cs @@ -8,18 +8,6 @@ using UniRx; using Unity.Mathematics; using static Unity.Mathematics.math; using float3 = Unity.Mathematics.float3; -public class TurretControllerConfig : RuntimeBehaviorConfig -{ - public override Behavior CreateInstance(EquippedItem item) - { - return new TurretController(this, item); - } - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new TurretController(this, item); - } -} - public class TurretController : Behavior, IInitializableBehavior { private List _weapons = new List(); @@ -30,11 +18,11 @@ public class TurretController : Behavior, IInitializableBehavior public float ShotSpeed => _shotSpeed; public bool PredictShots => _predictShots; - public TurretController(TurretControllerConfig data, EquippedItem item) : base(data, item) + public TurretController(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { } - public TurretController(TurretControllerConfig data, ConsumableItemEffect item) : base(data, item) + public TurretController(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { } diff --git a/Assets/Scripts/ServerShared/ItemManager.cs b/Assets/Scripts/ServerShared/ItemManager.cs index 4037a18ed..d70b100c9 100644 --- a/Assets/Scripts/ServerShared/ItemManager.cs +++ b/Assets/Scripts/ServerShared/ItemManager.cs @@ -61,32 +61,58 @@ public class ItemManager public Behavior[] CreateRuntimeBehaviors(EquippedItem item) { - return CreateRuntimeBehaviorConfigs(item?.EquippableItem) - .Select(config => config.CreateInstance(item)) - .ToArray(); + return GetRuntimeItem(item?.EquippableItem)?.BehaviorPayloads + .Select(payload => CreateRuntimeBehavior(payload, item)) + .Where(behavior => behavior != null) + .ToArray() ?? Array.Empty(); } public Behavior[] CreateRuntimeBehaviors(ConsumableItemEffect effect) { - return CreateRuntimeBehaviorConfigs(effect?.Item) - .Select(config => config.CreateInstance(effect)) - .ToArray(); - } - - private IReadOnlyList CreateRuntimeBehaviorConfigs(ItemInstance item) - { - var typedItem = GetRuntimeItem(item); - return typedItem == null - ? Array.Empty() - : BuildBehaviorConfigs(typedItem); - } - - private static RuntimeBehaviorConfig[] BuildBehaviorConfigs(AetheriaRuntimeCatalogItem item) - { - return item.BehaviorPayloads - .Select(BuildBehaviorConfig) + return GetRuntimeItem(effect?.Item)?.BehaviorPayloads + .Select(payload => CreateRuntimeBehavior(payload, effect)) .Where(behavior => behavior != null) - .ToArray(); + .ToArray() ?? Array.Empty(); + } + + private static Behavior CreateRuntimeBehavior(AetheriaRuntimeBehaviorPayload payload, EquippedItem item) + { + var directBehavior = CreateDirectRuntimeBehavior(payload, item); + return directBehavior ?? BuildBehaviorConfig(payload)?.CreateInstance(item); + } + + private static Behavior CreateRuntimeBehavior(AetheriaRuntimeBehaviorPayload payload, ConsumableItemEffect effect) + { + var directBehavior = CreateDirectRuntimeBehavior(payload, effect); + return directBehavior ?? BuildBehaviorConfig(payload)?.CreateInstance(effect); + } + + private static Behavior CreateDirectRuntimeBehavior(AetheriaRuntimeBehaviorPayload payload, EquippedItem item) + { + var definition = new RuntimeBehaviorDefinition(payload); + switch (payload.Kind) + { + case "Cockpit": return new Cockpit(definition, item); + case "HeatStorage": return new HeatStorage(definition, item); + case "Switch": return new Switch(definition, item); + case "Trigger": return new Trigger(definition, item); + case "TurretController": return new TurretController(definition, item); + default: return null; + } + } + + private static Behavior CreateDirectRuntimeBehavior(AetheriaRuntimeBehaviorPayload payload, ConsumableItemEffect effect) + { + var definition = new RuntimeBehaviorDefinition(payload); + switch (payload.Kind) + { + case "Cockpit": return new Cockpit(definition, effect); + case "HeatStorage": return new HeatStorage(definition, effect); + case "Switch": return new Switch(definition, effect); + case "Trigger": return new Trigger(definition, effect); + case "TurretController": return new TurretController(definition, effect); + default: return null; + } } private static RuntimeBehaviorConfig BuildBehaviorConfig(AetheriaRuntimeBehaviorPayload payload) @@ -97,13 +123,11 @@ public class ItemManager case "AutoWeapon": return Configure(new AutoWeaponConfig(), payload, ApplyInstantWeaponConfig); case "Capacitor": return Configure(new CapacitorConfig(), payload, ApplyCapacitorConfig); case "ChargedWeapon": return Configure(new ChargedWeaponConfig(), payload, ApplyChargedWeaponConfig); - case "Cockpit": return Configure(new CockpitConfig(), payload, null); case "ConstantWeapon": return Configure(new ConstantWeaponConfig(), payload, ApplyConstantWeaponConfig); case "Cooldown": return Configure(new CooldownConfig(), payload, ApplyCooldownConfig); case "EnergyDraw": return Configure(new EnergyDrawConfig(), payload, ApplyEnergyDrawConfig); case "GuidedWeapon": return Configure(new GuidedWeaponConfig(), payload, ApplyGuidedWeaponConfig); case "Heat": return Configure(new HeatConfig(), payload, ApplyHeatConfig); - case "HeatStorage": return Configure(new HeatStorageConfig(), payload, null); case "InstantWeapon": return Configure(new InstantWeaponConfig(), payload, ApplyInstantWeaponConfig); case "ItemUsage": return Configure(new ItemUsageConfig(), payload, ApplyItemUsageConfig); case "Launcher": return Configure(new LauncherConfig(), payload, ApplyLauncherConfig); @@ -115,11 +139,8 @@ public class ItemManager case "Sensor": return Configure(new SensorConfig(), payload, ApplySensorConfig); case "Shield": return Configure(new ShieldConfig(), payload, ApplyShieldConfig); case "StatModifier": return Configure(new StatModifierConfig(), payload, ApplyStatModifierConfig); - case "Switch": return Configure(new SwitchConfig(), payload, null); case "Thermotoggle": return Configure(new ThermotoggleConfig(), payload, ApplyThermotoggleConfig); case "Thruster": return Configure(new ThrusterConfig(), payload, ApplyThrusterConfig); - case "Trigger": return Configure(new TriggerConfig(), payload, null); - case "TurretController": return Configure(new TurretControllerConfig(), payload, null); case "VelocityConversion": return Configure(new VelocityConversionConfig(), payload, ApplyVelocityConversionConfig); case "VelocityLimit": return Configure(new VelocityLimitConfig(), payload, ApplyVelocityLimitConfig); case "Visibility": return Configure(new VisibilityConfig(), payload, ApplyVisibilityConfig); diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 436f6b8d1..96011fedc 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -322,6 +322,9 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. fields, burst/cooldown fields, charge multipliers, and lock parameters into runtime-owned fields. Behavior instances no longer retain their `RuntimeBehaviorConfig` subclasses after construction. + Cockpit, HeatStorage, Switch, Trigger, and TurretController now bypass + `RuntimeBehaviorConfig` entirely; `ItemManager` constructs those no-payload + behavior classes directly from typed runtime behavior definitions. `StatModifier` behavior requirements and behavior-stat targets compare typed behavior kinds on the live equipped behavior instances through `AetheriaRuntimeBehaviorMetadataCatalog` instead of scanning config @@ -1450,6 +1453,11 @@ First Aetheria surfaces to publish: all behavior subclasses now copy constructor config inputs into explicit runtime fields instead of keeping `RuntimeBehaviorConfig` subclass instances alive as state. + - Done: delete the no-payload `CockpitConfig`, `HeatStorageConfig`, + `SwitchConfig`, `TriggerConfig`, and `TurretControllerConfig` classes. + `ItemManager` now constructs those behavior kinds directly from typed + runtime behavior definitions rather than routing them through the + temporary config bridge. - Done: delete `LegacyPayloadKeyAttribute` from live Unity source after importer constants and explicit typed mappers became the only migrated field-key authorities.