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!
