WebGL WebSockets too slow for twitch-based realtime multiplayer?

Options
Hello! First post here and first PUN project.

I'm working on a tech demo in Unity WebGL that uses PUN for realtime multiplayer. Think of it as a 2-4 player game of "tag", where the person who is "it" holds a bomb. When they collide with another player, the player with the bomb tells an RPC to fire from a ScenePhotonView that lets all the players' local clients know that the bomb has been passed. At the end of a round, the bomb explodes (another RPC) and the player holding it is eliminated.

This all worked wonderfully in standalone builds because UDP was available and works best (from what I understand) for twitch-based realtime multiplayer. However, now having to use WebSockets with the WebGL build, I have two big issues:
  1. The bomb passing via RPC is so slow that it often looks like no collision between players happened at all and that the bomb just randomly jumped to another player.
  2. My "predictive" movement code for each player behaves very strangely and often puts networked players in the wrong position on a local client, presumably because of how slowly the messages are being sent/received in OnPhotonSerializeView.
Here's my code for bomb passing in the ScenePhotonView:
public void PassBomb(int playerWhoGetsBomb)//called by the local player who had the bomb and is now passing it { scenePhotonView.RPC ("SetNetworkedBomb",PhotonTargets.AllViaServer,playerWhoGetsBomb); } [PunRPC] void SetNetworkedBomb(int playerWhoGetsBomb) { ... /*code exists here to determine who the new bomb carrier is (chosenPlayer) and grab their gameObject*/ chosenPlayer.GetComponent<PlayerControl>().SetBomb(bomb);//reparents the bomb to the new player }

And here's my code for networked player movement:
// Update is called once per frame void Update() { if (!photonView.isMine)//if this isn't my character, continuously update this opponent's position on screen. { syncTime += Time.deltaTime; GetComponent<Rigidbody>().position = Vector3.Lerp(syncStartPosition, syncEndPosition, syncTime / syncDelay); } } void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.isWriting) { stream.SendNext (GetComponent<Rigidbody>().position); stream.SendNext (GetComponent<Rigidbody>().velocity); } else { Vector3 syncPosition = (Vector3)stream.ReceiveNext (); Vector3 syncVelocity = (Vector3)stream.ReceiveNext (); syncTime = 0f; syncDelay = Time.time - lastSynchronizationTime; lastSynchronizationTime = Time.time; syncEndPosition = syncPosition + syncVelocity * syncDelay; syncStartPosition = GetComponent<Rigidbody>().position; } }

I'd love to know if I'm doing something wrong for a game like this or if there's a better way to sync everything up! It all worked great via UDP in standalone builds, but WebSockets in the WebGL build make it almost unplayable because of the latency in movement and bomb passing. I do use PhotonTargets.AllViaServer on purpose which I know slows down the local player's bomb pass, but the bigger problem is when they receive the bomb from another player seemingly without touching them because networked positions are so far behind.

Would tracking the bomb holder via OnPhotonSerializeView make it faster? Should I avoid predictive movement code because of WebSockets' slow communication speeds, or can my code be adjusted? Maybe the bomb being a local non-networked object on every client's view is part of the issue, even though it's mainly a static object that just gets reparented when player-to-player collisions happen?

Insight would be amazing here! Thank you!

Comments

  • So, there's no way to hide the lag in WebSockets and improve the quality of the experience? It's borderline broken because of the latency introduced with WebSockets, which is super unfortunate...surely there's something I'm missing, because this would be an issue for ALL realtime twitchy multiplayer WebGL games.
  • vadim
    Options
    Websocket lag is technical limitation we can't overcome, You may use standard techniques for lag compensation like position prediction (that is used in your code i believe). But at least remote user input will remain laggy.
    Do yo know any websockets-based titles which give experience good enough for this type of games?
  • Yeah unfortunately the issue isn't with user movement so much as it is with letting everyone know who has the bomb in a reasonable amount of time. Because of the lag, a lot of times it looks like the bomb just got randomly passed to another player without a collision between players to trigger the pass.

    It looks like some folks have taken a stab at WebRTC/UDP in WebGL, particularly in Unity, if you want to have a look and see if it's something that could be incorporated into Photon in the future:

    http://forum.unity3d.com/threads/realtime-mutiplayer-games-in-webgl-using-webrtc-udp.350737/

    As it stands now, our demo won't work well using WebSockets in WebGL builds, even though it worked great using UDP on standalone builds.
  • vadim
    Options
    We are aware of WebRTC but did not experimented with it yet. I think it worth a try.
    Thanks for the link.