Unreal MMO Development with Yaz

28. UE MMO – how to synchronize players appearance

In the previous post we’ve looked at synchronizing the nearby players motion on our client.

This means that we could see the nearby players move about as we expect, however their appearance was not synchronized between the clients – this is what we’ll focus on achieving in this post.

This is actually not too difficult to achieve because we will be leveraging a lot of pre-existing functionality.

The main things that we have to do is:

Synchronize nearby player appearance

Graph for synchronising appearance

First thing – I added a new graph for synchronizing the nearby players appearance information and renamed the other to specifically cover only motion.

As the name suggests, this graph will be responsible for synchronizing the nearby proxy character appearance data.

First let’s add an entry point for this graph.

This function will run asynchronously – we want to keep the logic separate from others to avoid making any single graph too complicated.

We also make it async to avoid any single call becoming ‘too heavy’. For instance, the motion needs to be synchronized almost real-time, however appearance information doesn’t change as often, so its ok to make it happen less often. We can reduce load quite significantly by splitting this up (though bear in mind any additional HTTP call also has a relatively high overhead).

Next, let’s see what we’re actually trying to get every 0.5 seconds.

Here we see we make a GET request to: http://localhost:8081/player/characters?names=character1,character2

The request has url params for names, which will contain comma separated name values for characters we’re interested to get information of.

The response contains accountCharacters which includes the appearance information that we care about.

Let’s see how we make this call in UE:

We can see that we’re using the VaRest plugin in order to create a Json GET request here.

The URL is generated via a helper method – it’s time we start using refactored function calls to generate them.

The helper method is:

The input is an array of strings, in our case it’s an array of keys from NearbyPlayersData where the keys are the character names.

We can use the join string array function in order to nearly put those names together in CSV format.

The host is also refactored to make it easier to change in future, when we will push this to production.

After getting the result from the API call, we want to process it.

Let’s cover what we’re doing here:

  1. Get the account character array information from response
  2. Convert to AccountCharacter struct that we can use in our BP
  3. Update the NearbyPlayersData with the appearance information
  4. Apply the appearance data onto the proxy characters

1 – We saw that the response contained an array called accountCharacters – so we pull it from the payload.

For extra visibility, here’s the expected JSON payload again, notice the accountCharacters object, as well as the appearanceInfo that we ultimately want.

2 – We already covered the ConvertToAccountCharacterResponse function before (part of create/select character widget screens), but here are the helper methods just in case:

3 – Updating the nearby players data struct.

Remember that the variable contains a map of player name as key and Character data as value structure.

The definition of CharacterData is:

which includes AccountCharacter object, which is exactly what we’re pulling.

So once we’ve pulled the AccountCharacter data – we update the definition inside the NearbyPlayersData variable, using the name that’s inside the AccountCharacter as the key.

It can sound confusing so here’s breakdown:

First, get the name from account character and use that to find the nearby player data relevant to this account character.

Next, set the members of CharacterData – here we’re specifically updating the AccountCharacter that we’ve just obtained.

Finally, ADD it back into the map, using the name as the key.

This is because when we updated the value, we updated a copy of the value – if there’s a way to update reference of the value, we would not need to add it back.

4 – applying this appearance information onto the proxies.

Now that we’ve updated the Nearby Players Data struct, we can iterate over each one, and update the proxy characters appearance information and tell each one to Resolve All Appearance.

The resolver was covered part of create character screen post.

Final step is to add an entry point

I added mine to the SynchroniseMotion part of setting up websocket.

It can exist in constructor instead or something like ‘event begin play’.

And that’s it!

Testing

Now, simply start the game, select two characters and enter the game.

You will find that we will re-sync character appearance every 0.5 seconds!

Further improvements?

Many as usual, one big one for instance is to make the resolve character appearance more efficient. Specifically, only start resolving when there’s a noticed change in appearance. Currently it will try applying all appearance information even if nothing’s changed.

Exit mobile version