Complete typed behavior metadata coverage

This commit is contained in:
Meta Vens 2026-06-16 19:55:50 +01:00
commit 7bb896f41e
5 changed files with 99 additions and 2 deletions

View file

@ -32,6 +32,7 @@ RequireMainMenuSettingsCommit(root);
RequirePlayerSettingsEveSurface(root);
RequireMainMenuContinueRunState(root);
RequirePropertiesPanelReadOnlyInspector(root);
RequireTypedBehaviorMetadataCoverage(root);
RequireNoDeadRuntimeProjectionCaches(root);
RequireNoDeadInspectorMetadata(root);
RequireRuntimeSimulationTuningCommits(root);
@ -489,6 +490,7 @@ Console.WriteLine("Renderer-local debug panels: obsolete uGUI field tester autho
Console.WriteLine("Main-menu settings authority: player name, gameplay, and graphics settings return through typed player-settings commits");
Console.WriteLine("Main-menu Continue authority: Continue selects typed run state instead of a null button");
Console.WriteLine("PropertiesPanel inspector authority: dead generic reflection inspector path is deleted");
Console.WriteLine("Typed behavior metadata authority: live heat/mining/thermotoggle payload kinds stay owned by package metadata");
Console.WriteLine("Runtime simulation tuning authority: UI writes flow through gameplay checkpoint commits");
Console.WriteLine("Hull conductivity authority: inventory UI toggles flow through gameplay checkpoint commits");
Console.WriteLine("Inventory entity rename authority: UI rename flows through gameplay checkpoint commits");
@ -2419,6 +2421,71 @@ static void RequirePropertiesPanelReadOnlyInspector(string root)
}
}
static void RequireTypedBehaviorMetadataCoverage(string root)
{
var metadataPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeBehaviorMetadata.cs");
var propertiesPanelPath = Path.Combine(root, "Assets", "Scripts", "UI", "Properties Panel", "PropertiesPanel.cs");
var tradeMenuPath = Path.Combine(root, "Assets", "Scripts", "UI", "Menu", "TradeMenu.cs");
var metadata = File.Exists(metadataPath)
? File.ReadAllText(metadataPath)
: throw new InvalidOperationException("Cannot verify typed behavior metadata coverage; AetheriaRuntimeBehaviorMetadata.cs is missing.");
var propertiesPanel = File.Exists(propertiesPanelPath)
? File.ReadAllText(propertiesPanelPath)
: throw new InvalidOperationException("Cannot verify typed behavior metadata coverage; PropertiesPanel.cs is missing.");
var tradeMenu = File.Exists(tradeMenuPath)
? File.ReadAllText(tradeMenuPath)
: throw new InvalidOperationException("Cannot verify typed behavior metadata coverage; TradeMenu.cs is missing.");
var requiredMetadataSymbols = new[]
{
"AetheriaRuntimeBehaviorFieldValueKind.Temperature",
"Behavior(\"Heat\", \"\", Stat(\"Heat\", 1))",
"Behavior(\"MiningTool\", \"\", Stat(\"DamagePerSecond\", 1), Stat(\"Efficiency\", 2), Stat(\"Penetration\", 3), Stat(\"Range\", 4))",
"Behavior(\"Switch\", \"\")",
"Behavior(\"Thermotoggle\", \"\", Temperature(\"TargetTemperature\", 1))",
"Behavior(\"Trigger\", \"\")",
"Temperature(\"TemperatureFloor\", 3)"
};
var missingMetadataSymbols = requiredMetadataSymbols
.Where(symbol => !metadata.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingMetadataSymbols.Length > 0)
{
throw new InvalidOperationException(
"Typed behavior metadata no longer covers live heat/mining/thermotoggle payloads and switch/trigger shells: " +
string.Join(", ", missingMetadataSymbols));
}
var requiredUiSymbols = new[]
{
"AetheriaRuntimeBehaviorFieldValueKind.Temperature",
"FormatTemperature"
};
var missingPropertiesSymbols = requiredUiSymbols
.Where(symbol => !propertiesPanel.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingPropertiesSymbols.Length > 0)
{
throw new InvalidOperationException(
"PropertiesPanel no longer renders typed temperature-bearing behavior metadata: " +
string.Join(", ", missingPropertiesSymbols));
}
var missingTradeSymbols = requiredUiSymbols
.Where(symbol => !tradeMenu.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingTradeSymbols.Length > 0)
{
throw new InvalidOperationException(
"TradeMenu no longer renders typed temperature-bearing behavior metadata: " +
string.Join(", ", missingTradeSymbols));
}
}
static void RequireRuntimeSimulationTuningCommits(string root)
{
var requiredActionGameManagerPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "ActionGameManager.cs");

View file

@ -263,6 +263,15 @@ public class TradeMenu : MonoBehaviour
var value = GetTypedBehaviorNumber(x, behaviorFilter, field);
return () => ActionGameManager.RuntimePlayerSettings.Format((float)value);
}, x =>
{
return (float)GetTypedBehaviorNumber(x, behaviorFilter, field);
}));
else if (field.ValueKind == AetheriaRuntimeBehaviorFieldValueKind.Temperature)
columns.Add((field.Name, 1, x =>
{
var value = GetTypedBehaviorNumber(x, behaviorFilter, field);
return () => ActionGameManager.RuntimePlayerSettings.FormatTemperature((float)value);
}, x =>
{
return (float)GetTypedBehaviorNumber(x, behaviorFilter, field);
}));

View file

@ -455,6 +455,11 @@ public class PropertiesPanel : MonoBehaviour
var value = (float)(payloadField?.Value.NumberValue ?? 0);
sheet.AddStat(field.Name.SplitCamelCase(), () => $"{ActionGameManager.RuntimePlayerSettings.Format(value)}");
}
else if (field.ValueKind == AetheriaRuntimeBehaviorFieldValueKind.Temperature)
{
var value = (float)(payloadField?.Value.NumberValue ?? 0);
sheet.AddStat(field.Name.SplitCamelCase(), () => $"{ActionGameManager.RuntimePlayerSettings.FormatTemperature(value)}");
}
else if (field.ValueKind == AetheriaRuntimeBehaviorFieldValueKind.Integer)
{
var value = (int)(payloadField?.Value.NumberValue ?? 0);

View file

@ -8,7 +8,8 @@ namespace GameCult.Aetheria.State.Unity
{
Number,
Integer,
PerformanceStat
PerformanceStat,
Temperature
}
public sealed class AetheriaRuntimeBehaviorFieldMetadata
@ -74,15 +75,20 @@ namespace GameCult.Aetheria.State.Unity
Behavior(AetheriaRuntimeBehaviorKinds.AutoWeapon, AetheriaRuntimeBehaviorKinds.InstantWeapon, InstantWeaponFields),
Behavior("Cooldown", "", Stat("Cooldown", 1)),
Behavior("EnergyDraw", "", Stat("EnergyDraw", 1)),
Behavior("Heat", "", Stat("Heat", 1)),
Behavior("HeatStorage", ""),
Behavior("ItemUsage", ""),
Behavior("Radiator", "", Stat("Emissivity", 1), Stat("PumpedHeat", 2), Number("TemperatureFloor", 3), Stat("WasteHeat", 4), Stat("EnergyUsage", 5), Stat("ThermalMass", 6)),
Behavior("MiningTool", "", Stat("DamagePerSecond", 1), Stat("Efficiency", 2), Stat("Penetration", 3), Stat("Range", 4)),
Behavior("Radiator", "", Stat("Emissivity", 1), Stat("PumpedHeat", 2), Temperature("TemperatureFloor", 3), Stat("WasteHeat", 4), Stat("EnergyUsage", 5), Stat("ThermalMass", 6)),
Behavior("Reactor", "", Stat("Charge", 1), Stat("Efficiency", 2), Stat("OverloadEfficiency", 3), Stat("ThrottlingFactor", 4)),
Behavior("Reflector", "", Stat("CrossSection", 1)),
Behavior("ResourceScanner", "", Stat("Range", 1), Stat("MinimumDensity", 2), Stat("ScanDuration", 3)),
Behavior("Sensor", "", Stat("Sensitivity", 3), Stat("PingBoost", 5), Stat("PingEnergy", 6), Stat("PingVisibility", 7), Stat("PingRange", 8), Stat("PingCooldown", 9)),
Behavior("Shield", "", Stat("Efficiency", 1), Stat("EnergyUsage", 2)),
Behavior("Switch", ""),
Behavior("Thermotoggle", "", Temperature("TargetTemperature", 1)),
Behavior("Thruster", "", Stat("Thrust", 1), Stat("Visibility", 2), Stat("Heat", 3), Stat("EnergyUsage", 4)),
Behavior("Trigger", ""),
Behavior("TurretController", ""),
Behavior("VelocityConversion", "", Stat("Lambda", 1)),
Behavior("VelocityLimit", "", Stat("TopSpeed", 1)),
@ -142,6 +148,11 @@ namespace GameCult.Aetheria.State.Unity
return new AetheriaRuntimeBehaviorFieldMetadata(name, key, AetheriaRuntimeBehaviorFieldValueKind.Number);
}
private static AetheriaRuntimeBehaviorFieldMetadata Temperature(string name, int key)
{
return new AetheriaRuntimeBehaviorFieldMetadata(name, key, AetheriaRuntimeBehaviorFieldValueKind.Temperature);
}
private static AetheriaRuntimeBehaviorFieldMetadata[] With(
AetheriaRuntimeBehaviorFieldMetadata[] baseFields,
params AetheriaRuntimeBehaviorFieldMetadata[] extraFields)

View file

@ -1117,6 +1117,11 @@ First Aetheria surfaces to publish:
- Done: move PropertiesPanel generic behavior stat display off
`BehaviorData` reflection and onto package-owned typed behavior display
metadata keyed by behavior kind and payload field key.
- Done: complete package-owned typed behavior metadata coverage for live
`Heat`, `MiningTool`, and `Thermotoggle` payload fields plus `Switch` and
`Trigger` shell kinds. `PropertiesPanel` and `TradeMenu` no longer
silently drop those typed behavior families, and temperature-bearing
payload values format through the runtime temperature unit.
- Done: move TradeMenu behavior filter options, behavior family matching,
and dynamic behavior columns off `BehaviorData` reflection and onto
package-owned typed behavior metadata.