ModernUO/dev-docs/claude-skills/migrate-from-runuo/migrate-persistence.md
Kamron Batman 4f9bc1d9f6
feat: Adds AI skills to migrate from RunUO (#2366)
## Summary

Adds comprehensive RunUO → ModernUO migration documentation and Claude AI skills to help shard owners and script authors convert RunUO 2.7 code to ModernUO.

- **10 migration skills** (`dev-docs/claude-skills/migrate-from-runuo/`) — system-by-system conversion guides (foundation, serialization, timers, gumps, packets, property lists, commands/events, persistence, items/mobiles, systems/engines)
- **12 reference docs** (`dev-docs/runuo-migration-docs/`) — deep-reference with before/after examples, API mapping tables, edge cases, and gotchas
- **Updated existing skills** — `modernuo-timers`, `modernuo-serialization`, and `modernuo-threading` now document that `Serialize()` runs on background threads and timers are not thread-safe
- **Updated `CLAUDE.md`** — added migration skill lookup table

### Key migration patterns covered
- Manual `Serialize()`/`Deserialize()` → source-generated `[SerializableField]`
- `Packet` class hierarchy → static `SpanWriter`/`SpanReader` methods
- `Timer` subclasses → `TimerExecutionToken` fire-and-forget
- `Gump` → `StaticGump<T>`/`DynamicGump` with builders
- `EventSink.WorldSave` → `GenericPersistence`
- `ObjectPropertyList` → `IPropertyList` with string hole rules
- Universal changes: naming (`m_` → `_`), `[Constructable]` → `[Constructible]`, logging, spatial queries
2026-03-13 00:33:45 -07:00

1.9 KiB

name description
migrate-persistence Trigger: when converting RunUO EventSink.WorldSave/WorldLoad manual binary persistence to ModernUO GenericPersistence. Covers: GenericPersistence subclassing, IGenericWriter/IGenericReader, MarkDirty pattern.

RunUO -> ModernUO Persistence Migration

When This Activates

  • Converting EventSink.WorldSave/EventSink.WorldLoad patterns
  • Converting manual BinaryFileWriter/BinaryFileReader persistence
  • Systems that save custom data outside of Item/Mobile serialization

Conversion Steps

  1. Create class inheriting GenericPersistence: class MySystem : GenericPersistence
  2. Add static instance + Configure(): _instance = new MySystem();
  3. Call base("SaveName", 10) in constructor
  4. Move save logic to override Serialize(IGenericWriter writer)
  5. Move load logic to override Deserialize(IGenericReader reader)
  6. Remove EventSink.WorldSave/WorldLoad subscriptions
  7. Remove all file management code (Directory.Create, File.Exists, FileStream)
  8. Add _instance.MarkDirty() wherever data changes
  9. Replace writer.Write(mobile.Serial.Value) -> writer.Write(mobile)
  10. Replace World.FindMobile(reader.ReadInt32()) -> reader.ReadEntity<Mobile>()

Template

public class MySystem : GenericPersistence
{
    private static MySystem _instance;
    public static void Configure() => _instance = new MySystem();
    public MySystem() : base("MySystem", 10) { }
    public override void Serialize(IGenericWriter writer) { /* save */ }
    public override void Deserialize(IGenericReader reader) { /* load */ }
}

See Also

  • dev-docs/runuo-migration-docs/08-persistence.md -- detailed migration reference with before/after
  • dev-docs/serialization.md -- ModernUO serialization system (IGenericWriter/IGenericReader)
  • dev-docs/claude-skills/modernuo-serialization.md -- ModernUO serialization skill