From 251c1efce740528b6ebaf0e08615646a234bb6d3 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 22 Aug 2026 11:52:03 -0700 Subject: [PATCH] refactor: store DecayResetTime via WriteDeltaTime pending the anchored-time port Delta ticks at full precision instead of clamped whole minutes; the read guard against LastMoved stays since LastMoved is still minute-rounded. Swaps to Write/ReadAnchoredTime mechanically once the save-time anchor is ported. Safe to reshape the v10 payload: no v10 saves exist yet. Co-Authored-By: Claude Fable 5 --- .../Server.Tests/Tests/Items/DecayRegistrationTests.cs | 5 +++-- Projects/Server/Items/Item.cs | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Projects/Server.Tests/Tests/Items/DecayRegistrationTests.cs b/Projects/Server.Tests/Tests/Items/DecayRegistrationTests.cs index 9e71f25ef..4159780d7 100644 --- a/Projects/Server.Tests/Tests/Items/DecayRegistrationTests.cs +++ b/Projects/Server.Tests/Tests/Items/DecayRegistrationTests.cs @@ -325,9 +325,10 @@ public class DecayRegistrationTests var copy = new Item(item.Serial); copy.Deserialize(new BufferReader(writer.Buffer)); - // LastMoved persists as whole minutes; allow that much slack. + // The stamp is stored as a delta, so it ages only by the real time between + // write and read - milliseconds here, the downtime in production. Assert.True( - (copy.ScheduledDecayTime - expected).Duration() <= TimeSpan.FromMinutes(1), + (copy.ScheduledDecayTime - expected).Duration() <= TimeSpan.FromSeconds(5), "The restarted decay window must survive a save/load cycle." ); diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 8d2ef21f2..ae1931a0b 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -1026,8 +1026,8 @@ public partial class Item : IHued, IComparable, ISpawnable, IObjectPropert if (GetSaveFlag(flags, SaveFlag.DecayReset)) { - var resetMinutes = new TimeSpan(now - info.m_DecayReset.Ticks).TotalMinutes; - writer.WriteEncodedInt((int)Math.Clamp(resetMinutes, 0, int.MaxValue)); + // Replace with WriteAnchoredTime once the save-time anchor is ported. + writer.WriteDeltaTime(info.m_DecayReset); } if (GetSaveFlag(flags, SaveFlag.Direction)) @@ -2778,10 +2778,10 @@ public partial class Item : IHued, IComparable, ISpawnable, IObjectPropert if (version >= 10 && GetSaveFlag(flags, SaveFlag.DecayReset)) { - var reset = Core.Now - TimeSpan.FromMinutes(reader.ReadEncodedInt()); + var reset = reader.ReadDeltaTime(); - // Minute rounding can land the stamp on LastMoved; keep it only while it - // extends the deadline. + // LastMoved is stored at whole-minute precision; keep the stamp only + // while it still extends the deadline. if (reset > LastMoved) { DecayResetTime = reset;