Restore Continue session facts from typed state

This commit is contained in:
Meta Vens 2026-06-16 07:01:50 +01:00
commit 2a047cba28
6 changed files with 86 additions and 12 deletions

Binary file not shown.

View file

@ -846,6 +846,9 @@ static void RequireMainMenuContinueRunState(string root)
"entity.RecordKey",
"CreateEntityConstructionBlueprint(entitySnapshot, true)",
"BindToEntity(entity)",
"RestoreActiveConsumablesFromTypedEntitySnapshot(entity, entitySnapshot)",
"RestoreThermalExposure((float)entitySnapshot.Heatstroke, (float)entitySnapshot.Hypothermia)",
"entity.HeatsinksEnabled = entitySnapshot.HeatsinksEnabled",
"ContinueRunState = null",
"RestoreDroppedPickupsFromTypedZoneState"
};
@ -879,6 +882,27 @@ static void RequireMainMenuContinueRunState(string root)
"Unity package entity readback no longer preserves record identity for Continue: " +
string.Join(", ", missingPackageSymbols));
}
var entitySourcePath = Path.Combine(root, "Assets", "Scripts", "ServerShared", "Entity.cs");
var entitySource = File.Exists(entitySourcePath)
? File.ReadAllText(entitySourcePath)
: throw new InvalidOperationException("Cannot verify Continue entity restore ownership; Entity.cs is missing.");
var requiredEntityRestoreSymbols = new[]
{
"RestoreThermalExposure",
"RestoreActiveConsumable",
"new ConsumableItemEffect(item, this, remainingDuration, duration)"
};
var missingEntityRestoreSymbols = requiredEntityRestoreSymbols
.Where(symbol => !entitySource.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingEntityRestoreSymbols.Length > 0)
{
throw new InvalidOperationException(
"Entity no longer exposes narrow runtime-owned restore primitives for typed Continue state: " +
string.Join(", ", missingEntityRestoreSymbols));
}
}
static void RequirePropertiesPanelReadOnlyInspector(string root)

View file

@ -176,9 +176,11 @@ sessions publish typed state-host liveness. Zone checkpoints persist generated
orbit/body rows into `AetheriaZoneState`, so `ZoneConstructionBlueprint` is a
one-shot construction input rather than the retained surface carrying celestial graph facts. Entity checkpoints
persist hull simulation grids into `AetheriaEntitySnapshot`, so
`RuntimeEntityBlueprint` is no longer the only surface carrying those live
values. Broader runtime object graphs and behavior-private simulation state
remain legacy until dedicated typed runtime documents exist. Live behavior
`EntityConstructionBlueprint` is no longer the only surface carrying those live
values. Continue restore lowers the current player entity from the exact typed
entity snapshot record, including position, velocity, shutdown/heatsink state,
thermal exposure, and active consumable timers. Broader runtime object graphs
and behavior-private simulation state remain legacy until dedicated typed runtime documents exist. Live behavior
instances expose typed behavior kind and group through `Behavior.Kind` and
`Behavior.Group`; behavior construction now reads typed payload fields through
`RuntimeBehaviorDefinition` instead of projecting through config DTOs. Stat

View file

@ -2543,9 +2543,36 @@ public class ActionGameManager : MonoBehaviour
entity.Zone = Zone;
Zone.Entities.Add(entity);
entity.Activate();
entity.HeatsinksEnabled = entitySnapshot.HeatsinksEnabled;
entity.RestoreThermalExposure((float)entitySnapshot.Heatstroke, (float)entitySnapshot.Hypothermia);
RestoreActiveConsumablesFromTypedEntitySnapshot(entity, entitySnapshot);
BindToEntity(entity);
}
private void RestoreActiveConsumablesFromTypedEntitySnapshot(Entity entity, AetheriaRuntimeEntitySnapshot snapshot)
{
foreach (var activeConsumable in snapshot.ActiveConsumables)
{
var item = CreateLoadoutItem(new AetheriaRuntimeLoadoutItemSnapshot(
activeConsumable.ItemKey,
activeConsumable.Quality,
1,
1,
true,
false)) as ConsumableItem;
if (item == null)
{
Debug.LogWarning($"Typed active consumable {activeConsumable.ItemKey} could not be lowered for restored entity {snapshot.RecordKey}.");
continue;
}
entity.RestoreActiveConsumable(
item,
(float)activeConsumable.RemainingDuration,
(float)activeConsumable.Duration);
}
}
private static GalaxyZone ResolveStartZone(AetheriaRuntimeRunStateSnapshot run)
{
if (CurrentGalaxy?.Zones == null || CurrentGalaxy.Zones.Length == 0)

View file

@ -315,6 +315,20 @@ public abstract class Entity
_activeConsumables.Add(new ConsumableItemEffect(item, this));
}
public void RestoreThermalExposure(float heatstroke, float hypothermia)
{
Heatstroke = saturate(heatstroke);
Hypothermia = saturate(hypothermia);
}
public void RestoreActiveConsumable(ConsumableItem item, float remainingDuration, float duration)
{
if (item == null)
return;
_activeConsumables.Add(new ConsumableItemEffect(item, this, remainingDuration, duration));
}
public ConsumableItemEffect FindActiveConsumable(string itemKey)
{
return _activeConsumables.FirstOrDefault(ac => ac.Item?.ItemKey == itemKey);
@ -1182,13 +1196,20 @@ public class ConsumableItemEffect
private readonly BezierCurve _effectiveness;
public ConsumableItemEffect(ConsumableItem item, Entity entity)
: this(item, entity, null, null)
{
}
public ConsumableItemEffect(ConsumableItem item, Entity entity, float? remainingDuration, float? duration)
{
Item = item;
Entity = entity;
RuntimeItem = entity.ItemManager.GetRuntimeItem(item);
_duration = RuntimeItem?.Duration > 0 ? (float)RuntimeItem.Duration : 0;
_duration = duration.GetValueOrDefault(RuntimeItem?.Duration > 0 ? (float)RuntimeItem.Duration : 0);
_effectiveness = CreateEffectivenessCurve(RuntimeItem);
RemainingDuration = _duration;
RemainingDuration = remainingDuration.HasValue
? clamp(remainingDuration.Value, 0, Duration)
: _duration;
Behaviors = entity.ItemManager.CreateRuntimeBehaviors(this);
}

View file

@ -974,16 +974,16 @@ First Aetheria surfaces to publish:
`RunId + ZoneIndex + CurrentZoneEntityIndex` entity record, lowers it
through the existing construction blueprint path, restores hull,
equipment, cargo, docking contents, weapon groups, position, direction,
velocity, shutdown override, and tractor power, then binds the lowered
entity as the current player ship.
velocity, shutdown override, heatsink toggle, tractor power,
heatstroke/hypothermia exposure, and active consumable item/timer rows,
then binds the lowered entity as the current player ship.
- Remaining: add typed documents/mappers for runtime object graphs,
complete full Continue/run entity graph reconstruction from typed state
for non-current entities, child/docked entity activation, targets,
contacts, active consumables, behavior-private state not covered by
progress, weapon, sensor, radiator, reactor, or capacitor rows,
heatstroke/hypothermia runtime restore, typed behavior factory
construction, and any catalog fields not covered by the stable
scalar/fingerprint/payload pass.
contacts, restored active-consumable behavior runtime internals,
behavior-private state not covered by progress, weapon, sensor, radiator,
reactor, or capacitor rows, typed behavior factory construction, and any
catalog fields not covered by the stable scalar/fingerprint/payload pass.
4. Runtime cutover
- Done: add a Unity-facing typed catalog read facade and smoke proving it can