Demote behavior configs from stat authority

This commit is contained in:
Meta Vens 2026-06-15 17:38:55 +01:00
commit 26148829bd
4 changed files with 22 additions and 15 deletions

Binary file not shown.

View file

@ -176,7 +176,9 @@ documents exist. Live behavior instances expose typed behavior kind and group
through `Behavior.Kind` and `Behavior.Group`; the remaining
`RuntimeBehaviorConfig` objects are private construction configs, not runtime
identity owners or a public behavior API. Stat modifiers ask live behavior
instances for target stats instead of reading behavior config objects directly.
instances for target stats instead of reading behavior config objects directly;
base `Behavior` captures a runtime stat table at construction and no longer
retains the config object for later reflection.
`ItemManager` currently owns the explicit typed-payload-to-config bridge.
Typed name-file documents are `aetheria.name_file.v2` records. They carry the
legacy ID, display name, count, compact sample names for surfaces, and the full

View file

@ -12,7 +12,7 @@ using static Unity.Mathematics.noise;
public abstract class Behavior
{
private readonly RuntimeBehaviorConfig _config;
private readonly Dictionary<string, PerformanceStat> _performanceStats;
public string Kind { get; }
public int Group { get; }
public EquippedItem Item { get; }
@ -46,7 +46,7 @@ public abstract class Behavior
protected Behavior(RuntimeBehaviorConfig config, EquippedItem item)
{
_config = config;
_performanceStats = CapturePerformanceStats(config);
Kind = config?.Kind ?? "";
Group = config?.Group ?? 0;
Item = item;
@ -55,7 +55,7 @@ public abstract class Behavior
protected Behavior(RuntimeBehaviorConfig config, ConsumableItemEffect consumable)
{
_config = config;
_performanceStats = CapturePerformanceStats(config);
Kind = config?.Kind ?? "";
Group = config?.Group ?? 0;
Consumable = consumable;
@ -66,18 +66,21 @@ public abstract class Behavior
public bool TryGetPerformanceStat(string statName, out PerformanceStat stat)
{
stat = null;
if (_config == null || string.IsNullOrWhiteSpace(statName))
{
return false;
}
return !string.IsNullOrWhiteSpace(statName) &&
_performanceStats.TryGetValue(statName, out stat);
}
var statField = _config
.GetType()
.GetFields()
.FirstOrDefault(field => field.FieldType == typeof(PerformanceStat) && field.Name == statName);
stat = statField?.GetValue(_config) as PerformanceStat;
return stat != null;
private static Dictionary<string, PerformanceStat> CapturePerformanceStats(RuntimeBehaviorConfig config)
{
return config == null
? new Dictionary<string, PerformanceStat>(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

View file

@ -302,6 +302,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
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.
Base `Behavior` now captures a runtime performance-stat table during
construction and no longer retains the config object for later stat lookup.
`StatModifier` behavior requirements and behavior-stat targets compare typed
behavior kinds on the live equipped behavior instances through
`AetheriaRuntimeBehaviorMetadataCatalog` instead of scanning config