Run Re-Do
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using Unity.Entities;
|
||||
|
||||
namespace ProjectM.Simulation
|
||||
{
|
||||
/// <summary>
|
||||
/// The ONE collector of the permanent-meta save slice (the SaveStructureScan idiom): reads the director's
|
||||
/// replicated <see cref="MetaTierState"/> buffer + server-only <see cref="MetaCounters"/> into the
|
||||
/// <see cref="SaveData"/> v6 fields. Shared by BOTH save writers — <c>SaveWriteSystem</c> (autosave) AND
|
||||
/// <c>WorldLauncher.TrySaveFromServer</c> (quit-to-menu) — so the writers can never drift; the quit path
|
||||
/// silently omitting these fields would WIPE all permanent progression on the most common exit (the meta
|
||||
/// review's top blocker). Rows are copied VERBATIM (unknown ids round-trip).
|
||||
/// </summary>
|
||||
public static class MetaSaveScan
|
||||
{
|
||||
public static void Collect(EntityManager em, Entity director,
|
||||
out MetaUpgradeSave[] rows, out int runsCompleted, out int maxDepthReached)
|
||||
{
|
||||
rows = System.Array.Empty<MetaUpgradeSave>();
|
||||
runsCompleted = 0;
|
||||
maxDepthReached = 0;
|
||||
|
||||
if (em.HasBuffer<MetaTierState>(director))
|
||||
{
|
||||
var buf = em.GetBuffer<MetaTierState>(director, true);
|
||||
rows = new MetaUpgradeSave[buf.Length];
|
||||
for (int i = 0; i < buf.Length; i++)
|
||||
rows[i] = new MetaUpgradeSave { ClassId = buf[i].ClassId, UpgradeId = buf[i].UpgradeId, Tier = buf[i].Tier };
|
||||
}
|
||||
|
||||
if (em.HasComponent<MetaCounters>(director))
|
||||
{
|
||||
var counters = em.GetComponentData<MetaCounters>(director);
|
||||
runsCompleted = counters.RunsCompleted;
|
||||
maxDepthReached = counters.MaxDepthReached;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83b313e94b9f4304993358deca12e6e2
|
||||
@@ -22,6 +22,10 @@ namespace ProjectM.Simulation
|
||||
/// 2 = Loss -> the run loads finished + halted, no re-arm). Born-correct at director spawn.</summary>
|
||||
public byte RunOutcome;
|
||||
|
||||
/// <summary>v6: persisted run counters to restore into MetaCounters + the born-correct RunInfo HUD mirror.</summary>
|
||||
public int RunsCompleted;
|
||||
public int MaxDepthReached;
|
||||
|
||||
/// <summary>0 = nothing staged (New Game); non-zero = apply the staged slice at director spawn.</summary>
|
||||
public byte HasData;
|
||||
}
|
||||
@@ -32,6 +36,17 @@ namespace ProjectM.Simulation
|
||||
public ushort ItemId;
|
||||
public int Count;
|
||||
}
|
||||
|
||||
/// <summary>One staged PERMANENT meta tier for a Continue session (v6) — copied VERBATIM into the director's
|
||||
/// replicated MetaTierState buffer at spawn (unknown ids preserved for round-trip; clamping happens only at
|
||||
/// seed/shop/spend). The buffer is added UNCONDITIONALLY at staging (empty OK) — the Bursted spawn system
|
||||
/// GetBuffers it inside the HasData block and a missing buffer would throw on any v<=5 Continue.</summary>
|
||||
public struct PendingMetaRow : IBufferElementData
|
||||
{
|
||||
public byte ClassId;
|
||||
public byte UpgradeId;
|
||||
public byte Tier;
|
||||
}
|
||||
/// <summary>One staged player-built structure row for a Continue session (M7); BaseRestoreSystem replays it
|
||||
/// charge-free into the freshly-streamed base. Mirrors <see cref="StructureSave"/> but as an unmanaged ECS
|
||||
/// buffer element (staged in the ServerWorld before the subscene streams).</summary>
|
||||
|
||||
@@ -9,6 +9,18 @@ namespace ProjectM.Simulation
|
||||
public int ItemId;
|
||||
public int Count;
|
||||
}
|
||||
|
||||
/// <summary>One persisted per-class PERMANENT meta-upgrade tier (v6). ClassId = the normalized CharacterId
|
||||
/// (Warrior=2/Ranger=3); UpgradeId = the append-only meta-catalog key (unknown ids round-trip preserved and are
|
||||
/// skipped live); Tier clamps to the catalog's MaxTier at seed/shop/spend, never at rest.</summary>
|
||||
[Serializable]
|
||||
public struct MetaUpgradeSave
|
||||
{
|
||||
public byte ClassId;
|
||||
public byte UpgradeId;
|
||||
public byte Tier;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One serialized player-built structure (M7). Flat scalars (JsonUtility has no int2). The production
|
||||
/// cooldown is stored as REMAINING ticks (epoch-independent) so it survives the server-tick origin reset on a
|
||||
@@ -51,7 +63,7 @@ namespace ProjectM.Simulation
|
||||
[Serializable]
|
||||
public class SaveData
|
||||
{
|
||||
public const int CurrentVersion = 5; // END-2: v5 adds RunOutcome (a won/lost run loads finished); v4 added CoreCurrent
|
||||
public const int CurrentVersion = 6; // v6: permanent META (per-class upgrade tiers + run counters); v5 added RunOutcomeoreCurrent
|
||||
|
||||
/// <summary>Oldest save schema the loader accepts (additive); a v2 save loads with structures at full HP.</summary>
|
||||
public const int MinLoadableVersion = 2;
|
||||
@@ -62,6 +74,11 @@ namespace ProjectM.Simulation
|
||||
public int CoreCurrent; // END-1: Engine Core integrity at save time (0 from a pre-v4 save -> restored to baked Max)
|
||||
public int RunOutcome; // END-2: 0=InProgress (also any pre-v5 save) / 1=Victory / 2=Loss -> a finished run loads finished
|
||||
|
||||
// v6 — permanent meta-progression (0/empty-defaults on any v<=5 save):
|
||||
public int RunsCompleted; // boss-cleared runs (the HUD counter + the HostSalt fold at restore)
|
||||
public int MaxDepthReached; // deepest room actually CLEARED across all runs (honest depth, never planned)
|
||||
public MetaUpgradeSave[] MetaUpgrades = Array.Empty<MetaUpgradeSave>(); // sparse per-class tiers
|
||||
|
||||
public LedgerRow[] Ledger = Array.Empty<LedgerRow>();
|
||||
public StructureSave[] Structures = Array.Empty<StructureSave>();
|
||||
public StructureIoRow[] StructureIo = Array.Empty<StructureIoRow>();
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace ProjectM.Simulation
|
||||
// field 0-defaults and the restore guard maps 0 -> baked Max); v0/v1 garbage is still rejected.
|
||||
if (data == null || data.Version < SaveData.MinLoadableVersion || data.Version > SaveData.CurrentVersion) return null;
|
||||
data.Ledger ??= Array.Empty<LedgerRow>();
|
||||
data.MetaUpgrades ??= Array.Empty<MetaUpgradeSave>(); // v6: null on any v<=5 file();
|
||||
return data;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
Reference in New Issue
Block a user