Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.15k stars 435 forks source link

Observer system initial object #53

Closed TwoTenPvP closed 6 years ago

TwoTenPvP commented 6 years ago

Issue Type

Description

Currently, every networkedObject is replicated when a client first joins. This is due to how the MLAPI was designed before the observer system. With the addition of it, only observed objects should even be sent from the beginning. Making clients unaware of non-observed objects. This might lead to unexpected behaviour and future limitations. It would not allow host migration etc where clients have to be aware of the objects even if they don't neccecarly have the latest state.

One alternative would be to still tell every client of every object's existance but with limited information. Where things like SyncedVars, position? are excluded and only neccecary information is sent. Many parts of the MLAPI depend on every client knowing about every object. So minor changes are required in a few places. Ex ownership changes ignore observers.

Your Environment

TwoTenPvP commented 6 years ago

Further opinions are encouraged

TwoTenPvP commented 6 years ago

https://github.com/TwoTenPvP/MLAPI/commit/5a8eb76c480130f8607d47f8831e7695b32eb4c9 SyncedVars are no longer sent on the spawn call for non observed objects when a client joins. Idk about this though. It has it's problems. The idea of the NetworkStart method is that EVERYTHING is ready once it's called. SyncedVars, NetBehaviour variables etc. That doesn't hold true with this design. Edit: https://github.com/TwoTenPvP/MLAPI/commit/81f89e34b01fb990954b283a91659042c435171c Reverted. This probably needs more thought, I don't want to design a dirty system like the HLAPI. It needs consistency. The solution https://github.com/TwoTenPvP/MLAPI/commit/5a8eb76c480130f8607d47f8831e7695b32eb4c9 is efficient but not consistent. While the current behaviour is the other way around. The HLAPI suffers massivley from these things, lot's of callbacks for different events, the one frame bug where you have to wait for the second frame for things to be ready etc.

angusmf commented 6 years ago

It's two different use cases. For a "simple" case, you want everything synced all the time and don't want to know about the observer system. For advanced use, you want the above behavior. Thus you could resolve this by having two different API usages or modes.

TwoTenPvP commented 6 years ago

Observer system is "turned off" by default. It's not really turned off. But rather, every object is considered observed by default. So if you don't want to touch the observer system. You don't have to.

angusmf commented 6 years ago

So just make that distinction very clear and you're all good. It's like the diff between client server and p2p with a player host (the way MLAPI and HLAPI work.) There isn't really a difference, but the use is different, so you just make it "easy" to work in the two modes however you have to.

TwoTenPvP commented 6 years ago

Right.

Just to make things clear. No matter the decision of how to resolve this. The ones not using the observer system will not be affected. Essentially it's how to handle new clients that join where the developer specifically says: This object is not observed by this client.

What do we do?

Right now we spawn and sync it's data anyways. Just on the initial spawn.

Not spawning it at all until it gets observed would mean developers have to be aware that objects might not exist on both ends which will lead to confusion but will be more efficient.

Only syncing parts of the data, by ex. excluding SyncedVars would mean that the NetworkStart method no longer means, I am now ready. Unless we delay the call at which point additional problems occur for users who register Message handlers who doesn't even respect the observer system.

angusmf commented 6 years ago

I think it's ok for NetworkStart to mean, "This set of things is ready", the definition of which could change depending on whether you turn off any observers. Instead of, "Everything is ready", you might want a SyncedVarsSynced, etc. Dealing with the observer system efficiently is probably going to require extending the API surface for it, just like the ownership concept wanted new methods.

TwoTenPvP commented 6 years ago

https://github.com/TwoTenPvP/MLAPI/commit/26072db804206d8ab72c1f947f03663e82f9a6b6 NetworkStart no longer means that everything is ready. It should now be treated as the network version of Start / Awake. The only change is that SyncedVars are no longer guaranteed to be Synced when this gets invoked. (They will be if you don't use the observer system or you set it to observed during initial spawn). An additional OnSyncVarUpdate virtual was added to NetworkedBehaviour to get a callback each time the SyncedVars gets updated for this behaviour.