26. UE MMORPG: how to synchronize motion with a custom server

In this post we’re going to be synchronizing characters motion using a custom server.

Synchronise motion part 1

In the previous post, we’ve implemented the functionality to ‘login’ a player into the game world.

Therefore, its natural we want to make sure the character is synchronized with that game world and can potentially start interacting with other characters in game.

The server that’s used in this example can be found in Github here.

Ok first thing is that in this server implementation, we’ve used WebSockets to communicate with server. This is instead of HTTP protocol, as its with less delay. If you’re using a different server, check the implementation, because this is where it can be VERY different.

If you’re using HTTP protocol, you should use VaRest plugin for comms in UE. This allows you to send http requests easier.

I will be using WebSockets, so I will be using Blueprint WebSockets.

Once you install it to your engine, open up your project, then navigate to Edit -> Plugins

Find the plugin and enable it – you will need to restart UE after applying this change.

Enable Blueprint Websockets

Overview of what we need to do

Essentially, we need to be synchronizing our characters motion with the server. This will allow us to pop back into the same location when user logs out and also when there are other nearby players, we’ll be able to start drawing them on the map as well.

So, on our character blueprint we want to do the following:

  • Part of constructor, create websocket client
  • Configure ‘on connect’ and ‘on message’ events
  • Connect to the server
  • Construct motion messages
  • Send the motion information to server

Implementation

Ok let’s start at constructor, this is connected to the work we’ve done in the previous post, which was spawning the character on the map at the specified location and resolving the appearance.

First, I added a new graph to deal with this work, I called it SynchroniseMotion.

Create new graph to deal with synchronising motion

Let’s create a custom event which we’ll populate shortly, but we’ll reference from our constructor now.

Create Websocket custom event

With this event created in the SynchroniseMotion graph, we can now reference it inside our constructor:

Calling the new Create Websocket function from constructor

This is continuing off the logic that we’ve built in the constructor in previous post. But the previous post is not a pre-requisite to this one, so don’t worry if you don’t have those pieces.

Ok now let’s look at all the functionality/custom events that we needed to create to support the SynchroniseMotion graph.

First, I create a function to generate the server URL for me.

Create Websocket url

Depending on your requirement, this may just be a static string. For me, my URL requires me to set the map that the character is on and the character name.

Let’s cross reference with a POSTMAN request.

Postman request for synchronizing motion

We can see that the URL is set to: ws://localhost:8081/v1/player-motion/map1/character2.

So, the two variables are map and characterName – and that’s what you can see are being populated in the function.

Note that I’m obtaining this information from Game Instance (populated in the last post), but you can make those static for now if you like, to test.

Create Web Socket function is from the plugin – if you don’t have this available, double check that you’ve enabled the plugin.

Bind Connect custom event:

Bind Connect

This simply binds event to on connected – can be used to hook other actions. In this case, I will set Boolean for Websocket connected which will be pre-requisite in sending events to server.

Bind On Send

Bind On Send functionality

This simply prints out the message that’s sent – for now just helps with visibility, but again can be used to hook other events.

Set Update Timer

Set update timer functionality

Essentially when the websocket is connected, we want to start synchronizing all the motion between the client with the server.

The custom event for send does not have to be split from UpdateServer custom event, but I did so because I will move the logic around and I don’t want it to be muddled up.

Here we can see that every 0.05 seconds, we will send an update to the server, if the websocket is connected. It does this by:

  • update player motion struct, based off character pawn
  • construct motion json
  • convert json to string
  • send message with motion string

In the next post we will also be GETTING motion of nearby characters too – and we’ll update the screen with those results.

Let’s look into functionality for Update Player Motion.

Update Player Motion function

In this function, it looks busy, but its not too complicated – but it does some really fancy stuff.

Basically, we created a Motion structure and we’re populating it based on the motion of the character model.

The motion struct was introduced in the previous post, for reference it’s this:

Motion structure

Basically its:

  • Get Actor Location (x, y, z co-oridnates)
  • Get Actor Rotation pro tip – right click the ‘Return value’ and split struct pin
  • Get Actor Velocity (vx, vy, vz)
Right click Return value and click split struct pin to get pitch, roll, yaw

And once you got those values, just update the motion struct with that data.

construct motion Json

This is another helper method for converting a Structure object into JSON. It’s sad there’s no easy serializer available for this (if someone knows of one, please comment!).

Helper method for converting struct to Json

Note that this json is actually created from VaRest free plugin. We’re not actually using HTTP calls, but their implementation for json is very helpful.

It won’t be visible in below screenshot, but just for ‘overview’ – I go through each param in the struct and ‘set integer field’ or ‘set boolean field’ etc for each of the parameters.

Set relevant fields in json before returning

Ultimately, I put it into json only to convert it to a String:

Encode json to string

As that’s what the websocket tool expects.

And that’s it!

Once the messages are sent, we’re synchronising the motion with server.

Let’s test this and go over the findings.

Testing

Back to character selection screen, I am able to select the character and login as before.

Select my character and click login

Once I login, I will start seeing a bunch of messages sent to server, synchronizing motion of my character.

Messages are sent to server

If I move the character around, I can see all values are changing.

If they don’t, check your function on populating them, inside Update Player Motion.

Key here is that if I go to a new place, lets say this bridge.

Moving to new place

Then I close and restart the game, so again back to character select screen:

Back to character select screen

When I login, my character is back to the correct location!

Character inserted back into correct place

So, everything appears to be working as expected.

In the next post I will look to have 2 characters in the map and rendering both characters when they’re nearby.

3 Comments

Comments are closed