Persist entity simulation grids in checkpoints
This commit is contained in:
parent
dd21e287f4
commit
f276f9bcb3
7 changed files with 140 additions and 14 deletions
Binary file not shown.
|
|
@ -273,7 +273,24 @@ try
|
|||
}
|
||||
}
|
||||
},
|
||||
WeaponGroups = new[] { new[] { 0 } }
|
||||
WeaponGroups = new[] { new[] { 0 } },
|
||||
StatGrids = new[]
|
||||
{
|
||||
new AetheriaRuntimeEntityStatGridCommit
|
||||
{
|
||||
Name = "temperature",
|
||||
Width = 2,
|
||||
Height = 1,
|
||||
Values = new[] { 280.0, 281.0 }
|
||||
},
|
||||
new AetheriaRuntimeEntityStatGridCommit
|
||||
{
|
||||
Name = "hull_conductivity_x",
|
||||
Width = 2,
|
||||
Height = 1,
|
||||
Values = new[] { 1.0, 0.0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -325,6 +342,9 @@ try
|
|||
zone.Bodies[0].Asteroids.Length == 1 &&
|
||||
entity?.Equipment.Length == 1 &&
|
||||
entity.WeaponGroups.Length == 1 &&
|
||||
entity.StatGrids.Length == 2 &&
|
||||
entity.StatGrids.Any(grid => grid.Name == "temperature" && grid.Values.Length == 2 && grid.Values[1] == 281.0) &&
|
||||
entity.StatGrids.Any(grid => grid.Name == "hull_conductivity_x" && grid.Values.Length == 2 && grid.Values[0] == 1.0) &&
|
||||
AetheriaRuntimeStateCommitLog.ReadPending(commitSmokeStatePath).Count == 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -424,10 +424,25 @@ public static class AetheriaRuntimeCommitLogApplier
|
|||
.ToArray(),
|
||||
WeaponGroups = ToIntArrayArray(entity.WeaponGroups)
|
||||
.Select(group => new AetheriaWeaponGroupSnapshot { EquipmentIndices = group })
|
||||
.ToArray()
|
||||
.ToArray(),
|
||||
StatGrids = ToEntityStatGrids(entity.StatGrids)
|
||||
};
|
||||
}
|
||||
|
||||
private static AetheriaEntityStatGrid[] ToEntityStatGrids(
|
||||
IReadOnlyList<AetheriaRuntimeEntityStatGridCommit>? grids)
|
||||
{
|
||||
return (grids ?? Array.Empty<AetheriaRuntimeEntityStatGridCommit>())
|
||||
.Select(grid => new AetheriaEntityStatGrid
|
||||
{
|
||||
Name = grid.Name ?? "",
|
||||
Width = grid.Width,
|
||||
Height = grid.Height,
|
||||
Values = (grid.Values ?? Array.Empty<double>()).ToArray()
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static int[] ToIntArray(IReadOnlyList<int>? values)
|
||||
{
|
||||
return (values ?? Array.Empty<int>()).ToArray();
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ typed corporation references plus relationship tokens and numeric standings.
|
|||
Zone checkpoints include typed orbit and body rows for generated celestial
|
||||
state: orbit IDs, parent IDs, distance, phase, fixed positions, body kind,
|
||||
resources, gravity/body multipliers, asteroid entries, and gas/sun visual
|
||||
parameters.
|
||||
parameters. Entity checkpoints include typed simulation stat grids for
|
||||
temperature, thermal mass, armor, max armor, and hull-conductivity axes.
|
||||
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`, Unity
|
||||
|
|
@ -120,9 +121,12 @@ needs actual allegiance weights, not only display counts. Runtime checkpoints
|
|||
now persist session faction relationships into typed run state, and runtime
|
||||
sessions publish typed state-host liveness. Zone checkpoints persist generated
|
||||
orbit/body rows into `AetheriaZoneState`, so `RuntimeZoneBlueprint` is no
|
||||
longer the only surface carrying celestial graph facts. Broader runtime object
|
||||
graphs, typed behavior factory construction, and simulation state remain legacy
|
||||
until dedicated typed runtime documents exist.
|
||||
longer the only 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, typed behavior factory construction, and
|
||||
behavior-private simulation state remain legacy until dedicated typed runtime
|
||||
documents exist.
|
||||
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
|
||||
name array needed to move `Galaxy`/Markov name generation off legacy
|
||||
|
|
@ -170,8 +174,8 @@ an entity snapshot. It also writes and reopens `AetheriaRuntimeSession` and
|
|||
checks that the Eve provider advertises the runtime-session schema. The run
|
||||
smoke proves a typed run can reference a typed zone, the zone can preserve
|
||||
orbit/body rows and reference typed entity snapshots, and entity snapshots can
|
||||
preserve equipment slots, weapon groups, and stat grids without reviving
|
||||
`PlayerSettings.msgpack`, `.loadout`, or `.zone` serialization.
|
||||
preserve equipment slots, weapon groups, and simulation stat grids without
|
||||
reviving `PlayerSettings.msgpack`, `.loadout`, or `.zone` serialization.
|
||||
|
||||
`Aetheria.State.Verify` opens a materialized state file and checks that the
|
||||
typed migration ledger matches the actual item, corporation, and name-file
|
||||
|
|
|
|||
|
|
@ -655,7 +655,67 @@ public class ActionGameManager : MonoBehaviour
|
|||
.ToArray() ?? Array.Empty<int>(),
|
||||
WeaponGroups = entity.WeaponGroups?
|
||||
.Select(group => (IReadOnlyList<int>)group.items.Select(item => entity.Equipment.IndexOf(item)).Where(index => index >= 0).ToArray())
|
||||
.ToArray() ?? Array.Empty<IReadOnlyList<int>>()
|
||||
.ToArray() ?? Array.Empty<IReadOnlyList<int>>(),
|
||||
StatGrids = ProjectEntityStatGrids(entity)
|
||||
};
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEntityStatGridCommit[] ProjectEntityStatGrids(Entity entity)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
ProjectFloatGrid("temperature", entity.Temperature),
|
||||
ProjectFloatGrid("thermal_mass", entity.ThermalMass),
|
||||
ProjectFloatGrid("armor", entity.Armor),
|
||||
ProjectFloatGrid("max_armor", entity.MaxArmor),
|
||||
ProjectBool2Grid("hull_conductivity_x", entity.HullConductivity, axis: 0),
|
||||
ProjectBool2Grid("hull_conductivity_y", entity.HullConductivity, axis: 1)
|
||||
}
|
||||
.Where(grid => grid != null)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEntityStatGridCommit ProjectFloatGrid(string name, float[,] values)
|
||||
{
|
||||
if (values == null)
|
||||
return null;
|
||||
|
||||
var width = values.GetLength(0);
|
||||
var height = values.GetLength(1);
|
||||
var flattened = new double[width * height];
|
||||
var index = 0;
|
||||
for (var y = 0; y < height; y++)
|
||||
for (var x = 0; x < width; x++)
|
||||
flattened[index++] = values[x, y];
|
||||
|
||||
return new AetheriaRuntimeEntityStatGridCommit
|
||||
{
|
||||
Name = name,
|
||||
Width = width,
|
||||
Height = height,
|
||||
Values = flattened
|
||||
};
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEntityStatGridCommit ProjectBool2Grid(string name, bool2[,] values, int axis)
|
||||
{
|
||||
if (values == null)
|
||||
return null;
|
||||
|
||||
var width = values.GetLength(0);
|
||||
var height = values.GetLength(1);
|
||||
var flattened = new double[width * height];
|
||||
var index = 0;
|
||||
for (var y = 0; y < height; y++)
|
||||
for (var x = 0; x < width; x++)
|
||||
flattened[index++] = (axis == 0 ? values[x, y].x : values[x, y].y) ? 1.0 : 0.0;
|
||||
|
||||
return new AetheriaRuntimeEntityStatGridCommit
|
||||
{
|
||||
Name = name,
|
||||
Width = width,
|
||||
Height = height,
|
||||
Values = flattened
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -525,5 +525,24 @@ namespace GameCult.Aetheria.State.Unity
|
|||
|
||||
[Key(14)]
|
||||
public IReadOnlyList<IReadOnlyList<int>> WeaponGroups { get; set; } = Array.Empty<IReadOnlyList<int>>();
|
||||
|
||||
[Key(15)]
|
||||
public IReadOnlyList<AetheriaRuntimeEntityStatGridCommit> StatGrids { get; set; } = Array.Empty<AetheriaRuntimeEntityStatGridCommit>();
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public sealed class AetheriaRuntimeEntityStatGridCommit
|
||||
{
|
||||
[Key(0)]
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
[Key(1)]
|
||||
public int Width { get; set; }
|
||||
|
||||
[Key(2)]
|
||||
public int Height { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public IReadOnlyList<double> Values { get; set; } = Array.Empty<double>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,6 +135,10 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
|
|||
visual parameters now survive through the typed pending commit lane into
|
||||
`AetheriaZoneState`. `RuntimeZoneBlueprint` feeds this projector, but it is
|
||||
no longer the only place generated celestial graph facts can live.
|
||||
- Run checkpoint entity snapshots include typed simulation stat grids for
|
||||
temperature, thermal mass, armor, max armor, and hull-conductivity axes.
|
||||
`RuntimeEntityBlueprint` still exists for construction/loadout projection,
|
||||
but those live hull grids no longer survive only as blueprint fields.
|
||||
- `Aetheria.State` now defines `AetheriaLoadoutTemplate` as the typed Verse
|
||||
replacement for bespoke `.loadout` files. It stores structured hull,
|
||||
equipment, cargo bay, docking bay, child-entity, assignment, and weapon-group
|
||||
|
|
@ -738,9 +742,13 @@ First Aetheria surfaces to publish:
|
|||
- Done: extend run checkpoint commits and smoke coverage to carry typed
|
||||
zone orbit/body rows into `AetheriaZoneState`, so generated celestial
|
||||
graph facts no longer live only inside `RuntimeZoneBlueprint`.
|
||||
- Done: extend run checkpoint commits and smoke coverage to carry typed
|
||||
entity simulation stat grids into `AetheriaEntitySnapshot`, so
|
||||
temperature/armor/conductivity no longer live only in runtime blueprints.
|
||||
- Remaining: add typed documents/mappers for runtime object graphs,
|
||||
typed behavior factory construction, simulation state, and any catalog
|
||||
fields not covered by the stable scalar/fingerprint/payload pass.
|
||||
typed behavior factory construction, behavior-private simulation state,
|
||||
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
|
||||
|
|
@ -1130,9 +1138,9 @@ First Aetheria surfaces to publish:
|
|||
resolution, including full player settings as the `PlayerSettings.msgpack`
|
||||
replacement, loadout templates as the `.loadout` replacement, and a run ->
|
||||
zone -> entity snapshot graph as the `.zone` replacement. The zone smoke
|
||||
includes orbit/body rows for generated celestial state. It also proves
|
||||
`aetheria.runtime_session.v1` is advertised and survives reopen as the typed
|
||||
daemon-session signal.
|
||||
includes orbit/body rows for generated celestial state, and the entity smoke
|
||||
includes typed simulation stat grids. It also proves `aetheria.runtime_session.v1`
|
||||
is advertised and survives reopen as the typed daemon-session signal.
|
||||
- CultMesh smoke proves node start, typed put/get, subscription, flush, and
|
||||
reopen.
|
||||
- Eve surface smoke proves provider-owned surface documents are generated from
|
||||
|
|
|
|||
Loading…
Reference in a new issue