docs: update serialization docs and skills for generator v4
Replaces order-based linkage ([SerializableFieldSaveFlag]/[SerializableFieldDefault]) with field-side [SaveFlag(nameof(...))], [TimerDrift]/[DeserializeTimerField] with [DeserializeTimer(nameof(Method), wallClock)], and documents the [SerializableField] setter hooks (allowFieldChange/fieldChanged), the anchored-time semantics for drifting timers, [AnchoredDateTime], and the timer MigrateFrom pattern. Narrows [SerializableProperty] guidance to custom getters. Also fixes the documented [SerializableField] signature (the saveIf parameter never existed) and refreshes real-code examples that were converted in the v4 migration PRs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
b042edcf0b
commit
76bbcd88c4
7 changed files with 219 additions and 63 deletions
|
|
@ -457,16 +457,24 @@ set
|
|||
```
|
||||
Without this, changes won't be saved.
|
||||
|
||||
Most RunUO custom setters only clamp the value or run side effects after assignment. Those
|
||||
convert to a plain `[SerializableField]` with the `allowFieldChange`/`fieldChanged` hooks,
|
||||
which handle the equality check and `MarkDirty()` for you -- reserve `[SerializableProperty]`
|
||||
for custom getters (see `dev-docs/serialization.md`).
|
||||
|
||||
### 3. Field Ordering
|
||||
The `[SerializableField(N)]` index determines serialization order. Choose a logical order and don't change it after the first save — or increment the version.
|
||||
|
||||
### 4. Conditional Serialization
|
||||
Use `[SerializableFieldSaveFlag]` and `[SerializableFieldDefault]` to skip default values:
|
||||
Use `[SaveFlag]` on the serializable field to skip default values (the second method is
|
||||
optional -- omit it and the field keeps its default at load):
|
||||
```csharp
|
||||
[SerializableFieldSaveFlag(0)]
|
||||
[SerializableField(0)]
|
||||
[SaveFlag(nameof(ShouldSerializeMaxItems), nameof(MaxItemsDefaultValue))]
|
||||
private int _maxItems;
|
||||
|
||||
private bool ShouldSerializeMaxItems() => _maxItems != -1;
|
||||
|
||||
[SerializableFieldDefault(0)]
|
||||
private int MaxItemsDefaultValue() => -1;
|
||||
```
|
||||
|
||||
|
|
@ -479,12 +487,15 @@ private List<Mobile> _followers;
|
|||
```
|
||||
|
||||
### 6. DateTime Fields
|
||||
Use `[DeltaDateTime]` to survive server restarts:
|
||||
Use `[AnchoredDateTime]` to survive server restarts -- the value is shifted by downtime at
|
||||
load, so the remaining time is preserved and idle saves stay byte-stable:
|
||||
```csharp
|
||||
[DeltaDateTime]
|
||||
[AnchoredDateTime]
|
||||
[SerializableField(0)]
|
||||
private DateTime _expireTime;
|
||||
```
|
||||
(`[DeltaDateTime]` is the legacy equivalent; it rewrites bytes on every save. Converting an
|
||||
existing field between the two changes the wire format and requires a version bump.)
|
||||
|
||||
### 7. Keeping Manual Serialization (Rare)
|
||||
Some edge cases still need manual serialization. If a type has complex conditional logic that can't be expressed with attributes, you can implement `ISerializable` manually. But this is rare — try attributes first.
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ In RunUO, timers are commonly started in `Deserialize()`. In ModernUO, use `[Aft
|
|||
`_token.Cancel()` can be called on a default token, a stopped token, or an already-cancelled token. No null checks needed.
|
||||
|
||||
### 4. Timer.DelayCall Still Exists
|
||||
`Timer.DelayCall()` is still available and returns a `Timer` object. Use it when you need the `Timer` reference (e.g., for `[DeserializeTimerField]`) or state-carrying overloads.
|
||||
`Timer.DelayCall()` is still available and returns a `Timer` object. Use it when you need the `Timer` reference (e.g., for a serialized timer field with `[DeserializeTimer]`) or state-carrying overloads.
|
||||
|
||||
### 5. Custom Timer Classes Are Still Possible
|
||||
For complex timer logic (e.g., `Corpse.DecayTimer`), you can still subclass `Timer` with `OnTick()`. But prefer the fire-and-forget pattern for simple cases.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue