Demote runtime player settings projection

This commit is contained in:
Meta Vens 2026-06-13 18:48:53 +01:00
commit 3f2614cec0
17 changed files with 104 additions and 94 deletions

Binary file not shown.

View file

@ -15,20 +15,24 @@ The typed runtime state model is split into player settings, loadout templates,
run state, zone state, entity snapshots, item slots, weapon groups, action-bar
bindings, and stat grids. Player settings include player name, tutorial flag,
story-file hash cursors, gameplay formatting, graphics preferences, input
binding overrides, and action-bar inputs. Do not preserve `SavedGame`,
`PlayerSettings`, or runtime entity blueprints as opaque payloads in the new
store; they are source shapes for projection, not portable state authority.
binding overrides, and action-bar inputs. Do not preserve `SavedGame`, Unity
runtime settings projections, or runtime entity blueprints as opaque payloads in
the new store; they are source shapes for projection, not portable state
authority.
The Unity client no longer writes `PlayerSettings.msgpack`, `.loadout`, or
`.zone` files. `AetheriaPlayerSettings` is the typed Verse replacement for
`PlayerSettings.msgpack`, and `AetheriaLoadoutTemplate` is the typed Verse
replacement for bespoke loadout files, with structured hull/equipment/cargo/
docking item slots, nested child-entity loadouts, and weapon groups. Unity
settings, loadout saves, and run checkpoints now queue typed `.cc.pending`
runtime commit envelopes beside `GameData/aetheria-world.cc`. `Aetheria.State`
owns applying those envelopes into canonical typed state through
`AetheriaRuntimeCommitLogApplier`; the Unity-side command log is command-only
and cannot become durable truth by itself.
docking item slots, nested child-entity loadouts, and weapon groups.
`RuntimePlayerSettings` is the Unity session projection for menus, formatting,
and input binding edits; it queues typed `.cc.pending` player-settings commits
and is not portable state authority. Unity settings, loadout saves, and run
checkpoints now queue typed `.cc.pending` runtime commit envelopes beside
`GameData/aetheria-world.cc`. `Aetheria.State` owns applying those envelopes
into canonical typed state through `AetheriaRuntimeCommitLogApplier`; the
Unity-side command log is command-only and cannot become durable truth by
itself.
Unity Eve surfaces also emit `gamecult.eve.command.v1` envelopes under
`GameData/aetheria-world.cc.eve.pending`. `AetheriaEveCommandBridge` is the
provider-owned acceptance organ for those commands: it validates the provider,

View file

@ -40,22 +40,22 @@ public class ActionGameManager : MonoBehaviour
private static string RuntimeStateFilePath =>
_runtimeStateFilePath ??= AetheriaRuntimeStateBoundary.GetStateFilePath(GameDataDirectory);
private static PlayerSettings _playerSettings;
public static PlayerSettings PlayerSettings
private static RuntimePlayerSettings _runtimePlayerSettings;
public static RuntimePlayerSettings RuntimePlayerSettings
{
get
{
return _playerSettings ??= GetDefaultPlayerSettings();
return _runtimePlayerSettings ??= CreateDefaultRuntimePlayerSettings();
}
}
public static void SavePlayerSettings()
public static void QueueRuntimePlayerSettingsCommit()
{
try
{
var commit = AetheriaRuntimeStateCommitLog.QueuePlayerSettings(
RuntimeStateFilePath,
ProjectPlayerSettings(PlayerSettings));
ProjectRuntimePlayerSettings(RuntimePlayerSettings));
Debug.Log($"Queued Aetheria Verse player settings commit: {commit.Path}");
}
catch (Exception ex)
@ -64,9 +64,9 @@ public class ActionGameManager : MonoBehaviour
}
}
private static PlayerSettings GetDefaultPlayerSettings()
private static RuntimePlayerSettings CreateDefaultRuntimePlayerSettings()
{
var settings = new PlayerSettings();
var settings = new RuntimePlayerSettings();
settings.Name = Environment.UserName;
settings.InputSettings.ActionBarInputs.Add("<Keyboard>/leftShift");
settings.InputSettings.ActionBarInputs.Add("<Mouse>/leftButton");
@ -216,7 +216,7 @@ public class ActionGameManager : MonoBehaviour
get => Settings.GameplaySettings.DefaultEntitySettings.Copy();
}
private static AetheriaRuntimePlayerSettingsCommit ProjectPlayerSettings(PlayerSettings settings)
private static AetheriaRuntimePlayerSettingsCommit ProjectRuntimePlayerSettings(RuntimePlayerSettings settings)
{
return new AetheriaRuntimePlayerSettingsCommit
{
@ -492,7 +492,7 @@ public class ActionGameManager : MonoBehaviour
ZoneRenderer.ItemManager = ItemManager;
// If hiding minimap asteroids, turn them off to start with
if (!PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap)
if (!RuntimePlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap)
ZoneRenderer.ShowAsteroidUI = false;
// TODO: Process Stories
@ -500,7 +500,7 @@ public class ActionGameManager : MonoBehaviour
#region Input Handling
Input = new AetheriaInput();
foreach (var x in PlayerSettings.InputSettings.InputActionMap) Input.asset[x.Key.action].ApplyBindingOverride(x.Key.binding, x.Value);
foreach (var x in RuntimePlayerSettings.InputSettings.InputActionMap) Input.asset[x.Key.action].ApplyBindingOverride(x.Key.binding, x.Value);
InputDisplayLayout.Input = Input.asset;
Input.Global.Enable();
@ -684,7 +684,7 @@ public class ActionGameManager : MonoBehaviour
return slot;
}
var bindings = PlayerSettings.InputSettings.ActionBarInputs.OrderBy(i => i)
var bindings = RuntimePlayerSettings.InputSettings.ActionBarInputs.OrderBy(i => i)
.Select(createBinding).ToList();
#endregion
@ -693,7 +693,7 @@ public class ActionGameManager : MonoBehaviour
StartGame();
//if (!PlayerSettings.InputSettings.ActionBarInputs.Any())
//if (!RuntimePlayerSettings.InputSettings.ActionBarInputs.Any())
{
var newbinds = Enumerable.Range(0, 64)//CurrentEntity.WeaponGroups
.Zip(
@ -1292,7 +1292,7 @@ public class ActionGameManager : MonoBehaviour
MainMenu.gameObject.SetActive(true);
Menu.gameObject.SetActive(false);
CurrentGalaxy = null;
SavePlayerSettings();
QueueRuntimePlayerSettingsCommit();
Observable.EveryUpdate()
.Where(_ => Time.time - deathTime < DeathPostTransitionTime)
.Subscribe(_ =>

View file

@ -105,7 +105,7 @@ public class Galaxy
SectorBackgroundSettings background,
NameGeneratorSettings nameGeneratorSettings,
AetheriaRuntimeCatalogSnapshot runtimeCatalog,
PlayerSettings playerSettings,
RuntimePlayerSettings playerSettings,
DirectoryInfo narrativeDirectory,
Action<string> log,
Action<string> progressCallback = null,

View file

@ -33,11 +33,11 @@ public class StoryProcessor : IZoneResolver, IFactionResolver
public DirectoryInfo NarrativeDirectory { get; }
private Random _random;
public Galaxy Galaxy { get; }
public PlayerSettings Settings { get; }
public RuntimePlayerSettings Settings { get; }
private Action<string> Log { get; }
public StoryProcessor(PlayerSettings settings, DirectoryInfo narrativeDirectory, Galaxy galaxy, ref Random random, Action<string> log)
public StoryProcessor(RuntimePlayerSettings settings, DirectoryInfo narrativeDirectory, Galaxy galaxy, ref Random random, Action<string> log)
{
NarrativeDirectory = narrativeDirectory;
Galaxy = galaxy;

View file

@ -2,14 +2,14 @@ using System;
using System.Collections.Generic;
using System.Globalization;
public class PlayerSettings
public class RuntimePlayerSettings
{
public string Name = "Anonymous";
public bool TutorialPassed;
public Dictionary<string, string> HashedStoryFiles = new Dictionary<string, string>();
public PlayerGameplaySettings GameplaySettings = new PlayerGameplaySettings();
public PlayerInputSettings InputSettings = new PlayerInputSettings();
public PlayerGraphicsSettings GraphicsSettings = new PlayerGraphicsSettings();
public RuntimePlayerGameplaySettings GameplaySettings = new RuntimePlayerGameplaySettings();
public RuntimePlayerInputSettings InputSettings = new RuntimePlayerInputSettings();
public RuntimePlayerGraphicsSettings GraphicsSettings = new RuntimePlayerGraphicsSettings();
public string FormatTemperature(float t)
{
@ -47,19 +47,19 @@ public class PlayerSettings
}
}
public class PlayerGameplaySettings
public class RuntimePlayerGameplaySettings
{
public TemperatureUnit TemperatureUnit = TemperatureUnit.Celsius;
public int SignificantDigits = 3;
}
public class PlayerGraphicsSettings
public class RuntimePlayerGraphicsSettings
{
public Quality NebulaQuality = Quality.Normal;
public bool ShowAsteroidsInMinimap;
}
public class PlayerInputSettings
public class RuntimePlayerInputSettings
{
public Dictionary<(string action, int binding), string> InputActionMap = new Dictionary<(string action, int binding), string>();
public List<string> ActionBarInputs = new List<string>();

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@ -139,30 +139,30 @@ public class SchematicDisplay : MonoBehaviour
OverrideIcon.SetActive(_entity.OverrideShutdown && cos(Time.time * OverrideIconBlinkSpeed) > 0);
ShieldIcon.SetActive(_entity.Shield!=null && _entity.Shield.Item.Active.Value);
if (_radiators.Length == 1)
RadiatorTemperatureLabel.text = $"{((int)(_radiators[0].RadiatorTemperature - 273.15f)).ToString()}°C";
RadiatorTemperatureLabel.text = $"{((int)(_radiators[0].RadiatorTemperature - 273.15f)).ToString()}°C";
else if (_radiators.Length > 1)
RadiatorTemperatureLabel.text =
$"{((int)(_radiators.Min(r => r.RadiatorTemperature) - 273.15f)).ToString()}-" +
$"{((int)(_radiators.Max(r => r.RadiatorTemperature) - 273.15f)).ToString()}°C";
$"{((int)(_radiators.Max(r => r.RadiatorTemperature) - 273.15f)).ToString()}°C";
HeatsinkBackground.color = _entity.HeatsinksEnabled ? HeaderElementEnabledColor : HeaderElementDisabledColor;
if (_heatStorages.Length == 1)
HeatStorageTemperatureLabel.text = $"{((int)(_heatStorages[0].Item.Temperature - 273.15f)).ToString()}°C";
HeatStorageTemperatureLabel.text = $"{((int)(_heatStorages[0].Item.Temperature - 273.15f)).ToString()}°C";
else if (_heatStorages.Length > 1)
HeatStorageTemperatureLabel.text =
$"{((int)(_heatStorages.Min(r => r.Item.Temperature) - 273.15f)).ToString()}-" +
$"{((int)(_heatStorages.Max(r => r.Item.Temperature) - 273.15f)).ToString()}°C";
$"{((int)(_heatStorages.Max(r => r.Item.Temperature) - 273.15f)).ToString()}°C";
if (_cargoBays.Length == 1)
CargoTemperatureLabel.text = $"{((int)(_cargoBays[0].Temperature - 273.15f)).ToString()}°C";
CargoTemperatureLabel.text = $"{((int)(_cargoBays[0].Temperature - 273.15f)).ToString()}°C";
else if (_cargoBays.Length > 1)
CargoTemperatureLabel.text =
$"{((int)(_cargoBays.Min(r => r.Temperature) - 273.15f)).ToString()}-" +
$"{((int)(_cargoBays.Max(r => r.Temperature) - 273.15f)).ToString()}°C";
$"{((int)(_cargoBays.Max(r => r.Temperature) - 273.15f)).ToString()}°C";
if(_cockpit != null)
{
CockpitTemperatureLabel.text = $"{((int) (_cockpit.Item.Temperature - 273.15f)).ToString()}°C";
CockpitTemperatureLabel.text = $"{((int) (_cockpit.Item.Temperature - 273.15f)).ToString()}°C";
HeatstrokeMeterFill.anchorMax = new Vector2(_entity.Heatstroke, 1);
HypothermiaMeterFill.anchorMax = new Vector2(_entity.Hypothermia, 1);
@ -174,7 +174,7 @@ public class SchematicDisplay : MonoBehaviour
if (_capacitors.Length == 0)
{
EnergyFill.anchorMax = Vector2.up;
EnergyLabel.text = ActionGameManager.PlayerSettings.Format(_reactor.Draw);
EnergyLabel.text = ActionGameManager.RuntimePlayerSettings.Format(_reactor.Draw);
}
else
{
@ -186,13 +186,13 @@ public class SchematicDisplay : MonoBehaviour
if (_aetherDrive != null)
{
ForwardRPMLabel.text = ActionGameManager.PlayerSettings.Format(_aetherDrive.Rpm.x);
ForwardRPMLabel.text = ActionGameManager.RuntimePlayerSettings.Format(_aetherDrive.Rpm.x);
ForwardRPMFill.anchorMax = new Vector2(_aetherDrive.Rpm.x / _aetherDrive.MaximumRpm, 1);
StrafeRPMLabel.text = ActionGameManager.PlayerSettings.Format(_aetherDrive.Rpm.y);
StrafeRPMLabel.text = ActionGameManager.RuntimePlayerSettings.Format(_aetherDrive.Rpm.y);
StrafeRPMFill.anchorMax = new Vector2(_aetherDrive.Rpm.y / _aetherDrive.MaximumRpm, 1);
TurnRPMLabel.text = ActionGameManager.PlayerSettings.Format(_aetherDrive.Rpm.z);
TurnRPMLabel.text = ActionGameManager.RuntimePlayerSettings.Format(_aetherDrive.Rpm.z);
TurnRPMFill.anchorMax = new Vector2(_aetherDrive.Rpm.z / _aetherDrive.MaximumRpm, 1);
}
}
@ -210,7 +210,7 @@ public class SchematicDisplay : MonoBehaviour
var hullData = _entity.ItemManager.GetData(_hull);
var dur = _hull.Durability / hullData.Durability;
HullDurabilityFill.anchorMax = new Vector2(dur, 1);
HullDurabilityLabel.text = $"{ActionGameManager.PlayerSettings.Format(dur * 100)}%";
HullDurabilityLabel.text = $"{ActionGameManager.RuntimePlayerSettings.Format(dur * 100)}%";
}
foreach (var x in _schematicItems)

View file

@ -111,7 +111,7 @@ public class InputDisplayLayout : MonoBehaviour
buttonMapping.TestAction.Enable();
}
foreach(var actionBarInput in ActionGameManager.PlayerSettings.InputSettings.ActionBarInputs)
foreach(var actionBarInput in ActionGameManager.RuntimePlayerSettings.InputSettings.ActionBarInputs)
{
if (!_bindButtons.ContainsKey(actionBarInput)) Debug.LogError($"Unable to find input button for \"{actionBarInput}\"");
else
@ -527,7 +527,7 @@ public class InputDisplayLayout : MonoBehaviour
{
_dragAction.Binding.overridePath = _previewButton.Button.InputSystemPath;
_dragAction.Action.ApplyBindingOverride(_dragAction.Binding);
ActionGameManager.PlayerSettings.InputSettings.InputActionMap[(_dragAction.Action.name,
ActionGameManager.RuntimePlayerSettings.InputSettings.InputActionMap[(_dragAction.Action.name,
_dragAction.Action.GetBindingIndex(_dragAction.Binding))] = _previewButton.Button.InputSystemPath;
// TODO: Assign New Binding
}
@ -550,13 +550,13 @@ public class InputDisplayLayout : MonoBehaviour
buttonMapping.IsActionBarButton = !buttonMapping.IsActionBarButton;
if (buttonMapping.IsActionBarButton)
{
ActionGameManager.PlayerSettings.InputSettings.ActionBarInputs.Add(buttonMapping.Button.InputSystemPath);
ActionGameManager.RuntimePlayerSettings.InputSettings.ActionBarInputs.Add(buttonMapping.Button.InputSystemPath);
foreach(var overlap in OverlappingLabels(buttonMapping.ButtonRect))
PlaceLabel(overlap);
}
else
{
ActionGameManager.PlayerSettings.InputSettings.ActionBarInputs.Remove(buttonMapping.Button.InputSystemPath);
ActionGameManager.RuntimePlayerSettings.InputSettings.ActionBarInputs.Remove(buttonMapping.Button.InputSystemPath);
}
AssignColor(buttonMapping);
});

View file

@ -107,7 +107,7 @@ public class MainMenu : MonoBehaviour
Dialog.AddProperty(() => generatorState);
Dialog.Show();
if (ActionGameManager.PlayerSettings.TutorialPassed)
if (ActionGameManager.RuntimePlayerSettings.TutorialPassed)
{
Settings.SectorBackgroundSettings.NoisePosition = Random.value * 1000;
ActionGameManager.IsTutorial = false;
@ -144,7 +144,7 @@ public class MainMenu : MonoBehaviour
Settings.TutorialBackgroundSettings,
Settings.NameGeneratorSettings,
ActionGameManager.RuntimeCatalog,
ActionGameManager.PlayerSettings,
ActionGameManager.RuntimePlayerSettings,
ActionGameManager.GameDataDirectory.CreateSubdirectory("Narrative"),
Debug.Log,
setState);
@ -206,19 +206,19 @@ public class MainMenu : MonoBehaviour
_nextMenu.panel.Clear();
_nextMenu.panel.Title.text = TitleSubtitle("gameplay", "settings");
_nextMenu.panel.AddField("Name",
() => ActionGameManager.PlayerSettings.Name,
s => ActionGameManager.PlayerSettings.Name = s);
() => ActionGameManager.RuntimePlayerSettings.Name,
s => ActionGameManager.RuntimePlayerSettings.Name = s);
_nextMenu.panel.AddField("Temperature Unit",
() => (int) ActionGameManager.PlayerSettings.GameplaySettings.TemperatureUnit,
i => ActionGameManager.PlayerSettings.GameplaySettings.TemperatureUnit = (TemperatureUnit) i,
() => (int) ActionGameManager.RuntimePlayerSettings.GameplaySettings.TemperatureUnit,
i => ActionGameManager.RuntimePlayerSettings.GameplaySettings.TemperatureUnit = (TemperatureUnit) i,
Enum.GetNames(typeof(TemperatureUnit)));
_nextMenu.panel.AddField("Significant Digits",
() => ActionGameManager.PlayerSettings.GameplaySettings.SignificantDigits,
i => ActionGameManager.PlayerSettings.GameplaySettings.SignificantDigits = i);
() => ActionGameManager.RuntimePlayerSettings.GameplaySettings.SignificantDigits,
i => ActionGameManager.RuntimePlayerSettings.GameplaySettings.SignificantDigits = i);
_nextMenu.panel.AddButton("Back",
() =>
{
ActionGameManager.SavePlayerSettings();
ActionGameManager.QueueRuntimePlayerSettingsCommit();
ShowSettings();
Fade(false);
});
@ -229,16 +229,16 @@ public class MainMenu : MonoBehaviour
_nextMenu.panel.Clear();
_nextMenu.panel.Title.text = TitleSubtitle("graphics", "settings");
_nextMenu.panel.AddField("Nebula Quality",
() => (int)ActionGameManager.PlayerSettings.GraphicsSettings.NebulaQuality,
() => (int)ActionGameManager.RuntimePlayerSettings.GraphicsSettings.NebulaQuality,
i =>
{
ActionGameManager.PlayerSettings.GraphicsSettings.NebulaQuality = (Quality)i;
CloudRenderer.quality = ActionGameManager.PlayerSettings.GraphicsSettings.NebulaQuality;
ActionGameManager.RuntimePlayerSettings.GraphicsSettings.NebulaQuality = (Quality)i;
CloudRenderer.quality = ActionGameManager.RuntimePlayerSettings.GraphicsSettings.NebulaQuality;
},
Enum.GetNames(typeof(Quality)));
_nextMenu.panel.AddField("Show Asteroids in Minimap",
() => ActionGameManager.PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap,
b => ActionGameManager.PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap = b);
() => ActionGameManager.RuntimePlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap,
b => ActionGameManager.RuntimePlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap = b);
_nextMenu.panel.AddButton("Back",
() =>
{

View file

@ -207,8 +207,8 @@ public class InventoryPanel : MonoBehaviour, IPointerClickHandler
var opacity = smoothstep(0, MinTempRange, tempRange);
if(MinTempLabel)
{
MinTempLabel.text = ActionGameManager.PlayerSettings.FormatTemperature(_displayedEntity.MinTemp);
MaxTempLabel.text = ActionGameManager.PlayerSettings.FormatTemperature(_displayedEntity.MaxTemp);
MinTempLabel.text = ActionGameManager.RuntimePlayerSettings.FormatTemperature(_displayedEntity.MinTemp);
MaxTempLabel.text = ActionGameManager.RuntimePlayerSettings.FormatTemperature(_displayedEntity.MaxTemp);
}
var hullData = GameManager.ItemManager.GetData(_displayedEntity.Hull) as HullData;
for(var x = 0; x < _temperatureTexture.width; x++)

View file

@ -1,4 +1,4 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* 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/. */
@ -52,7 +52,7 @@ public class MapRenderer : MonoBehaviour
Title.text = $"Zone: {GameManager.Zone.GalaxyZone.Name}";
// If hiding minimap asteroids, turn them back on for the map screen
if (!ActionGameManager.PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap)
if (!ActionGameManager.RuntimePlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap)
ZoneRenderer.ShowAsteroidUI = true;
}
@ -68,7 +68,7 @@ public class MapRenderer : MonoBehaviour
InfluenceCamera.gameObject.SetActive(false);
// If hiding minimap asteroids, turn them back off when leaving the map screen
if (!ActionGameManager.PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap)
if (!ActionGameManager.RuntimePlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap)
ZoneRenderer.ShowAsteroidUI = false;
}

View file

@ -69,8 +69,8 @@ public class SectorRenderer : MonoBehaviour, IBeginDragHandler, IDragHandler, IS
var density = saturate(ActionGameManager.CurrentGalaxy.Background.CloudDensity(zone.Position)/2);
var radius = GameManager.Settings.ZoneSettings.ZoneRadius.Evaluate(density);
var mass = GameManager.Settings.ZoneSettings.ZoneMass.Evaluate(density);
Properties.AddProperty("Mass", () => ActionGameManager.PlayerSettings.Format(mass));
Properties.AddProperty("Radius", () => ActionGameManager.PlayerSettings.Format(radius));
Properties.AddProperty("Mass", () => ActionGameManager.RuntimePlayerSettings.Format(mass));
Properties.AddProperty("Radius", () => ActionGameManager.RuntimePlayerSettings.Format(radius));
if (zone.RuntimeBlueprint == null)
{
Properties.AddProperty(() => "Has not been visited");

View file

@ -212,7 +212,7 @@ public class TradeMenu : MonoBehaviour
return 0;
}));
columns.Add(("Mass", 1,
x => () => ActionGameManager.PlayerSettings.Format(x.data.Mass),
x => () => ActionGameManager.RuntimePlayerSettings.Format(x.data.Mass),
data => data.Mass));
columns.Add(("Price", 1,
x => () => (x.item is CraftedItemInstance craftedItemInstance ? GameManager.ItemManager.GetPrice(craftedItemInstance) : x.data.Price).ToString("N0"),
@ -254,7 +254,7 @@ public class TradeMenu : MonoBehaviour
columns.Add((field.Name, 1, x =>
{
var behavior = ((EquippableItemData) x.data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
return () => ActionGameManager.PlayerSettings.Format((float) field.GetValue(behavior));
return () => ActionGameManager.RuntimePlayerSettings.Format((float) field.GetValue(behavior));
}, data =>
{
var behavior = ((EquippableItemData) data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
@ -275,7 +275,7 @@ public class TradeMenu : MonoBehaviour
columns.Add((field.Name, 1, x =>
{
var behavior = ((EquippableItemData) x.data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));
return () => ActionGameManager.PlayerSettings.Format(((PerformanceStat) field.GetValue(behavior)).Max);
return () => ActionGameManager.RuntimePlayerSettings.Format(((PerformanceStat) field.GetValue(behavior)).Max);
}, data =>
{
var behavior = ((EquippableItemData) data).Behaviors.FirstOrDefault(b => type.IsInstanceOfType(b));

View file

@ -1,4 +1,4 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* 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/. */
@ -392,7 +392,7 @@ public class PropertiesPanel : MonoBehaviour
var sheet = AddStatSheet();
var manufacturer = ActionGameManager.RuntimeCatalog?.FindCorporationByLegacyId(data.Manufacturer.ToString());
sheet.AddStat("Manufacturer", () => manufacturer?.Name ?? "GameCult");
sheet.AddStat("Mass", () => ActionGameManager.PlayerSettings.Format(GameManager.ItemManager.GetMass(item)));
sheet.AddStat("Mass", () => ActionGameManager.RuntimePlayerSettings.Format(GameManager.ItemManager.GetMass(item)));
//AddProperty("Thermal Mass", () => Context.GetThermalMass(item).SignificantDigits(Context.GameplaySettings.SignificantDigits));
}
@ -411,7 +411,7 @@ public class PropertiesPanel : MonoBehaviour
{
if (behavior is StatModifierData statMod)
{
sheet.AddStat($"{statMod.Stat.Target.SplitCamelCase()}:{statMod.Stat.Stat.SplitCamelCase()}", () => $"{(statMod.Type == StatModifierType.Constant ? "+" : "x")}{ActionGameManager.PlayerSettings.Format(statValueFunction(statMod.Modifier))}");
sheet.AddStat($"{statMod.Stat.Target.SplitCamelCase()}:{statMod.Stat.Stat.SplitCamelCase()}", () => $"{(statMod.Type == StatModifierType.Constant ? "+" : "x")}{ActionGameManager.RuntimePlayerSettings.Format(statValueFunction(statMod.Modifier))}");
}
else
{
@ -421,13 +421,13 @@ public class PropertiesPanel : MonoBehaviour
{
var fieldType = field.FieldType;
if (fieldType == typeof(float))
sheet.AddStat(field.Name.SplitCamelCase(), () => $"{ActionGameManager.PlayerSettings.Format((float) field.GetValue(behavior))}");
sheet.AddStat(field.Name.SplitCamelCase(), () => $"{ActionGameManager.RuntimePlayerSettings.Format((float) field.GetValue(behavior))}");
else if (fieldType == typeof(int))
sheet.AddStat(field.Name.SplitCamelCase(), () => $"{(int) field.GetValue(behavior)}");
else if (fieldType == typeof(PerformanceStat))
{
var stat = (PerformanceStat) field.GetValue(behavior);
sheet.AddStat(field.Name.SplitCamelCase(), () => $"{ActionGameManager.PlayerSettings.Format(statValueFunction(stat))}");
sheet.AddStat(field.Name.SplitCamelCase(), () => $"{ActionGameManager.RuntimePlayerSettings.Format(statValueFunction(stat))}");
}
}
}
@ -436,7 +436,7 @@ public class PropertiesPanel : MonoBehaviour
if (gearData.Behaviors.FirstOrDefault(b => b is WeaponData) is WeaponData weapon)
{
var range = AddCurveField();
range.Show("Damage Range", weapon.DamageCurve, t => ActionGameManager.PlayerSettings.Format(lerp(statValueFunction(weapon.MinRange), statValueFunction(weapon.Range), t)));
range.Show("Damage Range", weapon.DamageCurve, t => ActionGameManager.RuntimePlayerSettings.Format(lerp(statValueFunction(weapon.MinRange), statValueFunction(weapon.Range), t)));
}
}
@ -490,13 +490,13 @@ public class PropertiesPanel : MonoBehaviour
if (item.EquippableItem.Durability < .01f)
statusSheet.AddStat("Durability", () => "Item Destroyed!");
else statusSheet.AddStat("Durability", () => $"{(int)(item.EquippableItem.Durability / gearData.Durability * 100)}%");
statusSheet.AddStat("Temperature", () => ActionGameManager.PlayerSettings.FormatTemperature(item.Temperature));
statusSheet.AddStat("Temperature", () => ActionGameManager.RuntimePlayerSettings.FormatTemperature(item.Temperature));
var heatCurve = AddCurveField();
heatCurve.Show(
"Thermal Performance",
gearData.HeatPerformanceCurve,
t => ActionGameManager.PlayerSettings.FormatTemperature(lerp(gearData.MinimumTemperature, gearData.MaximumTemperature, t)),
t => ActionGameManager.RuntimePlayerSettings.FormatTemperature(lerp(gearData.MinimumTemperature, gearData.MaximumTemperature, t)),
true);
RefreshPropertyValues += () => heatCurve.SetCurrent(unlerp(gearData.MinimumTemperature, gearData.MaximumTemperature, item.Temperature));
AddEquippableItemProperties(item.EquippableItem, item.Evaluate);
@ -536,7 +536,7 @@ public class PropertiesPanel : MonoBehaviour
heatCurve.Show(
"Thermal Performance",
gearData.HeatPerformanceCurve,
t => ActionGameManager.PlayerSettings.FormatTemperature(lerp(gearData.MinimumTemperature, gearData.MaximumTemperature, t)),
t => ActionGameManager.RuntimePlayerSettings.FormatTemperature(lerp(gearData.MinimumTemperature, gearData.MaximumTemperature, t)),
true);
AddEquippableItemProperties(gear, stat => GameManager.ItemManager.Evaluate(stat, gear));
}
@ -550,16 +550,16 @@ public class PropertiesPanel : MonoBehaviour
AddProperty(data.Description).Label.fontStyle = FontStyles.Normal;
if (data is EquippableItemData gearData)
{
AddProperty("Durability", () => ActionGameManager.PlayerSettings.Format(gearData.Durability));
AddProperty("Durability", () => ActionGameManager.RuntimePlayerSettings.Format(gearData.Durability));
var sheet = AddStatSheet();
foreach (var behavior in gearData.Behaviors)
{
if (behavior is StatModifierData statMod)
{
if(Math.Abs(statMod.Modifier.Min - statMod.Modifier.Max) < .001f)
sheet.AddStat($"{statMod.Stat.Target}:{statMod.Stat.Stat}", () => $"{(statMod.Type == StatModifierType.Constant ? "+" : "x")}{ActionGameManager.PlayerSettings.Format(statMod.Modifier.Min)}");
sheet.AddStat($"{statMod.Stat.Target}:{statMod.Stat.Stat}", () => $"{(statMod.Type == StatModifierType.Constant ? "+" : "x")}{ActionGameManager.RuntimePlayerSettings.Format(statMod.Modifier.Min)}");
else
sheet.AddStat($"{statMod.Stat.Target}:{statMod.Stat.Stat}", () => $"{(statMod.Type == StatModifierType.Constant ? "+" : "x")}{ActionGameManager.PlayerSettings.Format(statMod.Modifier.Min)}-{ActionGameManager.PlayerSettings.Format(statMod.Modifier.Max)}");
sheet.AddStat($"{statMod.Stat.Target}:{statMod.Stat.Stat}", () => $"{(statMod.Type == StatModifierType.Constant ? "+" : "x")}{ActionGameManager.RuntimePlayerSettings.Format(statMod.Modifier.Min)}-{ActionGameManager.RuntimePlayerSettings.Format(statMod.Modifier.Max)}");
}
var type = behavior.GetType();
if (type.GetCustomAttribute(typeof(RuntimeInspectable)) != null)
@ -568,16 +568,16 @@ public class PropertiesPanel : MonoBehaviour
{
var fieldType = field.FieldType;
if (fieldType == typeof(float))
sheet.AddStat(field.Name, () => $"{ActionGameManager.PlayerSettings.Format((float) field.GetValue(behavior))}");
sheet.AddStat(field.Name, () => $"{ActionGameManager.RuntimePlayerSettings.Format((float) field.GetValue(behavior))}");
else if (fieldType == typeof(int))
sheet.AddStat(field.Name, () => $"{(int) field.GetValue(behavior)}");
else if (fieldType == typeof(PerformanceStat))
{
var stat = (PerformanceStat) field.GetValue(behavior);
if(Math.Abs(stat.Min - stat.Max) < .001f)
sheet.AddStat(field.Name, () => $"{ActionGameManager.PlayerSettings.Format(stat.Min)}");
sheet.AddStat(field.Name, () => $"{ActionGameManager.RuntimePlayerSettings.Format(stat.Min)}");
else
sheet.AddStat(field.Name, () => $"{ActionGameManager.PlayerSettings.Format(stat.Min)}-{ActionGameManager.PlayerSettings.Format(stat.Max)}");
sheet.AddStat(field.Name, () => $"{ActionGameManager.RuntimePlayerSettings.Format(stat.Min)}-{ActionGameManager.RuntimePlayerSettings.Format(stat.Max)}");
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
@ -78,7 +78,7 @@ public class VolumeCloudRenderer : EffectBase
private void Start() {
this.EnsureMaterial(true);
if (Application.isPlaying)
quality = ActionGameManager.PlayerSettings.GraphicsSettings.NebulaQuality;
quality = ActionGameManager.RuntimePlayerSettings.GraphicsSettings.NebulaQuality;
}
[ImageEffectOpaque]

View file

@ -40,8 +40,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
`AetheriaStateNode`. Local run saves, loadouts, player settings files, zone
files, and generated keyboard layout caches no longer write bespoke durable files. The
legacy
`PlayerSettings` runtime object is no longer decorated as a MessagePack
persistence shape. `Economy.Server` now drains `aetheria-world.cc.pending`
`RuntimePlayerSettings` runtime object is no longer named or decorated as a
MessagePack persistence shape. `Economy.Server` now drains `aetheria-world.cc.pending`
into canonical typed state and drains `aetheria-world.cc.eve.pending` through
the provider-owned Eve command bridge on startup and on a daemon polling loop
while hosting the CultMesh state node. `Aetheria.State.ApplyPending` remains a
@ -68,8 +68,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
pointer into the typed Verse replacement for `PlayerSettings.msgpack`: player
name, tutorial flag, story-file hash cursors, gameplay formatting, graphics
preferences, input binding overrides, and action-bar inputs. Unity's menu and
input screens still mutate the old `PlayerSettings` runtime object in memory
until the runtime Verse package is wired.
input screens mutate `RuntimePlayerSettings` in memory and queue typed Verse
commits; the in-memory projection is not portable state authority.
- `Aetheria.State` now exposes typed node put/get ports for run state, zone
state, and entity snapshots. The state smoke writes a run referencing a zone,
a zone referencing an entity snapshot, and an entity snapshot carrying
@ -636,6 +636,10 @@ First Aetheria surfaces to publish:
`RuntimeZoneBlueprint`/`RuntimeEntityBlueprint`, and rename loadout
collections away from save-payload vocabulary. These are now explicitly
runtime construction projections, not portable state authority.
- Done: demote Unity's live `PlayerSettings` runtime object to
`RuntimePlayerSettings`; `AetheriaPlayerSettings` remains the typed Verse
state document owner, while Unity only keeps a session projection and
queues typed player-settings commits.
- Remaining: delete or quarantine old cache abstractions that no longer
protect an invariant once catalog migration has a typed reader.
@ -682,6 +686,8 @@ First Aetheria surfaces to publish:
live Unity source has no `EntityPack`, `ShipPack`, `OrbitalEntityPack`,
`ZonePack`, `PackedContents`, `PackZone`, `EntitySerializer.Pack`, or
`EntitySerializer.Unpack` hits.
- Unity runtime settings projection is now `RuntimePlayerSettings`; live Unity
source has no standalone `PlayerSettings` class/property/method symbols.
- `Aetheria.State.Smoke` proves the provider-owned Eve command bridge drains
`gamecult.eve.command.v1` envelopes, accepts advertised refresh commands,
rejects unknown commands, persists `AetheriaEveCommandDrainStatus`, and exposes