A GM flipping Movable (or Visible) back on for a long-frozen item registered it with a deadline computed from its stale LastMoved, so the scheduler deleted it on the next tick. The old save-time decay sweep had the same semantics but hid them behind the save cadence. Introduce DecayResetTime (CompactInfo-backed, persisted as delta minutes under a new SaveFlag with an Item version bump): the decay countdown now runs from the later of LastMoved and DecayResetTime. RestartDecay() stamps it only when the item can decay and the stamp extends the deadline, so hot paths with a fresh LastMoved allocate nothing. - Movable/Visible/Spawner setters restart the countdown instead of registering a stale deadline - The region-refusal retry in DecayScheduler restarts the countdown without rewriting LastMoved, which is reserved for actual moves - A raw Map assignment (e.g. props) now counts as a move: it stamps LastMoved and enrolls/withdraws the item, closing the gap where an item moved out of Map.Internal via the setter never decayed Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| Application | ||
| BuildTool | ||
| Logger | ||
| Server | ||
| Server.Tests | ||
| UOContent | ||
| UOContent.Tests | ||