Simulator Connection Issues & LiveQuery

Hello, I’ve been messing around with getting simulator and server authoritative npcs working for a while now.

I’ve managed to get the simulator to connect only during local testing in the editor. (not with running a local simulator, nor uploading a cloud build). What I found success with is: Changing the editor project settings to COHERENCE_SIMULATOR, and then manually connecting via script which connects to local and world id 123.

When I did that it worked as expected.

Problem 1: I ran into an issue with LiveQuery. I put one on my player object which simulates in Server + Client input. and that worked great. But if I also put a LiveQuery on an object that the simulator spawns(that spawned object simulates in just Server…), as soon as the player object gets into range, the client controlling it loses input and cannot be controlled anymore.

Problem 2: If I remove the code that manually connects the simulator and instead use the Auto Simulator Connect component, nothing seems to work. Not on local and not on cloud.
My process is to coherence hub > Simulators > build and upload headless linux client. Then change the server to use the new simulator slug and save/restart.
I also tried local simulator build.

I’ll also add that i’m just modifying the demo scene for AreasOfInterest while testing this stuff.

1 Like

Hi Travis! And I’ll assume you are “clonze” on Discord, right?

As Miguel replied, you might have stumbled into a bug present on pre 1.0 versions affecting LiveQueries parented to other objects. It will be fixed for 1.0, as we definitely intend to support that use case.
For now I would suggest to leave the LiveQuery component on the root of the Player prefab - so you circumvent any issue.
(again, for now)

I would also suggest to set these CoherenceLiveQuery components to disable when you don’t have or lose authority on the player. You can use the so-called “Component Actions” to do it all automatically. They are briefly explained on this page, and also in the first lesson of our tutorial project.

For this one, I would say, can you share the Logs of the Simulator? I usually get them from the World interface, but there should be some also for Rooms. This way we can see what’s happening when the Simulator tries to connect, and fails.

I’m running a world simulator, not using rooms at the moment.
Not sure if i’m getting the correct logs here, this is off of the cloud upload. The logs just look like a bunch of shader warnings for headless build or something…

Simulator logs:

Replicator logs:

I’m a little bit confused because the LiveQuery components do not show up as a component that I can disable with component actions:

Also I noticed when the player moves into the simulator server object’s live query radius, it despawns my player and respawns it as a [networked] [local] named object rather than just a [local]. Thats when I lose control and can only visually rotate the character with input keys. The simulator also can adjust the visual rotation of the object, but neither can actually move it.

Sorry if I’m not understanding something and wasting your time explaining this to me.

It’s perfectly fine! I am happy to try and help :slight_smile:

The Simulator logs generally do. Nothing super wrong that I can see, except maybe this line:

Error response from daemon: network with name cgria0lbo1hvlpoltfhg already exists

But I don’t know what it means. I have asked our Online team.

On the Replication Server side, I can see that you do have some Simulator successfully connect, but not always. You can notice them if you look in the logs for IsSimulator: true, that’s when a Client successfully connected as a Simulator.

Interesting! It’s probably intentional, because the LiveQuery is a bit of a special component from the network point of view. But you can always disable it manually, by hooking into CoherenceSync’s callbacks, like OnStateRemote and OnStateAuthority. But I also want to clarify one thing:

Before, I suggested you to disable these LiveQueries. But what I meant is, disable them on the Simulator! As in, on the Simulator you want only the LiveQueries that concern the Simulator to be active.
On a Client, you want only the ones who concern the player to be active, otherwise they can effectively cheat, because they see too much.

To make an example:
A big world shooter game. Each character prefab has a LiveQuery component parented to it. On spawn, the remote characters disable their LiveQuery. Say we have 2 Clients connected (A and B) and a Simulator (S) driving a bunch of bots.
You will have:

  • Client A: Here we have Player A with an active LiveQuery on them, while Player B and the bots have none.
  • Client B: Here we have Player B with an active LiveQuery on them, while Player A and the bots have none.
  • The Simulator: from their point of view, Player A and Player B have no LiveQuery, but the bots all have one. This is the case if you want the human Clients to have full authority on their Player characters. For a server-authoritative setup, You might as well have a special LiveQuery for the Simulator which is set to radius 0, so they see it all!

So each network node sees only what concerns them, and they never lose sight of their owned players!

Does this clarify it a bit?

So my next question is, were you using them differently? Perhaps disabling the Client’s own LiveQuery? Maybe that’s what was creating the issue?

Thanks for the response, I’ll go through what you said and try it out.

To answer your question I was not disabling any live queries. I had a server authority object which exists in the scene before runtime. I noticed that the simulator did not see the player object so I thought adding a livequery to the server object is the correct way to fix that.

My goal is to have a server authoritative game. right now i’m working on trying to get enemy NPCs to detect the players on the simulator.

I'll try to give you a way to reproduce this problem:
1) start with the coherence demo. Load up the scene areasOfInterest in editor.
2) modify the player prefab to be authority: Server + Client Input
3) add input fields to the CoherenceInput component: "Horizontal", "Vertical", "Jump" 
4) add a livequery to the root player object with 10 radius.
4) Create a new object in the scene, add coherence sync
5) Set the new object to be simulated in: "Server"
6) Add a livequery to the root new object with 10 of radius.
7) Load up the world server, start a simulator, start the client, walk the player into the server object and lose control.

I don't think this is working as intended. When I switch the player to be just client side, everything starts working again as it should. So the key thing here is simulator with livequery is rubbing up against Player object that has authority: Server + Client input.

Ah yes, one gotcha: previously I described the setup for a client-side authorship. If you want the gameplay to be server-driven, then you need the Simulator to see all the Player’s entities at all times. As such, I suggest having a special LiveQuery on the Simulator set to radius 0 (infinite).

I have edited my above reply for clarity, so it doesn’t confuse others!

Thanks for the detailed steps, I’ll try them out!

Okay, thanks again for being so responsive!

I thought there would be some performance gain for the simulator if it didn’t see every player but I suppose that probably doesn’t matter, and it makes sense that all the players actions need to be simulated anyhow.

There is, because the Simulator is nothing else than another Unity build with no graphics. And framerate is not guaranteed. So the less it sees, the less it has to process.

But if it has to drive the gameplay… well then it needs to see what it’s doing!

Okay, so now i’ve tried with your suggestions.

  1. setting 0 radius on the simulator livequery.
  2. using awake to hook into OnStateAuthority for player objects and disabling the livequery
  3. using awake to hook into OnStateAuthority for the simulator server object to disable the livequery for clients.

I’ve also tried both having the livequery for players as a child object of the root object and also just having the livequery component on the root object itself. both cases gave same results.

With the new 0 radius setting, the player objects now immediately lose control.

Please let me know if you’ve tried it yourself and found it to be working.

Quick question: do you have the correct scene in the Simulator Build Options, within the Simulators tab of the coherence Hub?

yes i do

1 Like

Ok cool.
I’m testing in the project, following the exact steps you detailed. Will come back soon :slight_smile:

Ok, so, I think what you are seeing is according to norm. I’ll explain, starting from what I think is the mistake:

I presume you think that the CoherenceInput script will automatically apply your input based on those 3 fields (“Horizontal”, “Vertical”, “Jump”), but that is not the case.
You can read more about it here: Server-authoritative setup - Unity Multiplayer SDK Documentation | coherence

What is happening then, is this:

  • When you start the game, the Player character - which is supposed to be driven by the server - is actually outside of the Simulator’s LiveQuery. As such, the Simulator doesn’t know about it, and the Player retains full control.
    You can verify this in the CoherenceSync:

    The reason why you are able to move it now is because it’s still using Client-side input via the script PlayerInput (which is just regular game code).

  • When you walk into the Simulator’s LiveQuery, the Simulator goes: “hey, that’s mine!” and takes control of the player’s state. You can see that the CoherenceSync reflects this:

  • The reason why you can’t walk anymore is because, as soon as you lose authority, both PlayerInput and Move are disabled, as configured in the coherence Config window, third tab (Components):

What you really need to do is to familiarise yourself with CoherenceInput, and modify the whole setup accordingly.

This probably means removing my PlayerInput script altogether or disabling it when player becomes remote, but keeping the Move script active so you can pass to it - on the Simulator - the inputs that the Sim receives through the network.

Hope it helps.

1 Like

Thank you. Sorry about that… I was assuming it was working before :cold_face: This makes much more sense now, before I thought it was pure magic… no delay on server authoritative? yup I can feel it now! Now I gotta see if I can smooth it out and if it’s worth putting effort into this for anti cheating.

I also had to mark the rigidbody to leave as it for no authority action for anyone else stumbling across this.

1 Like

If you want to do prediction locally, you could. But wouldn’t it make more sense to still have it as kinematic on the Client, given that if any physics event happens, they will be detected on the Simulator?

Yes, well I just meant that after the initial spawn, the simulation’s version of the rigidbody gets marked as kinematic with the default settings, so that was causing movement not to occur.

Ah, right, of course!
Yeah I think for your setup you might want to not use the Config window, which is intended for simple use cases and for people who can’t put their hands into code.

Keep in mind that you can also handle variables and commands in code: [Sync] and [Command] Attributes - Unity Multiplayer SDK Documentation | coherence

1 Like