Skip to content

Conversation

@andy013
Copy link
Contributor

@andy013 andy013 commented Dec 9, 2025

Fix GameObjects in GameObjectSystem NetLists / NetDictionaries being null on clients.

Issue: Facepunch/sbox-issues#9694

Changes

SceneNetworkSystem.cs:

  • Moved GameObjectSystem data table reading to after GameObject spawning

Scene.Network.cs:

  • Removed connection count check to ensure network table isDirty flags are cleared every network update

Notes

When GameObjectSystem data tables were read before GameObjects spawned, GameObjects in NetList/NetDictionaries were null because lookup by GUID failed.

There was a second issue that meant that the first client to connect would not experience the first bug. When the NetList is changed on the host, it's entry within the NetworkTable is marked as isDirty. This is only ever toggled when a network update is sent. Since there are no connections at first, no network update is sent and so isDirty remains true until the first client connects.

When the first client connects, it encounters the first bug, but immediately after it receives an additional delta snapshot which fixes it. This then toggles isDirty to false for that entry on the server, so every other client that connects now develops the first bug with no correction snapshot afterwards.

I found this really confusing. It took me ages to understand why the first client was being treated differently from all the rest. I think the code should be changed so that even when no clients are connected isDirty will still be set to false when the SceneNetworkUpdateticks. This way, every client will run the same code regardless of if they are the first to connect to the server or not. The change I made to Scene.Network.cs does this. I don't think it will have a big performance impact because when there are no changes it just returns early. It might not affect anything else outside of the first bug but I still think it's better to not have some clients running different code from the rest. It could end up masking other bugs that you wouldn't notice while testing if you only connected with one client.

If you want to avoid the extra work when there are no clients connected, other than the host, it should be done in another way, so that isDirty is still set to false each SceneNetworkUpdate regardless of whether an update was sent to anyone or not.

@garrynewman
Copy link
Member

Makes sense to me - what do you think @kurozael

@kurozael
Copy link
Contributor

Looks good to me

@handsomematt handsomematt added the triaged triaged pull-requests are replicated on the internal sbox repo label Dec 12, 2025
@sboxbot
Copy link
Contributor

sboxbot commented Dec 12, 2025

This PR has been merged upstream.

@sboxbot sboxbot added the accepted this pull request was accepted, hurrah! label Dec 12, 2025
@sboxbot sboxbot closed this Dec 12, 2025
@andy013 andy013 deleted the gameobjectsystems_fix branch December 19, 2025 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accepted this pull request was accepted, hurrah! triaged triaged pull-requests are replicated on the internal sbox repo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants