Skip to content

v0.24.0

Choose a tag to compare

@dmitry-lebedev dmitry-lebedev released this 28 May 06:27
· 63 commits to main since this release
651db56

Two redesigns and a server-side allocation rework. Wire-breaking: 0.23.x ↔ 0.24.0 do not mix.

  • Signature handshake — annotated client signature replaces ClientCapabilities. O(1) gate, < 100 B steady-state connect (vs ~5 KB). Client-side IServerAnnotationCache (in-memory + Unity PlayerPrefs); cache invalidation via serverHash.
  • Client-owned subscriptions — server no longer persists subscription list; client claims its set on Resume via SessionConnectRequest.ClaimedSubscriptions, entity grain verdicts Continued / Refreshed / Failed per claim. Any Failed routes through IMetaSessionRecoveryHandler.
  • Session recovery — explicit SessionConnectMode.{Resume,StartNew}; IMetaSessionRecoveryHandler game-level callback on SessionUnknown; unified TriggerRecovery (transport-reconnect + server-pushed). Persisted RPC-ordering baseline (LastDispatchedRequestId + LastCompletedRequestId) eliminates infinite retry loops after silo restart; stale + cache-miss returns an error op instead of silent re-execution.
  • Server-side allocation rework — PooledPayloadRegistry (0.23.1 opt-in, never engaged) removed (~1500 LOC, 9 files). Replaced by cached IPayloadWriter per grain returning ReadOnlyMemory<byte> over pool-rented scratch (IServerRecordContext.AcquireWriter()); Immutable<ROM> kept only at Orleans grain boundaries; SessionManagerGrain hot-path wrappers flipped class → struct; _pendingPackets aliased to persisted state; CleanupPendingPackets* rewritten (prefix-scan + single RemoveRange).
  • Fixes —
    • ReclaimSubscriptionAsync truth source is EntitySequenceNumber alone; missing Subscribers entry is repaired in place (no more state-rollback after silo restart with offline-applied RPCs).
    • Client _lastKnownEntitySeq advances on every CrossEntityOperations[i], not just the outer entity (no more spurious Refreshed after cross-entity activity).
    • ResendPendingRequestsAsync now awaits Task.WhenAll(resends) — was fire-and-forget, racing with new user actions during recovery.
    • CleanupPendingPacketsByCount — leftover empty for loop caused N-times RemoveRange → broadcasts lost. Fixed.
    • Unity Expedition example — server projects switched from NuGet to ProjectReference.

See docs/GUIDE.md and docs/ARCHITECTURE.md for integration details and rationale.