Why is the ServerTravel command not recognized for Dedicated Servers?

Greetings!

I’m attempting to create a game using multiple dedicated servers hosted on a single machine.
Most of the functionality is working, but I can’t seem to use ServerTravel to change maps. When I try, I see this message in the log:
Command not recognized: ServerTravel /Game/FirstPersonBP/Maps/GameplayMap

Since trouble-shooting networking issues tends to involve a lot of background information, I’m going to try to provide a thorough explanation of my setup. Boring details to follow!

General Architecture

I’m attempting to run multiple sessions on a single physical dedicated server.
To achieve that, I have a copy of my game server running before launching the clients. This server is built using the instructions found here.
When a client starts up, I connect to that game server using the OpenLevel blueprint node, specifying the IP address and port of the server.
From this centralized server, clients are able to launch new server instances or find existing server instances to join. Doing either action should move the player to a lobby and (eventually) into a game.

The Test Project

For testing purposes, I display this UI when a client connects to the centralized server:

233228-management-ui.png

This user interface breaks down several of the connection activities I’m performing so that I can test them in isolation.

  • Refresh List Refreshes the list of buttons on the right based on active servers
  • Launch Server Runs the executable for server to start a new server instance (using the next available port)
  • Travel Attempts to perform a ServerTravel to change maps
  • Close & Exit Some preliminary attempts to terminate remote server instances. Out of the scope of this question, I think :wink:
  • Join Button (7778) Buttons on the right represent running servers - click to join

Procedure:

  1. I click Launch Server and wait for the server to finish loading (I send the -log argument for now so that I can watch the server start)
  2. I click Refresh List. A new button appears on the right with the server’s port.
  3. I click the button on the right. The server log shows that a client joined it.
  4. I click Travel. The client log shows the message above (“Command not recognized: ServerTravel”)

Here’s the blueprint code for Launch Server and the join buttons on the right:

And here’s the blueprint code for the Travel button:

Some notes about the travel code:

  • The Full Path checkbox switches between using the map’s full path and just its name
  • The Replicate checkbox switches between calling the LaunchMap function locally and as an RPC on the server
  • For the ExecuteConsoleCommand node, I’ve tried with the player controller connected and with it disconnected

For your viewing pleasure, here’s my configuration for Maps & Modes and the selected game mode. I do have seamless travel checked on.

It’s probably worth noting that I’m not attempting to create/find/join sessions. I was under the impression that using the OpenLevel node to access a dedicated server played a similar role to the session management nodes for listen servers.
If that’s not the case, let me know and I’ll tinker with my test project a bit more.

Here’s the log from my client (with slight modifications and notes):
[Client Log][5]
There are several lines in the log with this message:
SetActiveLevelCollection attempted to use an out of date NetDriver: GameNetDriver
I think this issue is unrelated, but I’d be happy to hear any suggestions for how to solve it, especially if it might explain why the ServerTravel command isn’t being recognized!

Nearly a month with no activity - Bump!

Same Problem!

Bump

Time for another bump

Hi,

just a wild guess: does it work if you spell ‘servertravel’ without any caps (not ‘ServerTravel’ but ‘servertravel’)?

Hey Benjamin!
Thanks for the answer, but alas - it did not work:
Command not recognized: servertravel GameplayMap

I was pretty confident that I’d tried all lower-case before, but I ran it again just to confirm.
Anyway, thanks again and have a good one!

Got it!

It turns out that my issue was a fundamental misunderstanding of how some of Unreal’s built-in classes work. The GameInstance exists on both client and server, but doesn’t share information between the two.

“LaunchMapReplicated” is a custom event in the GameInstance class which I’d marked as Run on Server and Reliable. The problem (I believe) is that it wasn’t actually running on the server - it was still running on the client. That would explain why the “ServerTravel” command wasn’t recognized, since the client wouldn’t know how to perform a ServerTravel.

Armed with that assumption, we still have one obstacle to overcome. We need to run the ServerTravel command on the server, but the button click is occurring on the client.

The solution is to run the RPC in a class that actually does successfully replicate. In this case, I just used the PlayerController. I added a client-side RPC which could be invoked directly from the user interface. That calls a server-side RPC which runs the code containing the ServerTravel command.

It’s probably not strictly necessary to designate the client-side custom event as a Client RPC (since it’s being invoked from the UI, which exists on the client anyway), but I’ve done it for clarity anyway. The “LaunchMap” function being called by “ServerInvokeTravel” is the same function shown in the original question.

The moral of the story is that it’s insufficient to understand what an RPC does - you also have to know where you can use them. I’d recommend checking out this PDF from eXi. The network layout on page 8 was especially helpful. It didn’t necessarily answer all of my questions, but it at least got me investigating the possibility that my RPC was in the wrong class!

can u show us how u fixed it?

Hey Elea!

I fixed my issue by shifting some of my code into my game’s PlayerController class, which allowed my Remote Procedure Call (RPC) to work. Basically, my problem was that I was trying to have the GameInstance class send a call from the client to the server, but the GameInstance doesn’t work that way - my event was trying to run on the client despite being set to “Run on Server.”

Is there anything in particular you could use a hand figuring out? If you need to know which classes support replication, check out the PDF I linked from eXi (and try to add some logging so that you can see if you code happens on the client or server - having logging helped a lot). If you want to know more about launching a session and connecting to it, look at the blueprints I included in the original question. Most of that didn’t have to change - I just had to make sure my RPCs went through the PlayerController instead of just doing them all in the GameInstance where I had them originally.

Let me know if there are any specific gaps I can help fill in for you, and I’ll do what I can!