Paul Marsh

May 29, 2021

3 min read

Synchronizing player bullets…?

In my previous articles and video I demonstrated how to synchronize the enemy between the co-op players. Essentially it is about the Server using MLAPI Network Object and Network Transform.

Simplified Enemy Network Sequences

This works well for the enemy because the majority of the logic (firing, moving, etc.) is all held within the server and then distributed to the clients. However, player logic is different. The clients receive the player’s input and move the local player. This is then synced back to the server and distributed to the other players.

Simplified Player Movement Sync

The player movement requires more network use and therefore introduces more lag. Will this cause a performance problem to the way the sync occurs for when the player shoots?

Player 2 shot delta

When Player 1 shoots the performance is still pretty good. The view of Player 1 for Player 2 remains in sync. However, when Player 2 moves and shoots you can see a noticeable lag. This is because Player 2 is moving faster than the sync sequence of the bullet spawning on the server and then syncing back to Player 2’s client. It might not be too bad for many situations but for a shooter like Xevious it will probably mean the player will be hit by close-shave enemy collisions when they should have shot the enemy. Equally they will incorrectly shoot enemies that are offset from their current positions. It just is not good enough.

Sync the action not the result

The experiment to try and solve this problems changes from syncing the bullets to syncing the trigger of creating the bullets, i.e. sync the fire event rather than the resulting bullets.

Simplified Fire Event Sync

When a player fires they tell the server that a fire event has occurred and they stop processing. The server receives the message and instructs all the clients with representations of that player that they have fired. In Xevious’ case this means that the representation of Player 1’s ship is firing on all of the clients. Each client then creates a local version of the bullet. I.e. the resulting bullet on client 2 has no association with the resulting bullet on client 1. Therefore they will be out of sync with each other, but it should mean that visually there will not be any lag in the shot positioning.

It works, there is no perceived lag (network performance allowing). However, we have traded performance for a lack of synchronization. When a bullet on Client 1 hits something, what happens to the bullet on Client 2? I suspect that the trick is the Server must create an associative Id for the fire event and assign it to the bullet. That way each bullet now has a sync relationship, all be it a manual one. When a bullet hits something it informs the Server who in turn informs the clients.

What next?

Will the bullet ‘hit sync’ method work? What happens when the bullet from each client hits the same enemy, or potentially different enemies?