Local rs and simulator

So I’m trying to develop a simulator server. Following the documentation I have a simulator slug setup, a windows dedicated server. Right now I’m just trying to get things connecting. My project is all code based for connecting so I’m not using the sample UI. I can’t seem to get a connection between my editor, rs and simulator.

Unity 6000.10f1, coherence 1.2.3, All of this is just in editor.

I have everything setup per the defaults and I’m running into 2 consistent issues:

If I have everything setup to connect to a world, I can get the simulator to connect to the RS by hardcoding it to world 0. When I try to connect the client I get:

Join lobby failed: Simulator not enabled. Please make sure that simulators are enabled in the coherence Dashboard.

Which is confusing to me since I thought I had everything setup locally, I’m not sure why a dashboard setting would affect local dev?

When I enable the dashboard setting then it complains about no simulators have been uploaded. So even though I set it up in code to connect locally it’s still reaching out to get settings or something back?

Following the documentation I have this before coherence connects:

var endpoint = new EndpointData
            {
                region = EndpointData.LocalRegion,
                host = "127.0.0.1",
                port = 42002,
                schemaId = RuntimeSettings.instance.SchemaID,
            };
            _coherenceBridge.Connect(endpoint);

I have only 1 bridge in my scene set to be the main bride with these settings:


I made sure Auto Login as Guest is turned off.

The 2nd issue I’m gettings is related to the previous but if I set everything to Rooms, I can’t get the simulator to connect since I don’t know what room to join. It seems rooms aren’t defaulted to id 0? I don’t see any room information in the output from the RS to know what room to connect to. Or does that all happen when the client connects which I can’t seem to get working.

Hey, so I’m taking a look at the first issue regarding the join lobby message to see if I can reproduce what you’re experiencing.

In the meantime when using rooms you have to create a room manually before trying to connect. This is a main difference between rooms and worlds in that the Replication Server can host multiple rooms or one world. So if you’re using rooms you have to instruct the RS to open a room. You can open a room using the rooms dialog sample or using the rooms API: Rooms API | Unity Multiplayer SDK Documentation | coherence

Once the room is open you can request the rooms info from the RS and then connect to the room using the right info.

ok, so I’ve cooked up a test that works fine for worlds connecting the simulator manually using this behaviour in the scene:

using UnityEngine;
using Coherence;
using Coherence.Connection;
using Coherence.Toolkit;

public class ManualConnector : MonoBehaviour
{
    private CoherenceBridge bridge;
    private IClient client;

    private EndpointData endpoint;

    void Awake()
    {
        endpoint = new EndpointData()
        {
            region = EndpointData.LocalRegion,
            host = "127.0.0.1",
            port = 32001,
            schemaId = RuntimeSettings.Instance.SchemaID,
        };

        if (CoherenceBridgeStore.TryGetBridge(gameObject.scene, null, this, out bridge))
        {
            client = bridge.Client;
            client.OnConnected += NetworkOnConnected;
            client.OnDisconnected += NetworkOnDisconnected;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (client.ConnectionState == Coherence.Brisk.ConnectionState.Disconnected)
        {
            bridge.Connect(endpoint);
        }
    }

    private void NetworkOnConnected(ClientID _)
    {
        Debug.Log("Connected.");
    }

    private void NetworkOnDisconnected(ConnectionCloseReason connectionCloseReason)
    {
        Debug.Log("Disconnected.");
    }
}

So, there must be some step you’ve missed or a misunderstanding. Here are the steps I did to test a manually connected simulator and client:

  • created new project
  • installed the SDK
  • in the default scene I added: bridge, world connect dialog sample and a GO with the ManualConnector behaviour above
  • bake
  • set the SampleScene as the scene for simulators in the coherence HUB
  • build the simulator
  • launched the RS in worlds mode
  • disabled the ManualConnector since I want to use the connect dialog on the client, but you could just use it as well and not connect manually but for the “fetch” to work when launching the simulator from the coherence HUB you need to use the dialog
  • run the scene and connect the client to the RS via the dialog
  • stop the scene
  • hit the “fetch” button in the run local simulator setup in the coherence HUB
  • hit run local simulator (see the output show “Connected.”
  • run the scene again and connect again and both the simulator and the client are connected to a local RS.

So, maybe you’ve missed a setup or have some extra work you’re trying to do (like use the cloud API for local RS). The coherence Auto Simulator Connection behaviour is recommended for simulators and it works locally and remotely and with rooms or worlds so you might have more success with that.

So is your setup not checking for the simulator flag turned on from the dashboard? I’ve essentially followed that outside of using the template dialogues since adding that into our flow would be challenging now.
I mean I’m sure I’m missing something simple here but I don’t know how to get around this connect error.

ok, so I think what is happening is you’re trying to both use the cloud simulator and a local connection. My setup example is for connecting a locally running simulator and client to a locally running RS. For purely local development you don’t even need a dashboard account so you don’t need to call any cloud API or even check what the dashboard settings are.

Sorry, had to bounce to some other things going on, I’m now back on this. So looking through the code in the SDK I think I have the pieces to connect and use the local RS.

I now have rooms being created but when I get the callback with the roomdata when I try to join that room I’m getting an error that there is no roomUID 0

I’m at a loss again as to how to actually join the local room. I’m using the data provided in the callback so I don’t know why it’s trying to join roomUID 0.

Forgot to add the code here is where I create the room:

RoomCreationOptions creationOptions = new RoomCreationOptions();
            creationOptions.MaxClients = 4;
            creationOptions.FindOrCreate = true;
            creationOptions.Tags = new[] { "LocalRoom" };

            ReplicationServerRoomsService localRSRoomService = new ReplicationServerRoomsService();
            
            localRSRoomService.CreateRoom(LocalRoomCreated, creationOptions);

And this is just joining the room:

protected void LocalRoomCreated(RequestResponse<RoomData> roomData)
      {
          _coherenceBridge.JoinRoom(roomData.Result);
      }

I don’t define the room UID or anything this all just me using SDK calls and callbacks.

Michael, is the error happening when running in WebGL through the browser? I notice that the log in the RS is a TCPListener rather an a UDP based log.

If so, I’m not sure this is a scenario we have fully supported. Can you verify if things are working in the editor as intended? If so, I will make an issue to investigate and fix the WebGL local RS issue.

This is editor only at the moment.

Is the request response status succesful with no error attached?

Yes it is successful on the client side after the room is created.

If the request was successful it shouldn’t return a RoomData with the room ID set to zero.

Can you dump here the entire RoomData struct please?

Have you tried using the Room sample UI? It has an example on how to work with the ReplicationServerRoomsService API.

Okay here is debug output:

Code that matches it:

protected void LocalRoomCreated(RequestResponse<RoomData> roomData)
        {
            if (roomData.Status == RequestStatus.Success)
            {
                Log(LogLevel.Debug, $"Room created: " +
                                    $"RoomID: {roomData.Result.Id}, " +
                                    $"RoomUniqueID: {roomData.Result.UniqueId}, +" +
                                    $"RoomTag: {roomData.Result.Tags[0]}");
                _coherenceBridge.JoinRoom(roomData.Result);
            }
            else if (roomData.Status == RequestStatus.Fail)
            {
                Log(LogLevel.Error, "LOCAL ROOM CREATION FAILED!");
            }
        }

RS Side:

I understand that bringing the example UI in might be helpful but that would take quite a bit of time to integrate it into this project, and that would also split how we connect to rooms now. I’m not doing anything crazy here, it’s connecting to my local RS it’s making the room. And I’m just trying to connect to the room with the data I get back.

Can you share your entire RS logs including the flags passed to the exec? Are you perhaps hard coding the TCP port into your bridge connection? What does that code look like now?

coherence replication server v6.3.1
Copyright (c) coherence ApS

By running this software, you are agreeing to the coherence Replication Server end-user license agreement (EULA). A copy of this EULA is available at [https://coherence.io/rs-eula].
To display the EULA, run with argument '--eula'.

command: rooms
args:
--api-port 64001
--udp-port 42001
--signalling-port 42002
--send-frequency 20
--recv-frequency 60
--default-schema D:\Projects\proj\Library\PackageCache\io.coherence.sdk\Coherence.Toolkit\Toolkit.schema,D:\Projects\proj\Assets\coherence\Gathered.schema
--log-target=console:colored:info
--env dev

10:29:31.734 INF running replication listener version=v6.3.1
10:29:31.735 INF start udp mux listenHost=127.0.0.1:42001 localAddr=127.0.0.1:42001
10:29:31.737 INF listening for webrtc signalling listenHost=127.0.0.1:42002
10:29:31.737 INF acceptConnections - start logger=TCPListener port=42001
10:29:31.737 INF listening for webrtc listenHost=127.0.0.1:42003
10:29:31.820 INF start prometheus port=64000
10:29:31.824 INF starting address=127.0.0.1:64001 logger=apiServer

I’m using whatever the defaults are, launching this from the editor.

var endpoint = new EndpointData
            {
                region = EndpointData.LocalRegion,
                host = "127.0.0.1",
                port = 42001,
                schemaId = RuntimeSettings.instance.SchemaID,
            };
            _coherenceBridge.Connect(endpoint);

This is the same as before.

Hey michael, when you’re connecting to a room, you don’t need to call the Connect method manually.

Calling JoinRoom will be enough, thats why you’re getting an “already connected” warning from the ClientCore after calling JoinRoom.

You don’t need to be connected to the RS to create a room, since the room is created via a rest api call.

Hope that helps.

I’m not quite sure I follow, I call joinroom on the callback from creating the room. Unless you mean creating the room would also connect coherence?

If so I don’t know how endpoint information gets passed in unless I’m missing something here.

private async Awaitable ConnectToCoherence()
        {
            var endpoint = new EndpointData
            {
                region = EndpointData.LocalRegion,
                host = "127.0.0.1",
                port = 42001,
                schemaId = RuntimeSettings.instance.SchemaID,
            };
            _coherenceBridge.Connect(endpoint);

            RoomCreationOptions creationOptions = new RoomCreationOptions();
            creationOptions.MaxClients = 4;
            creationOptions.FindOrCreate = true;
            creationOptions.Tags = new[] { "LocalRoom" };

            ReplicationServerRoomsService localRSRoomService = new ReplicationServerRoomsService();
            
            localRSRoomService.CreateRoom(LocalRoomCreated, creationOptions);

            _connectToCoherenceRequestCompletionSource = new AwaitableCompletionSource();

            if (_connectToCoherenceRequestCompletionSource != null)
            {
                await _connectToCoherenceRequestCompletionSource.Awaitable;
            }
        }

You can simply delete the first two lines of code from that method and everything will work fine.

The endpoint gets inferred internally by coherence using the data from the RuntimeSettings asset.

Creating a room does not connect you to the RS, joining a previously created room will.

Like I mentioned before, rooms are created in the RS using a rest api.

I strongly suggest firing up an empty scene with a coherencebridge, a livequery and the rooms sample UI to familiarize yourself with the differences between working with a local RS vs cloud-hosted one.

If you don’t want to do that, simply deleting the first two lines of that method will get things working for you.

Cheers!