From 18a4ead6f8b94ccc3a0901d0188c0201d2fe38de Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 15 Jun 2026 20:12:34 +0100 Subject: [PATCH] Delete runtime behavior config bridge --- .voidbot/state/aetheria.cc | Bin 128137 -> 131079 bytes Aetheria.State/README.md | 40 ++- .../ServerShared/Behaviors/AutoWeapon.cs | 13 +- .../ServerShared/Behaviors/Behaviors.cs | 60 +--- .../ServerShared/Behaviors/ChargedWeapon.cs | 111 +++----- .../ServerShared/Behaviors/ConstantWeapon.cs | 25 +- .../ServerShared/Behaviors/InstantWeapon.cs | 59 ++-- .../ServerShared/Behaviors/Launcher.cs | 59 ---- .../ServerShared/Behaviors/Launcher.cs.meta | 3 - .../ServerShared/Behaviors/LockWeapon.cs | 63 ++--- .../Scripts/ServerShared/Behaviors/Weapon.cs | 171 +++++------- Assets/Scripts/ServerShared/ItemManager.cs | 261 ++---------------- docs/aetheria-perfect-machine-map.md | 83 +++--- 13 files changed, 243 insertions(+), 705 deletions(-) delete mode 100644 Assets/Scripts/ServerShared/Behaviors/Launcher.cs delete mode 100644 Assets/Scripts/ServerShared/Behaviors/Launcher.cs.meta diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index 09423f081464e10b4e7f520484172ab795a8ed73..acecff7f6322f1a419893253de66237d6306b753 100644 GIT binary patch delta 1803 zcmah~PiS047-y1bYYEmr`BOb4(?buD-HqKeNn5v%9v|imlDw;g;$>-3cpB zw8M7xjrQFA=FC{%`dA-XJ5C;7zqw3aZM9y`4ekpeRJxJ(AOH(_9Z4%f$d|xpHKBB# zD_Is5_r+&qW!KuW540>K3mmylhG|I)uL4vUntbie(mJrJlKCiZ{~g%5eaMEC=lJlRf_qerB%Oxo=AP-Ip1 zJg>Iz&HGGOz{|FeD!#h)%p%Es&^gMaM_-79m&J7eVXZ61>WJG8wz5`X3OwTkt3?uo z6?pnAolBWIo|LtSmBy#cMI!LBJ;aG5=3>@{c#a-Tu@tyT;IJS_nWIl7u@qS_1`K5y zXhlinJq8kp8qgDXc7qxfX%2Mak1)mv=0vVqZDvRB;DrF~C z4yNT%2-2E^RB3E2v-l^pm#;F7u&a!(G8D~=OUD+*4a0Iwq|1zVmFj-}nhZ35S%A}) zRwFISf~OdK6$KtO9Pw%h88$&y5@h2^g-OPm;;e+gb%UzN8f-N}fJ~%YWv2Sg#hVg$ zc^p{x0bez3#$U)7f~re=M{e(xtNaUYcPJ|2n|#nG-5AY zVJJ$a7olw4Idf4%d1L$#w%wX>cekI6wm$l2WR%Y_gSgsmNR7l*7^Xcjtw;ab_dr`6 zv47mHezL<&uaW1*V zNh1{r^`_vS{f^|DU1GkpDx~*uBFtod=iE?tvQK|R+XkL2^! zEq-PfQvR1f*FZ1fEJJ!S(WL^WD$>sg`(StringComparer.Ordinal); @@ -103,19 +85,6 @@ public abstract class Behavior } } - private static Dictionary CapturePerformanceStats(RuntimeBehaviorConfig config) - { - return config == null - ? new Dictionary(StringComparer.Ordinal) - : config - .GetType() - .GetFields() - .Where(field => field.FieldType == typeof(PerformanceStat)) - .Select(field => (field.Name, Stat: field.GetValue(config) as PerformanceStat)) - .Where(entry => entry.Stat != null) - .ToDictionary(entry => entry.Name, entry => entry.Stat, StringComparer.Ordinal); - } - protected void AddHeat(float heat) => Item?.AddHeat(heat); // TODO: Heat for Consumables protected void CauseDamage(float damage) @@ -229,6 +198,11 @@ public sealed class RuntimeBehaviorDefinition return _fields.TryGetValue(key, out var value) ? (float)value.NumberValue : fallback; } + public int Int(int key, int fallback = 0) + { + return _fields.TryGetValue(key, out var value) ? checked((int)value.NumberValue) : fallback; + } + public uint UInt(int key, uint fallback = 0) { return _fields.TryGetValue(key, out var value) ? checked((uint)value.NumberValue) : fallback; @@ -272,6 +246,13 @@ public sealed class RuntimeBehaviorDefinition }; } + public float4[] Float4Array(int key, float4[] fallback) + { + return _fields.TryGetValue(key, out var value) + ? value.Children.Select(ToFloat4).ToArray() + : fallback; + } + public StatReference StatReference(int key, StatReference fallback) { if (!_fields.TryGetValue(key, out var value)) @@ -334,20 +315,3 @@ public sealed class RuntimeBehaviorDefinition return value.Children.Count > index ? value.Children[index].StringValue ?? "" : ""; } } - -[Inspectable] -public abstract class RuntimeBehaviorConfig -{ - public string Kind { get; set; } = ""; - - [Inspectable] - public int Group; - - public abstract Behavior CreateInstance(EquippedItem item); - public abstract Behavior CreateInstance(ConsumableItemEffect consumable); - - public override string ToString() - { - return base.ToString().FormatTypeName(); - } -} diff --git a/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs index a3872a02a..a79351924 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs @@ -4,56 +4,6 @@ using System.Collections.Generic; using Unity.Mathematics; using static Unity.Mathematics.math; -[Inspectable] -public class ChargedWeaponConfig : InstantWeaponConfig -{ - [Inspectable] - public PerformanceStat ChargeTime = new PerformanceStat(); - - [Inspectable] - public PerformanceStat ChargeEnergy = new PerformanceStat(); - - [Inspectable] - public PerformanceStat ChargeHeat = new PerformanceStat(); - - [Inspectable] - public bool CanFireEarly; - - [Inspectable] - public float FailureCharge; - - [Inspectable] - public float FailureDamage = 1; - - [Inspectable] - public float ChargeFiringDamageMultiplier = 1; - - [Inspectable] - public float ChargeFiringSpreadMultiplier = 1; - - [Inspectable] - public float ChargeFiringBurstCountMultiplier = 1; - - [Inspectable] - public float ChargeFiringVisibilityMultiplier = 1; - - [Inspectable] - public float ChargeFiringVelocityMultiplier = 1; - - [Inspectable] - public float ChargeFiringHeatMultiplier = 1; - - public override Behavior CreateInstance(EquippedItem item) - { - return new ChargedWeapon(this, item); - } - - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new ChargedWeapon(this, item); - } -} - public class ChargedWeapon : InstantWeapon { private readonly PerformanceStat _chargeTime; @@ -109,36 +59,45 @@ public class ChargedWeapon : InstantWeapon public bool Charging => _charging; public bool Charged => _charged; - public ChargedWeapon(ChargedWeaponConfig data, EquippedItem item) : base(data, item) + public ChargedWeapon(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { - _chargeTime = data.ChargeTime; - _chargeEnergy = data.ChargeEnergy; - _chargeHeat = data.ChargeHeat; - _canFireEarly = data.CanFireEarly; - _failureCharge = data.FailureCharge; - _failureDamage = data.FailureDamage; - _chargeFiringDamageMultiplier = data.ChargeFiringDamageMultiplier; - _chargeFiringSpreadMultiplier = data.ChargeFiringSpreadMultiplier; - _chargeFiringBurstCountMultiplier = data.ChargeFiringBurstCountMultiplier; - _chargeFiringVisibilityMultiplier = data.ChargeFiringVisibilityMultiplier; - _chargeFiringVelocityMultiplier = data.ChargeFiringVelocityMultiplier; - _chargeFiringHeatMultiplier = data.ChargeFiringHeatMultiplier; + _chargeTime = definition.PerformanceStat(21, new PerformanceStat()); + _chargeEnergy = definition.PerformanceStat(22, new PerformanceStat()); + _chargeHeat = definition.PerformanceStat(23, new PerformanceStat()); + _canFireEarly = definition.Bool(24); + _failureCharge = definition.Float(25); + _failureDamage = definition.Float(26, 1); + _chargeFiringDamageMultiplier = definition.Float(27, 1); + _chargeFiringSpreadMultiplier = definition.Float(28, 1); + _chargeFiringBurstCountMultiplier = definition.Float(29, 1); + _chargeFiringVisibilityMultiplier = definition.Float(30, 1); + _chargeFiringVelocityMultiplier = definition.Float(31, 1); + _chargeFiringHeatMultiplier = definition.Float(32, 1); + RegisterChargedWeaponStats(); } - public ChargedWeapon(ChargedWeaponConfig data, ConsumableItemEffect item) : base(data, item) + public ChargedWeapon(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { - _chargeTime = data.ChargeTime; - _chargeEnergy = data.ChargeEnergy; - _chargeHeat = data.ChargeHeat; - _canFireEarly = data.CanFireEarly; - _failureCharge = data.FailureCharge; - _failureDamage = data.FailureDamage; - _chargeFiringDamageMultiplier = data.ChargeFiringDamageMultiplier; - _chargeFiringSpreadMultiplier = data.ChargeFiringSpreadMultiplier; - _chargeFiringBurstCountMultiplier = data.ChargeFiringBurstCountMultiplier; - _chargeFiringVisibilityMultiplier = data.ChargeFiringVisibilityMultiplier; - _chargeFiringVelocityMultiplier = data.ChargeFiringVelocityMultiplier; - _chargeFiringHeatMultiplier = data.ChargeFiringHeatMultiplier; + _chargeTime = definition.PerformanceStat(21, new PerformanceStat()); + _chargeEnergy = definition.PerformanceStat(22, new PerformanceStat()); + _chargeHeat = definition.PerformanceStat(23, new PerformanceStat()); + _canFireEarly = definition.Bool(24); + _failureCharge = definition.Float(25); + _failureDamage = definition.Float(26, 1); + _chargeFiringDamageMultiplier = definition.Float(27, 1); + _chargeFiringSpreadMultiplier = definition.Float(28, 1); + _chargeFiringBurstCountMultiplier = definition.Float(29, 1); + _chargeFiringVisibilityMultiplier = definition.Float(30, 1); + _chargeFiringVelocityMultiplier = definition.Float(31, 1); + _chargeFiringHeatMultiplier = definition.Float(32, 1); + RegisterChargedWeaponStats(); + } + + private void RegisterChargedWeaponStats() + { + RegisterPerformanceStat(nameof(ChargeTime), _chargeTime); + RegisterPerformanceStat(nameof(ChargeEnergy), _chargeEnergy); + RegisterPerformanceStat(nameof(ChargeHeat), _chargeHeat); } protected override void UpdateStats() diff --git a/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs index fb4a8e489..1dc8aad70 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs @@ -6,23 +6,6 @@ using System; using Unity.Mathematics; using static Unity.Mathematics.math; -[Inspectable] -public class ConstantWeaponConfig : WeaponConfig -{ - [InspectablePrefab] - public float AmmoInterval = 1; - - public override Behavior CreateInstance(EquippedItem item) - { - return new ConstantWeapon(this, item); - } - - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new ConstantWeapon(this, item); - } -} - public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior { private readonly float _ammoIntervalDuration; @@ -63,14 +46,14 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior OnStopFiring = null; } - public ConstantWeapon(ConstantWeaponConfig data, EquippedItem item) : base(data, item) + public ConstantWeapon(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { - _ammoIntervalDuration = data.AmmoInterval; + _ammoIntervalDuration = definition.Float(17, 1); } - public ConstantWeapon(ConstantWeaponConfig data, ConsumableItemEffect item) : base(data, item) + public ConstantWeapon(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { - _ammoIntervalDuration = data.AmmoInterval; + _ammoIntervalDuration = definition.Float(17, 1); } public override bool Execute(float dt) diff --git a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs index df39a4122..6530e019a 100644 --- a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs @@ -4,32 +4,6 @@ using System.Collections.Generic; using Unity.Mathematics; using static Unity.Mathematics.math; -[Inspectable] -public class InstantWeaponConfig : WeaponConfig -{ - [Inspectable] - public PerformanceStat Count = new PerformanceStat(); - - [Inspectable] - public PerformanceStat BurstTime = new PerformanceStat(); - - [Inspectable] - public PerformanceStat Cooldown = new PerformanceStat(); - - [InspectablePrefab] - public bool SingleAmmoBurst; - - public override Behavior CreateInstance(EquippedItem item) - { - return new InstantWeapon(this, item); - } - - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new InstantWeapon(this, item); - } -} - public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior { private readonly PerformanceStat _count; @@ -82,22 +56,31 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior OnFire = null; } - public InstantWeapon(InstantWeaponConfig data, EquippedItem item) : base(data, item) + public InstantWeapon(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { - _count = data.Count; - _burstTime = data.BurstTime; - _cooldownDuration = data.Cooldown; - _singleAmmoBurst = data.SingleAmmoBurst; - _ammo = data.MagazineSize; + _count = definition.PerformanceStat(17, new PerformanceStat()); + _burstTime = definition.PerformanceStat(18, new PerformanceStat()); + _cooldownDuration = definition.PerformanceStat(19, new PerformanceStat()); + _singleAmmoBurst = definition.Bool(20); + _ammo = MagazineSize; + RegisterInstantWeaponStats(); } - public InstantWeapon(InstantWeaponConfig data, ConsumableItemEffect item) : base(data, item) + public InstantWeapon(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { - _count = data.Count; - _burstTime = data.BurstTime; - _cooldownDuration = data.Cooldown; - _singleAmmoBurst = data.SingleAmmoBurst; - _ammo = data.MagazineSize; + _count = definition.PerformanceStat(17, new PerformanceStat()); + _burstTime = definition.PerformanceStat(18, new PerformanceStat()); + _cooldownDuration = definition.PerformanceStat(19, new PerformanceStat()); + _singleAmmoBurst = definition.Bool(20); + _ammo = MagazineSize; + RegisterInstantWeaponStats(); + } + + private void RegisterInstantWeaponStats() + { + RegisterPerformanceStat("Count", _count); + RegisterPerformanceStat(nameof(BurstTime), _burstTime); + RegisterPerformanceStat(nameof(Cooldown), _cooldownDuration); } protected void Trigger() diff --git a/Assets/Scripts/ServerShared/Behaviors/Launcher.cs b/Assets/Scripts/ServerShared/Behaviors/Launcher.cs deleted file mode 100644 index e91629cbc..000000000 --- a/Assets/Scripts/ServerShared/Behaviors/Launcher.cs +++ /dev/null @@ -1,59 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -using Unity.Mathematics; - -[Inspectable] -public class LauncherConfig : LockWeaponConfig -{ - [InspectableAnimationCurve] - public float4[] GuidanceCurve; - - [InspectableAnimationCurve] - public float4[] ThrustCurve; - - [InspectableAnimationCurve] - public float4[] LiftCurve; - - [Inspectable] - public PerformanceStat Thrust = new PerformanceStat(); - - [Inspectable] - public float DodgeFrequency; - - [Inspectable] - public PerformanceStat MissileVelocity = new PerformanceStat(); - - public override Behavior CreateInstance(EquippedItem item) - { - return new LockWeapon(this, item); - } -} - -[Inspectable] -public class GuidedWeaponConfig : InstantWeaponConfig -{ - [InspectableAnimationCurve] - public float4[] GuidanceCurve; - - [InspectableAnimationCurve] - public float4[] ThrustCurve; - - [InspectableAnimationCurve] - public float4[] LiftCurve; - - [Inspectable] - public PerformanceStat Thrust = new PerformanceStat(); - - [Inspectable] - public float DodgeFrequency; - - [Inspectable] - public PerformanceStat MissileVelocity = new PerformanceStat(); - - public override Behavior CreateInstance(EquippedItem item) - { - return new InstantWeapon(this, item); - } -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/Launcher.cs.meta b/Assets/Scripts/ServerShared/Behaviors/Launcher.cs.meta deleted file mode 100644 index 4815b7661..000000000 --- a/Assets/Scripts/ServerShared/Behaviors/Launcher.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5fd0ce9fd7384ba5a40c2ba41ece74eb -timeCreated: 1584292825 \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/Behaviors/LockWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/LockWeapon.cs index dac1dcf58..4e1f6cda8 100644 --- a/Assets/Scripts/ServerShared/Behaviors/LockWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/LockWeapon.cs @@ -4,34 +4,6 @@ using System.Collections.Generic; using Unity.Mathematics; using static Unity.Mathematics.math; -[Inspectable] -public class LockWeaponConfig : InstantWeaponConfig -{ - [Inspectable] - public PerformanceStat LockSpeed = new PerformanceStat(); - - [Inspectable] - public PerformanceStat SensorImpact = new PerformanceStat(); - - [Inspectable] - public PerformanceStat LockAngle = new PerformanceStat(); - - [Inspectable] - public PerformanceStat DirectionImpact = new PerformanceStat(); - - [Inspectable] - public PerformanceStat Decay = new PerformanceStat(); - - public override Behavior CreateInstance(EquippedItem item) - { - return new LockWeapon(this, item); - } - public override Behavior CreateInstance(ConsumableItemEffect item) - { - return new LockWeapon(this, item); - } -} - public class LockWeapon : InstantWeapon { private readonly PerformanceStat _lockSpeed; @@ -66,21 +38,32 @@ public class LockWeapon : InstantWeapon public Entity LockTarget => _target; - public LockWeapon(LockWeaponConfig data, EquippedItem item) : base(data, item) + public LockWeapon(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { - _lockSpeed = data.LockSpeed; - _sensorImpact = data.SensorImpact; - _lockAngle = data.LockAngle; - _directionImpact = data.DirectionImpact; - _decay = data.Decay; + _lockSpeed = definition.PerformanceStat(21, new PerformanceStat()); + _sensorImpact = definition.PerformanceStat(22, new PerformanceStat()); + _lockAngle = definition.PerformanceStat(23, new PerformanceStat()); + _directionImpact = definition.PerformanceStat(24, new PerformanceStat()); + _decay = definition.PerformanceStat(25, new PerformanceStat()); + RegisterLockWeaponStats(); } - public LockWeapon(LockWeaponConfig data, ConsumableItemEffect item) : base(data, item) + public LockWeapon(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { - _lockSpeed = data.LockSpeed; - _sensorImpact = data.SensorImpact; - _lockAngle = data.LockAngle; - _directionImpact = data.DirectionImpact; - _decay = data.Decay; + _lockSpeed = definition.PerformanceStat(21, new PerformanceStat()); + _sensorImpact = definition.PerformanceStat(22, new PerformanceStat()); + _lockAngle = definition.PerformanceStat(23, new PerformanceStat()); + _directionImpact = definition.PerformanceStat(24, new PerformanceStat()); + _decay = definition.PerformanceStat(25, new PerformanceStat()); + RegisterLockWeaponStats(); + } + + private void RegisterLockWeaponStats() + { + RegisterPerformanceStat(nameof(LockSpeed), _lockSpeed); + RegisterPerformanceStat(nameof(SensorImpact), _sensorImpact); + RegisterPerformanceStat(nameof(LockAngle), _lockAngle); + RegisterPerformanceStat(nameof(DirectionImpact), _directionImpact); + RegisterPerformanceStat(nameof(Decay), _decay); } public override bool Execute(float dt) diff --git a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs index e0c28ba5d..8157dbe3d 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs @@ -7,56 +7,6 @@ using System.Linq; using Unity.Mathematics; using static Unity.Mathematics.math; -[Inspectable] -public abstract class WeaponConfig : RuntimeBehaviorConfig -{ - [Inspectable] - public DamageType DamageType; - - [Inspectable] - public PerformanceStat Damage = new PerformanceStat(); - - [InspectableRangedFloat(0,1)] - public PerformanceStat Penetration = new PerformanceStat(); - - [InspectableRangedFloat(0,1)] - public PerformanceStat DamageSpread = new PerformanceStat(); - - [Inspectable] - public PerformanceStat MinRange = new PerformanceStat(); - - [Inspectable] - public PerformanceStat Range = new PerformanceStat(); - - [InspectableAnimationCurve] - public BezierCurve DamageCurve; - - [InspectablePrefab] - public string EffectPrefab; - - [InspectablePrefab] - public PerformanceStat Energy = new PerformanceStat(); - - [InspectablePrefab] - public PerformanceStat Heat = new PerformanceStat(); - - [InspectablePrefab] - public PerformanceStat Visibility = new PerformanceStat(); - public string AmmoItemKey; - - [InspectablePrefab] - public int MagazineSize; - - [InspectablePrefab] - public float ReloadTime = 1; - - [InspectablePrefab] - public PerformanceStat Spread = new PerformanceStat(); - - [Inspectable] - public PerformanceStat Velocity = new PerformanceStat(); -} - public abstract class Weapon : Behavior, IActivatedBehavior { private readonly PerformanceStat _damage; @@ -107,70 +57,89 @@ public abstract class Weapon : Behavior, IActivatedBehavior get => _firing; } - public Weapon(WeaponConfig data, EquippedItem item) : base(data, item) + public Weapon(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item) { - _damage = data.Damage; - _penetration = data.Penetration; - _damageSpread = data.DamageSpread; - _minRange = data.MinRange; - _range = data.Range; - _energy = data.Energy; - _heat = data.Heat; - _visibility = data.Visibility; - _spread = data.Spread; - _velocity = data.Velocity; - DamageType = data.DamageType; - DamageCurve = data.DamageCurve; - EffectPrefab = data.EffectPrefab ?? ""; - AmmoItemKey = data.AmmoItemKey; - MagazineSize = data.MagazineSize; - ReloadTime = data.ReloadTime; - InitializeGuidedProjectileProfile(data); + _damage = definition.PerformanceStat(2, new PerformanceStat()); + _penetration = definition.PerformanceStat(3, new PerformanceStat()); + _damageSpread = definition.PerformanceStat(4, new PerformanceStat()); + _minRange = definition.PerformanceStat(5, new PerformanceStat()); + _range = definition.PerformanceStat(6, new PerformanceStat()); + _energy = definition.PerformanceStat(9, new PerformanceStat()); + _heat = definition.PerformanceStat(10, new PerformanceStat()); + _visibility = definition.PerformanceStat(11, new PerformanceStat()); + _spread = definition.PerformanceStat(15, new PerformanceStat()); + _velocity = definition.PerformanceStat(16, new PerformanceStat()); + DamageType = definition.Enum(1, default(DamageType)); + DamageCurve = definition.BezierCurve(7, null); + EffectPrefab = definition.String(8); + AmmoItemKey = definition.ItemKey(12); + MagazineSize = definition.Int(13); + ReloadTime = definition.Float(14, 1); + RegisterWeaponStats(); + InitializeGuidedProjectileProfile(definition); } - public Weapon(WeaponConfig data, ConsumableItemEffect item) : base(data, item) + public Weapon(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item) { - _damage = data.Damage; - _penetration = data.Penetration; - _damageSpread = data.DamageSpread; - _minRange = data.MinRange; - _range = data.Range; - _energy = data.Energy; - _heat = data.Heat; - _visibility = data.Visibility; - _spread = data.Spread; - _velocity = data.Velocity; - DamageType = data.DamageType; - DamageCurve = data.DamageCurve; - EffectPrefab = data.EffectPrefab ?? ""; - AmmoItemKey = data.AmmoItemKey; - MagazineSize = data.MagazineSize; - ReloadTime = data.ReloadTime; - InitializeGuidedProjectileProfile(data); + _damage = definition.PerformanceStat(2, new PerformanceStat()); + _penetration = definition.PerformanceStat(3, new PerformanceStat()); + _damageSpread = definition.PerformanceStat(4, new PerformanceStat()); + _minRange = definition.PerformanceStat(5, new PerformanceStat()); + _range = definition.PerformanceStat(6, new PerformanceStat()); + _energy = definition.PerformanceStat(9, new PerformanceStat()); + _heat = definition.PerformanceStat(10, new PerformanceStat()); + _visibility = definition.PerformanceStat(11, new PerformanceStat()); + _spread = definition.PerformanceStat(15, new PerformanceStat()); + _velocity = definition.PerformanceStat(16, new PerformanceStat()); + DamageType = definition.Enum(1, default(DamageType)); + DamageCurve = definition.BezierCurve(7, null); + EffectPrefab = definition.String(8); + AmmoItemKey = definition.ItemKey(12); + MagazineSize = definition.Int(13); + ReloadTime = definition.Float(14, 1); + RegisterWeaponStats(); + InitializeGuidedProjectileProfile(definition); } - private void InitializeGuidedProjectileProfile(WeaponConfig data) + private void RegisterWeaponStats() { - if (data is LauncherConfig launcher) + RegisterPerformanceStat(nameof(Damage), _damage); + RegisterPerformanceStat(nameof(Penetration), _penetration); + RegisterPerformanceStat(nameof(DamageSpread), _damageSpread); + RegisterPerformanceStat(nameof(MinRange), _minRange); + RegisterPerformanceStat(nameof(Range), _range); + RegisterPerformanceStat(nameof(Energy), _energy); + RegisterPerformanceStat(nameof(Heat), _heat); + RegisterPerformanceStat(nameof(Visibility), _visibility); + RegisterPerformanceStat(nameof(Spread), _spread); + RegisterPerformanceStat(nameof(Velocity), _velocity); + } + + private void InitializeGuidedProjectileProfile(RuntimeBehaviorDefinition definition) + { + if (string.Equals(definition.Kind, "Launcher")) { GuidedProjectileTargeting = GuidedProjectileTargetMode.TargetEntity; - GuidedProjectileGuidanceCurve = launcher.GuidanceCurve; - GuidedProjectileLiftCurve = launcher.LiftCurve; - GuidedProjectileThrustCurve = launcher.ThrustCurve; - GuidedProjectileDodgeFrequency = launcher.DodgeFrequency; - _guidedProjectileThrust = launcher.Thrust; - _guidedProjectileVelocity = launcher.MissileVelocity; + GuidedProjectileGuidanceCurve = definition.Float4Array(26, null); + GuidedProjectileThrustCurve = definition.Float4Array(27, null); + GuidedProjectileLiftCurve = definition.Float4Array(28, null); + _guidedProjectileThrust = definition.PerformanceStat(29, new PerformanceStat()); + GuidedProjectileDodgeFrequency = definition.Float(30); + _guidedProjectileVelocity = definition.PerformanceStat(31, new PerformanceStat()); } - else if (data is GuidedWeaponConfig guidance) + else if (string.Equals(definition.Kind, "GuidedWeapon")) { GuidedProjectileTargeting = GuidedProjectileTargetMode.LookDirection; - GuidedProjectileGuidanceCurve = guidance.GuidanceCurve; - GuidedProjectileLiftCurve = guidance.LiftCurve; - GuidedProjectileThrustCurve = guidance.ThrustCurve; - GuidedProjectileDodgeFrequency = guidance.DodgeFrequency; - _guidedProjectileThrust = guidance.Thrust; - _guidedProjectileVelocity = guidance.MissileVelocity; + GuidedProjectileGuidanceCurve = definition.Float4Array(21, null); + GuidedProjectileThrustCurve = definition.Float4Array(22, null); + GuidedProjectileLiftCurve = definition.Float4Array(23, null); + _guidedProjectileThrust = definition.PerformanceStat(24, new PerformanceStat()); + GuidedProjectileDodgeFrequency = definition.Float(25); + _guidedProjectileVelocity = definition.PerformanceStat(26, new PerformanceStat()); } + + RegisterPerformanceStat("Thrust", _guidedProjectileThrust); + RegisterPerformanceStat("MissileVelocity", _guidedProjectileVelocity); } protected virtual void UpdateStats() diff --git a/Assets/Scripts/ServerShared/ItemManager.cs b/Assets/Scripts/ServerShared/ItemManager.cs index ac3670a2f..d2b29ac8f 100644 --- a/Assets/Scripts/ServerShared/ItemManager.cs +++ b/Assets/Scripts/ServerShared/ItemManager.cs @@ -8,11 +8,9 @@ using System.Linq; using GameCult.Aetheria.State.Unity; using Unity.Mathematics; using static Unity.Mathematics.math; -using float2 = Unity.Mathematics.float2; using Random = Unity.Mathematics.Random; using JM.LinqFaster; using UniRx; -using float4 = Unity.Mathematics.float4; public class ItemManager { @@ -77,14 +75,12 @@ public class ItemManager private static Behavior CreateRuntimeBehavior(AetheriaRuntimeBehaviorPayload payload, EquippedItem item) { - var directBehavior = CreateDirectRuntimeBehavior(payload, item); - return directBehavior ?? BuildBehaviorConfig(payload)?.CreateInstance(item); + return CreateDirectRuntimeBehavior(payload, item); } private static Behavior CreateRuntimeBehavior(AetheriaRuntimeBehaviorPayload payload, ConsumableItemEffect effect) { - var directBehavior = CreateDirectRuntimeBehavior(payload, effect); - return directBehavior ?? BuildBehaviorConfig(payload)?.CreateInstance(effect); + return CreateDirectRuntimeBehavior(payload, effect); } private static Behavior CreateDirectRuntimeBehavior(AetheriaRuntimeBehaviorPayload payload, EquippedItem item) @@ -94,12 +90,19 @@ public class ItemManager { case "Cockpit": return new Cockpit(definition, item); case "AetherDrive": return new AetherDrive(definition, item); + case "AutoWeapon": return new AutoWeapon(definition, item); case "Capacitor": return new Capacitor(definition, item); + case "ChargedWeapon": return new ChargedWeapon(definition, item); case "Cooldown": return new Cooldown(definition, item); + case "ConstantWeapon": return new ConstantWeapon(definition, item); case "EnergyDraw": return new EnergyDraw(definition, item); + case "GuidedWeapon": return new InstantWeapon(definition, item); case "Heat": return new Heat(definition, item); case "HeatStorage": return new HeatStorage(definition, item); + case "InstantWeapon": return new InstantWeapon(definition, item); case "ItemUsage": return new ItemUsage(definition, item); + case "Launcher": return new LockWeapon(definition, item); + case "LockWeapon": return new LockWeapon(definition, item); case "MiningTool": return new MiningTool(definition, item); case "Radiator": return new Radiator(definition, item); case "Reactor": return new Reactor(definition, item); @@ -128,12 +131,19 @@ public class ItemManager { case "Cockpit": return new Cockpit(definition, effect); case "AetherDrive": return new AetherDrive(definition, effect); + case "AutoWeapon": return new InstantWeapon(definition, effect); case "Capacitor": return new Capacitor(definition, effect); + case "ChargedWeapon": return new ChargedWeapon(definition, effect); case "Cooldown": return new Cooldown(definition, effect); + case "ConstantWeapon": return new ConstantWeapon(definition, effect); case "EnergyDraw": return new EnergyDraw(definition, effect); + case "GuidedWeapon": return new InstantWeapon(definition, effect); case "Heat": return new Heat(definition, effect); case "HeatStorage": return new HeatStorage(definition, effect); + case "InstantWeapon": return new InstantWeapon(definition, effect); case "ItemUsage": return new ItemUsage(definition, effect); + case "Launcher": return new LockWeapon(definition, effect); + case "LockWeapon": return new LockWeapon(definition, effect); case "MiningTool": return new MiningTool(definition, effect); case "Radiator": return new Radiator(definition, effect); case "Reactor": return new Reactor(definition, effect); @@ -155,245 +165,6 @@ public class ItemManager } } - private static RuntimeBehaviorConfig BuildBehaviorConfig(AetheriaRuntimeBehaviorPayload payload) - { - switch (payload.Kind) - { - case "AutoWeapon": return Configure(new AutoWeaponConfig(), payload, ApplyInstantWeaponConfig); - case "ChargedWeapon": return Configure(new ChargedWeaponConfig(), payload, ApplyChargedWeaponConfig); - case "ConstantWeapon": return Configure(new ConstantWeaponConfig(), payload, ApplyConstantWeaponConfig); - case "GuidedWeapon": return Configure(new GuidedWeaponConfig(), payload, ApplyGuidedWeaponConfig); - case "InstantWeapon": return Configure(new InstantWeaponConfig(), payload, ApplyInstantWeaponConfig); - case "Launcher": return Configure(new LauncherConfig(), payload, ApplyLauncherConfig); - default: return null; - } - } - - private static T Configure(T config, AetheriaRuntimeBehaviorPayload payload, Action apply) - where T : RuntimeBehaviorConfig - { - var reader = new BehaviorPayloadReader(payload); - config.Kind = payload.Kind; - config.Group = payload.Group; - apply?.Invoke(config, reader); - return config; - } - - private static void ApplyWeaponConfig(WeaponConfig config, BehaviorPayloadReader reader) - { - config.DamageType = reader.Enum(1, config.DamageType); - config.Damage = reader.PerformanceStat(2, config.Damage); - config.Penetration = reader.PerformanceStat(3, config.Penetration); - config.DamageSpread = reader.PerformanceStat(4, config.DamageSpread); - config.MinRange = reader.PerformanceStat(5, config.MinRange); - config.Range = reader.PerformanceStat(6, config.Range); - config.DamageCurve = reader.BezierCurve(7, config.DamageCurve); - config.EffectPrefab = reader.String(8, config.EffectPrefab); - config.Energy = reader.PerformanceStat(9, config.Energy); - config.Heat = reader.PerformanceStat(10, config.Heat); - config.Visibility = reader.PerformanceStat(11, config.Visibility); - config.AmmoItemKey = reader.ItemKey(12, config.AmmoItemKey); - config.MagazineSize = reader.Int(13, config.MagazineSize); - config.ReloadTime = reader.Float(14, config.ReloadTime); - config.Spread = reader.PerformanceStat(15, config.Spread); - config.Velocity = reader.PerformanceStat(16, config.Velocity); - } - - private static void ApplyInstantWeaponConfig(InstantWeaponConfig config, BehaviorPayloadReader reader) - { - ApplyWeaponConfig(config, reader); - config.Count = reader.PerformanceStat(17, config.Count); - config.BurstTime = reader.PerformanceStat(18, config.BurstTime); - config.Cooldown = reader.PerformanceStat(19, config.Cooldown); - config.SingleAmmoBurst = reader.Bool(20, config.SingleAmmoBurst); - } - - private static void ApplyConstantWeaponConfig(ConstantWeaponConfig config, BehaviorPayloadReader reader) - { - ApplyWeaponConfig(config, reader); - config.AmmoInterval = reader.Float(17, config.AmmoInterval); - } - - private static void ApplyChargedWeaponConfig(ChargedWeaponConfig config, BehaviorPayloadReader reader) - { - ApplyInstantWeaponConfig(config, reader); - config.ChargeTime = reader.PerformanceStat(21, config.ChargeTime); - config.ChargeEnergy = reader.PerformanceStat(22, config.ChargeEnergy); - config.ChargeHeat = reader.PerformanceStat(23, config.ChargeHeat); - config.CanFireEarly = reader.Bool(24, config.CanFireEarly); - config.FailureCharge = reader.Float(25, config.FailureCharge); - config.FailureDamage = reader.Float(26, config.FailureDamage); - config.ChargeFiringDamageMultiplier = reader.Float(27, config.ChargeFiringDamageMultiplier); - config.ChargeFiringSpreadMultiplier = reader.Float(28, config.ChargeFiringSpreadMultiplier); - config.ChargeFiringBurstCountMultiplier = reader.Float(29, config.ChargeFiringBurstCountMultiplier); - config.ChargeFiringVisibilityMultiplier = reader.Float(30, config.ChargeFiringVisibilityMultiplier); - config.ChargeFiringVelocityMultiplier = reader.Float(31, config.ChargeFiringVelocityMultiplier); - config.ChargeFiringHeatMultiplier = reader.Float(32, config.ChargeFiringHeatMultiplier); - } - - private static void ApplyLockWeaponConfig(LockWeaponConfig config, BehaviorPayloadReader reader) - { - ApplyInstantWeaponConfig(config, reader); - config.LockSpeed = reader.PerformanceStat(21, config.LockSpeed); - config.SensorImpact = reader.PerformanceStat(22, config.SensorImpact); - config.LockAngle = reader.PerformanceStat(23, config.LockAngle); - config.DirectionImpact = reader.PerformanceStat(24, config.DirectionImpact); - config.Decay = reader.PerformanceStat(25, config.Decay); - } - - private static void ApplyLauncherConfig(LauncherConfig config, BehaviorPayloadReader reader) - { - ApplyLockWeaponConfig(config, reader); - config.GuidanceCurve = reader.Float4Array(26, config.GuidanceCurve); - config.ThrustCurve = reader.Float4Array(27, config.ThrustCurve); - config.LiftCurve = reader.Float4Array(28, config.LiftCurve); - config.Thrust = reader.PerformanceStat(29, config.Thrust); - config.DodgeFrequency = reader.Float(30, config.DodgeFrequency); - config.MissileVelocity = reader.PerformanceStat(31, config.MissileVelocity); - } - - private static void ApplyGuidedWeaponConfig(GuidedWeaponConfig config, BehaviorPayloadReader reader) - { - ApplyInstantWeaponConfig(config, reader); - config.GuidanceCurve = reader.Float4Array(21, config.GuidanceCurve); - config.ThrustCurve = reader.Float4Array(22, config.ThrustCurve); - config.LiftCurve = reader.Float4Array(23, config.LiftCurve); - config.Thrust = reader.PerformanceStat(24, config.Thrust); - config.DodgeFrequency = reader.Float(25, config.DodgeFrequency); - config.MissileVelocity = reader.PerformanceStat(26, config.MissileVelocity); - } - - private sealed class BehaviorPayloadReader - { - private readonly IReadOnlyDictionary _fields; - - public BehaviorPayloadReader(AetheriaRuntimeBehaviorPayload payload) - { - var fields = new Dictionary(); - foreach (var field in payload.Fields) - { - if (!fields.ContainsKey(field.Key)) - { - fields.Add(field.Key, field.Value); - } - } - - _fields = fields; - } - - public string String(int key, string fallback = "") - { - return _fields.TryGetValue(key, out var value) ? value.StringValue ?? "" : fallback; - } - - public bool Bool(int key, bool fallback = false) - { - return _fields.TryGetValue(key, out var value) ? value.BoolValue : fallback; - } - - public float Float(int key, float fallback = 0) - { - return _fields.TryGetValue(key, out var value) ? (float)value.NumberValue : fallback; - } - - public int Int(int key, int fallback = 0) - { - return _fields.TryGetValue(key, out var value) ? checked((int)value.NumberValue) : fallback; - } - - public string ItemKey(int key, string fallback = "") - { - return _fields.TryGetValue(key, out var value) && - !string.IsNullOrWhiteSpace(value.ItemKeyValue) - ? value.ItemKeyValue - : fallback; - } - - public T Enum(int key, T fallback) where T : struct - { - if (!_fields.TryGetValue(key, out var value)) - { - return fallback; - } - - if (!string.IsNullOrWhiteSpace(value.StringValue) && - System.Enum.TryParse(value.StringValue, true, out T parsed)) - { - return parsed; - } - - return (T)System.Enum.ToObject(typeof(T), checked((int)value.NumberValue)); - } - - public float4[] Float4Array(int key, float4[] fallback) - { - return _fields.TryGetValue(key, out var value) - ? value.Children.Select(ToFloat4).ToArray() - : fallback; - } - - public PerformanceStat PerformanceStat(int key, PerformanceStat fallback) - { - return _fields.TryGetValue(key, out var value) ? ToPerformanceStat(value) : fallback; - } - - public BezierCurve BezierCurve(int key, BezierCurve fallback) - { - if (!_fields.TryGetValue(key, out var value)) - { - return fallback; - } - - return new BezierCurve - { - Keys = value.Children.Count > 0 - ? value.Children[0].Children.Select(ToFloat4).ToArray() - : Array.Empty() - }; - } - - public StatReference StatReference(int key, StatReference fallback) - { - if (!_fields.TryGetValue(key, out var value)) - { - return fallback; - } - - return new StatReference - { - Target = ChildString(value, 1), - Stat = ChildString(value, 2) - }; - } - - private static PerformanceStat ToPerformanceStat(AetheriaRuntimeBehaviorValue value) - { - return new PerformanceStat - { - Min = ChildFloat(value, 0), - Max = ChildFloat(value, 1), - HeatExponentMultiplier = ChildFloat(value, 2), - DurabilityExponentMultiplier = ChildFloat(value, 3), - QualityExponent = ChildFloat(value, 4) - }; - } - - private static float4 ToFloat4(AetheriaRuntimeBehaviorValue value) - { - return new float4(ChildFloat(value, 0), ChildFloat(value, 1), ChildFloat(value, 2), ChildFloat(value, 3)); - } - - private static float ChildFloat(AetheriaRuntimeBehaviorValue value, int index) - { - return value.Children.Count > index ? (float)value.Children[index].NumberValue : 0; - } - - private static string ChildString(AetheriaRuntimeBehaviorValue value, int index) - { - return value.Children.Count > index ? value.Children[index].StringValue ?? "" : ""; - } - } - public Shape GetRuntimeShape(ItemInstance item) { var typedItem = GetRuntimeItem(item); diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 7781171e6..e77903ac7 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -53,8 +53,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. while hosting the CultMesh state node. `Aetheria.State.ApplyPending` remains a bounded local operator applicator for both pending lanes. - Shared item domain state is now built around typed item-key references, - typed runtime catalog rows, explicit `RuntimeBehaviorConfig` projection, and - runtime geometry/stat primitives. The old `ItemData` DTO hierarchy is deleted + typed runtime catalog rows, direct `RuntimeBehaviorDefinition` behavior + construction, and runtime geometry/stat primitives. The old `ItemData` DTO hierarchy is deleted from live Unity source. Dead user-record and galaxy-map-layer catalog roots have been deleted, and surviving runtime DTOs no longer carry legacy catalog group/table annotations. Newtonsoft, @@ -235,11 +235,10 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. for item selection and instantiation. Hull type, hardpoint type, shape fit, station bay fit, hull/category, and behavior-kind prefilters run against typed catalog rows. `EquippedItem` and `ConsumableItemEffect` now create behavior - instances through `ItemManager.CreateRuntimeBehaviors`; the remaining - `RuntimeBehaviorConfig` bridge is explicitly temporary and internal to - behavior construction. Behavior config construction now switches on stable - typed behavior kind and uses an explicit per-kind payload mapper; layout - metadata no longer selects or mutates runtime behavior configs. + instances through `ItemManager.CreateRuntimeBehaviors`, which switches on + stable typed behavior kind and constructs live behavior classes directly from + `RuntimeBehaviorDefinition`; layout metadata no longer selects or mutates + runtime behavior configs. `StatModifier` requirement and stat-target lookup now inspects the live equipped behavior instances and asks package-owned typed behavior metadata for kind/family matching, not a freshly rebuilt config list or a @@ -297,11 +296,9 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. derives from the typed runtime catalog row. `EquippedItem.InsetShape` now derives from typed hull/item shape rows. `EquippedItem` and `ConsumableItemEffect` behavior construction now read typed behavior payloads - through the runtime behavior config bridge before instantiating the - current behavior classes. `RuntimeBehaviorConfig` remains the temporary - behavior-class construction bridge, not the runtime behavior payload owner; - bridge instances carry the typed behavior payload kind so runtime logic does - not have to reselect behavior identity from the old class graph. + through `RuntimeBehaviorDefinition` before instantiating the current behavior + classes. The old behavior config bridge is deleted; typed behavior kind and + group flow directly into live behavior instances. Base `Behavior` now captures a runtime performance-stat table during construction and no longer retains the config object for later stat lookup. Heat, EnergyDraw, and Cooldown behavior instances now copy constructor @@ -320,22 +317,25 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. InstantWeapon, ConstantWeapon, ChargedWeapon, and LockWeapon now copy constructor stats, curves, ammo/reload fields, guided projectile profile 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. + runtime-owned fields. Behavior instances no longer retain construction config + DTOs after construction. + Cockpit, HeatStorage, Switch, Trigger, and TurretController read directly from + typed runtime behavior definitions. Heat, EnergyDraw, Cooldown, Wear, Visibility, Reflector, VelocityLimit, VelocityConversion, and ItemUsage also bypass the temporary config bridge and read typed behavior fields through `RuntimeBehaviorDefinition`; stat-bearing behaviors register their runtime performance stats explicitly for `StatModifier` rather than relying on config reflection. Capacitor, Shield, MiningTool, ResourceScanner, Thermotoggle, and Thruster now - follow the same direct-definition path, so the temporary config bridge no - longer constructs those medium behavior classes. + follow the same direct-definition path. Reactor, Radiator, Sensor, StatModifier, and AetherDrive also read typed payload fields through `RuntimeBehaviorDefinition`; their live stat surfaces are registered explicitly rather than recovered through config reflection. + Weapon, InstantWeapon, AutoWeapon, ConstantWeapon, ChargedWeapon, LockWeapon, + Launcher, and GuidedWeapon payloads also construct directly from + `RuntimeBehaviorDefinition`; the old `RuntimeBehaviorConfig`, + `BehaviorPayloadReader`, and weapon `*Config` classes are deleted from live + source. `StatModifier` behavior requirements and behavior-stat targets compare typed behavior kinds on the live equipped behavior instances through `AetheriaRuntimeBehaviorMetadataCatalog` instead of scanning config @@ -658,12 +658,10 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. contract for full .NET smokes and Eve surface reads. Neither writes state or owns simulation. The runtime no longer has a MessagePack catalog cache or whole-item DTO projection cache. `AetheriaRuntimeItemCatalog` exposes typed - item rows only. `ItemManager.CreateRuntimeBehaviors` owns the temporary - projection from typed behavior payloads into `RuntimeBehaviorConfig` objects - required by the current behavior constructors. This projection is an explicit - typed behavior-kind switch with per-kind field mapping; it no longer reflects - over `LegacyPayloadKeyAttribute` to select or assign config fields. Direct - config reads no longer escape `ItemManager`; + item rows only. `ItemManager.CreateRuntimeBehaviors` owns the explicit typed + behavior-kind switch from typed payloads into live behavior instances. There + is no remaining `RuntimeBehaviorConfig` projection and no reflection over + `LegacyPayloadKeyAttribute` to select or assign config fields; gameplay stat modifiers target live behavior instances and package-owned behavior metadata instead of rebuilding config DTOs for lookup. `ItemInstance.Reference` stores the typed item key, `ItemInstance.ItemKey` @@ -1048,35 +1046,33 @@ First Aetheria surfaces to publish: shape rows; legacy `HullData.Shape`/`EquippableItemData.Shape` no longer decide equipped-item temperature footprint geometry. - Done: move `EquippedItem` and `ConsumableItemEffect` behavior construction - off `Data.Behaviors` and onto typed runtime behavior payload config - construction; `RuntimeBehaviorConfig` remains only the temporary - behavior-class construction bridge. + off `Data.Behaviors` and onto typed runtime behavior payload construction. - Done: route `EquippedItem` and `ConsumableItemEffect` behavior instance - creation through `ItemManager.CreateRuntimeBehaviors`; temporary config - reads are internal to that construction bridge. + creation through `ItemManager.CreateRuntimeBehaviors`; behavior reads now + go through `RuntimeBehaviorDefinition`. - Done: move the temporary behavior config constructor map from legacy union keys to typed behavior payload kind strings; union keys remain migration provenance only for this runtime path. - Done: move `StatModifier` behavior requirements and behavior-stat targets off `EquippableItemData.Behaviors` and old `BehaviorData` subclass - identity checks. Temporary behavior configs carry typed payload kinds, and + identity checks. Live behaviors carry typed payload kinds, and `StatModifier` matches those kind strings for target and requirement selection. The obsolete item-DTO stat target branch is deleted because the live equippable item DTO hierarchy has no active `PerformanceStat` fields. - Done: move `StatModifier` target and requirement lookup onto the live equipped behavior instances. It now modifies the `PerformanceStat` objects - actually held by runtime behavior configs instead of rebuilding temporary - config DTOs from the catalog. + actually held by runtime behaviors instead of rebuilding temporary config + DTOs from the catalog. - Done: delete the generic `BehaviorPayloadReader.Guid(...)` helper from `ItemManager`; migrated behavior payload legacy-ID fields now cross the runtime bridge only through the explicit `ItemKey(...)` projection. - Done: move `StatModifier` behavior kind/family matching onto `AetheriaRuntimeBehaviorMetadataCatalog`; the behavior only normalizes migrated `*Data` tokens before asking the package-owned metadata owner. - - Done: move live behavior identity reads from the temporary - `RuntimeBehaviorConfig` bridge onto `Behavior.Kind` and `Behavior.Group`, so state - snapshots, weapon snapshots, progress rows, stat-modifier matching, and - behavior grouping use runtime instance identity. + - Done: move live behavior identity reads onto `Behavior.Kind` and + `Behavior.Group`, so state snapshots, weapon snapshots, progress rows, + stat-modifier matching, and behavior grouping use runtime instance + identity. - Done: move TurretController's weapon range/velocity reads off weapon config casts and onto `Weapon.EvaluateRange`/`EvaluateVelocity`; copied weapon range and velocity fields are owned by the weapon runtime. @@ -1447,9 +1443,7 @@ First Aetheria surfaces to publish: behavior config methods to temporary behavior config construction so old projection vocabulary no longer implies item DTO authority. - Done: delete `IRuntimeItemCatalogReader.GetTemporaryBehaviorConfigs`; the - runtime catalog reader now exposes typed item rows only, and the remaining - `RuntimeBehaviorConfig` projection is private `ItemManager` behavior - construction machinery. + runtime catalog reader now exposes typed item rows only. - Done: rename the temporary behavior construction DTO family from `BehaviorData`/`*Data` to `RuntimeBehaviorConfig`/`*Config`; live `Behavior` instances expose typed kind/group values while typed behavior @@ -1487,8 +1481,13 @@ First Aetheria surfaces to publish: `StatModifier`. - Done: delete `AetherDriveConfig`. `RuntimeBehaviorDefinition` now reads rotor geometry, RPM/coupling/torque/energy/passive-coupling stats, torque - curve, audio parameters, and particle prefab path directly; the remaining - `RuntimeBehaviorConfig` bridge is weapon-family-only. + curve, audio parameters, and particle prefab path directly. + - Done: delete the weapon config hierarchy and the last + `RuntimeBehaviorConfig` bridge. Weapon-family behavior construction now + reads common stats, instant/constant/charged/lock fields, and guided + projectile profiles directly through `RuntimeBehaviorDefinition`; + `BehaviorPayloadReader`, `BuildBehaviorConfig`, and config reflection are + gone from live Unity source. - Done: delete `LegacyPayloadKeyAttribute` from live Unity source after importer constants and explicit typed mappers became the only migrated field-key authorities.