Skip to content

fix: remove unnecessary checks for empty client snapshot and count in NetSyncServer#354

Merged
from2001 merged 1 commit intodevelopfrom
fix/stealth-client-disconnect-notification
Mar 2, 2026
Merged

fix: remove unnecessary checks for empty client snapshot and count in NetSyncServer#354
from2001 merged 1 commit intodevelopfrom
fix/stealth-client-disconnect-notification

Conversation

@from2001
Copy link
Collaborator

@from2001 from2001 commented Mar 1, 2026

Close #349

This pull request makes a small change to the _serialize_room_transform method in STYLY-NetSync-Server/src/styly_netsync/server.py, removing early returns that previously caused the function to return None when there were no client snapshots or when no client data was serialized. Now, the function always returns a serialized buffer, even if it is empty. [1] [2]

@from2001
Copy link
Collaborator Author

from2001 commented Mar 1, 2026

Issue: Disconnection Detection Failure with Stealth Clients

When only stealth clients remain in a room, the server fails to send an "empty room broadcast." Consequently, disconnection detection is never triggered on the client side.

Reproduction Flow

  1. Room State: Stealth Client A (Local) + Normal Client B (Remote).
  2. Client B Disconnects: After 5 seconds, the server’s _cleanup_clients removes B.
  3. Room Flags as "Dirty": _adaptive_broadcast_all_rooms attempts a broadcast.
  4. Snapshot Construction: During the client_snapshot build, Stealth Client A is skipped, resulting in an empty list.
  5. Serialization Logic: _serialize_room_transform is called, but execution hits the following guard clause:
# server.py:1810-1811
if not client_snapshot:
    return None  # Ends here without sending the broadcast
  1. Unity Side: The Unity client never receives a room broadcast that excludes Client B.
  2. Logic Failure: The disconnection detection logic in ProcessRoomTransform (MessageProcessor.cs:339-365) is never triggered.
  3. Ghosting: Client B’s remote avatar remains stuck in the Hierarchy.

Why it works in "Normal Mode"

In Normal Mode (where LocalAvatarPrefab is present), the local client is treated as a non-stealth client.

After Client B disconnects, the local client's transform data is still included in the client_snapshot. Because the snapshot is not empty, the broadcast is successfully sent, allowing the remaining client to recognize that B is no longer in the room list and clean up the avatar.

@from2001 from2001 merged commit 30af2ba into develop Mar 2, 2026
@from2001 from2001 deleted the fix/stealth-client-disconnect-notification branch March 2, 2026 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stealth client does not receive disconnect notification when the last normal client leaves a room

1 participant