Trigger OnValueSynced when not connected

Coherence is obviously a multiplayer framework, but many games will want to support solo play as well I imagine. Being able to use the same network objects in both offline and networked environments would be ideal.

When offline, OnValueSynced will not fire (nothing is synced), but a lot of network functionality will obviously be based off of this attribute. This means that the OnValueSynced method will basically need to be duplicated and slightly modified to accommodate for an offline environment when the synced field will not be updated via the network.

I’m not sure the absolute best way to achieve this, but my thought is if Coherence detects no connection, when a script modifies a synced property, it automatically fires the OnValueSynced method. This is essentially simulating sending data over the network and receiving it without actually doing that.

Another thought is that if modifying the OnValueSynced attribute to support this would not make much sense, maybe adding another attribute that would do this such as [SyncWhileOffline] or something like that.

1 Like

Thanks for the suggestion @Neodamus , I’ll add it to our tickets.

I’d like to refresh this one just because it is still something that feels like there’s a reasonable solution here, and is something that anyone who wants both multiplayer and solo play in their game will want to make use of.

If we’re developing a multiplayer game, OnValueSynced is basically a way to do client-side functionality as its needed. There could be a lot of client-side functionality depending on this.

If we then go to a single player environment, OnValueSynced will never fire, and all of the client side functionality that depends on it will not happen.

In the docs for OnValueSynced, it does mention using properties with backing fields for non-simulated entities, which in a single player environment, this does apply… but it would be way better and prevent a lot of patterned code if non-simulated entities also had the capability to invoke OnValueSynced

Obviously, this could function totally differently for a simulated and non-simulated entity in the coherence code, but for the developer, ideally it would be the same abstraction in either case – The value changed, it is marked as syncable, so OnValueSynced will trigger

If I understand correctly, you have entities that are never synced even in multiplayer mode that you’d like to use the OnValueSynced callback for game logic?

No, the entities do sync in multiplayer, and that is expected and works fine.

The issue is when I’m running the game when it is disconnected, as in, a person playing the game by themselves, single player against a simulated player in an offline environment.

In this case, all instantiated entities have full authority, thus OnValueSynced is never called.

In my particular case, 1 very simple example is when the HP of a unit changes, OnValueSynced is what I use to update the HP bar. Though I think using OnValueSynced to update UI elements of all kinds is probably a very general use case.

What this means is in an offline environment, all of the UI logic based off of OnValueSynced doesn’t work.

The best solution I’ve come up with based off of the docs looks like this:

[Sync]
[OnValueSynced(nameof(valSynced))]
public int val;
public int Val {
	get { return val; }
	set {
		val = value;
		if (IsClientEnvironment)
           {
                ValChanged?.Invoke(val);
           }

	}
}
public event Action<int> ValChanged;
void valSynced(int o, int n) => ValChanged?.Invoke(n);

Because OnValueSynced doesn’t work offline, I create a separate event that can get called both offline and online that I plug all the UI into. This works, but just is a lot of extra boilerplate that’s needed just because OnValueSynced doesn’t work offline.

If there’s a way to configure the entity so that it will trigger OnValueSynced offline, that’d obviously be the best solution… maybe I just am not configuring it correctly.

I guess I would summarize by saying, in offline environment, entities are all treated as non-simulated entities… but really I think in offline, they represent both non-simulated entities AND simulated entities because you are simultaneously sim and client.

Got it - ok, I’ll forward your suggestion to the SDK team. I know other developers are using a model where they run an RS locally in single player scenarios and run a simulator as an authoritative client so that their code remains the same offline and online. You could consider setting up something like that. @Mathias may have more info on this setup.

Hey Neodamus,

I understand you use-case and I think this is a very reasonable request.

The problem here is that coherence does not process bindings and entities when offline, so it is not trivial to enable offline callbacks. We’ll discuss this internally to see what can be done.

1 Like

@Mathias Thanks for your response and I appreciate what you are saying fully. You definitely better understand what I’m suggesting on the technical side, so when you say it’s non-trivial, I totally get it. Discussing it internally is all I could ask.

Since you say it’s worthy of discussion, I want to make the case from my perspective, as a user, coming from a conceptual / sustainability viewpoint.

One of the main design choices that I value in Coherence is that it is very much an additive framework. That is, I can use my own code base, add a few attributes, and now my code base is networked. This is extremely powerful.

Every other networking system I’ve used is more of a dependency framework. That is, you need to fit inside the box that they give you to work in.

When I make this suggestion about OnValueSynced, I’m saying Coherence has become very much aligned with ease of use and being non-disruptive with the development process. Even though, the boilerplate I’m using is really not that bad, I also imagine a world where it could be easier because you’ve shown me how easy a thoughtful system can make it for a user.

I imagine most users of Coherence are not going to be multiplayer-only games because most games that are multiplayer also have single player modes. Even though we are a “multiplayer-first” team, it only makes sense to leverage all our work and dedication in the multiplayer mode, by also molding the game into a single player mode, which quite frankly, might lead to more sales than the multiplayer version.

I would also imagine the even more common use case will be games that are already single player and want to add multiplayer onto their already existing game. This is where Coherence shines and has the most advantage imo

All this is to say, I believe it is fair to assume that, generally speaking, when we are using Coherence and we are offline, we still want our machine to act as if we are a “client”. The only thing that has changed, is that we are now ALSO the sim. We never stopped being a client though, and the current functionality treats us as if we did.

There was a change in 1.1 – Release Notes | SDK 1.1 | Unity Multiplayer SDK Documentation | coherence

  • CoherenceSync: we now allow sending commands while disconnected (method gets called locally).

This is a change that has already been made that is in alignment with the idea that we are a “client”, even while offline. This change may be trivial in comparison to the OnValueSynced suggestion, but it is in the same spirit.

1 Like