Mobile clients - performance suggestions?

Started by
21 comments, last by lerno 11 years, 11 months ago
I think the maximum is like 5 times a second, when the user tries to walk as fast as possible.[/quote]

So I move forward. Assuming no packets arrive during next second, will I experience jitter or lag, or will I move smoothly?

I really hope that each move doesn't wait for confirmation until it starts showing the movement. That doesn't work even on low latency wired networks.

This is unrelated to quality of network - I should not notice 1 second long absence of communication, underlying engine must deal with it. That is the first problem to solve. On desktop/wired networks, one can go as low as 125ms-400ms (depending on distance to peer), but mobile should really tolerate 1 second, perhaps much more, especially if working on twitch/interactive things.

Ideally, unless doing something CS-like, which isn't really viable directly on unreliable networks, client should ideally tolerate 5 seconds jitter and compensate the way interaction is done.

Mobile networks aren't a single thing. There are dozens or so variations on how data moves, then there's carriers, different wifi issues and whatnot.
Advertisement

I think the maximum is like 5 times a second, when the user tries to walk as fast as possible.


So I move forward. Assuming no packets arrive during next second, will I experience jitter or lag, or will I move smoothly?
I really hope that each move doesn't wait for confirmation until it starts showing the movement. That doesn't work even on low latency wired networks.
[/quote]

In my particular case:

Since we're walking around on a 2D map and there is fog-of-war and the client is not trusted with that map data until that fog-of-war is cleared, there is a limitation.

My idea is simply to move the map forward, then fade in the revealed areas. This will give me the whole movement animation to hide any lag. There would be a delay on the reveal until the result comes back though.

In the case the movement actually was refused, the map could drift back to the original position as soon as possible, creating the illusion of bouncing back off some elastic boundary.

Other situations in the game must incorporate similar animations to cover up the lag.
the client is not trusted[/quote]

You're on an iPhone. Just dump the whole map and use different servers for jailbroken clients.

There would be a delay on the reveal until the result comes back though.[/quote]

Delay is a bad choice here, I personally find this type of map generation very distracting, especially if it's not temporary, such as Minecraft starting up and generating/loading chunks. Jitter is more annoying than lag. If reveal takes consistent 2 seconds it's better than if it's taking 250-2500ms.

Send the map in chunks, keep enough locally to cover 5 seconds or movement if covering for 1-2 seconds of lag.

For the rest, such as units, use the usual observer/LOS method, where only visible/in-range units are updated.

It's precisely the type of design compromise that needs to be made. Pixel-perfect information hiding simply doesn't work well over network. Unless you're Starcraft, but that's a different story altogether and maphacks are detected serverside.

the client is not trusted

You're on an iPhone. Just dump the whole map and use different servers for jailbroken clients.
[/quote]

Sadly I feel it's not applicable for the game:

Think a multiplayer RPG with strategy elements. You "reveal" the 3x3 grid where you stand. You only see players on the particular tile you're standing on. Player have actions that cause them to alter the map. For the gameplay it is essential that map info does not leak. Clients are not intended to be limited to iPhone/iPad.

During a game session, you typically make around 60 on-map movements. Aside from movement, there are a bunch of other actions.

I feel speculative response is very hard to do, and it's not like it's an action game where you constantly feed updates.

I made a client-server video poker game based on HTTP. When drawing/changing cards, there was a drawing animation as the new cards were dealt, followed by the cards turning (revealing themselves). If there still was a wait after 1 second after the animation, I put up a "Waiting for response..."-spinner. Even with each request sending a new connect, I only ever saw that spinner when having a really poor connection, and then only occasionally.

Besides, does it need to feel jittery? Always animated gliding movement forward (same pace regardless of response), only the delay in the soft fade-in and update of present players would reveal connection problems.
During a game session, you typically make around 60 on-map movements.[/quote]
I think the maximum is like 5 times a second, when the user tries to walk as fast as possible.[/quote]

Is a game session 12 seconds long?
---

As for lag and jitter, here's an example. I remember it only because on-move lag was so annoying I consider it to be broken. it's done for same reason, but it ends up terribly distracting.

Maybe it's not a problem, considering it's a typical pay-for-action type of game, but for me it's simply broken.


Is smooth experience worth it? It's rarely mentioned and 10/10 managers agree one optimizes last.

Yet it's interesting to see that even in developers circles, smooth interfaces to get comments like: "it's so fast" or "it's so smooth". IMHO, it plays a factor. Smoothness was one of types of comments on the feeling of iPad, even though there is no real hardware behind it and no magic, just ensuring response rates are faster than in alternatives. And for same reason, Java was always called slow, even when it wasn't,

To me, it matters. Whether it's worth spending effort on that is another question.

During a game session, you typically make around 60 on-map movements.
I think the maximum is like 5 times a second, when the user tries to walk as fast as possible.[/quote]

Is a game session 12 seconds long?
[/quote]

Like your example, movement is something done occasionally, in bursts. A game session will probably tick in at less than 5 minutes though.

As for lag and jitter, here's an example. I remember it only because on-move lag was so annoying I consider it to be broken. it's done for same reason, but it ends up terribly distracting.[/quote]

  1. There are two reasons your example might feel slow: The movement uses ease in-out, which is slow in the beginning and end. This is nice for animations that are supposed to feel "gentle", but gives a feeling of sluggishness.
  2. I also strongly suspect that the game performs a new connect every time you move. I.e. you're seeing the latency of TCP connect + request.


I believe simply patching two things would change the your of that game: move the animation to linear or possibly ease-out and send requests on an established socket.


To me, it matters. Whether it's worth spending effort on that is another question.
[/quote]

I too believe it is important.

2) Switch to UDP. When packets get there, they get there, and you don't have to wait for earlier packets to get later packets. The link layer may re-transmit and re-order packets; the easiest thing to do is to number each packet and drop any packet that has a lower number than the previously received highest-numbered packet. The draw-back is that, well, packets will be dropped!


I did a little experimenting, setting up a rudimentary UDP and TCP echo servers. I then used my iPhone to ping those servers.

Setup:

(Internet) - ADSL - Wireless Router - Computer (connected using ethernet to the router)
iPhone with WiFi/3G sending a single 5 byte packet and measuring the time it takes to come back.
TCP_NODELAY on both server and client.

- With iPhone on the wireless router, UDP/TCP both gives me a roundtrip of 50 ms. So that's just over WiFi directly to my computer.
- Second test was with 3G. The wireless router as a public IP which is forwarded to my computer, again identical results with UDP/TCP - both running between 200 and 500 ms.

(Testing the same thing in the simulator on the same computer gives 2-3 ms, so there shouldn't be anything wrong with the test code)

Why is UDP giving me the same results as TCP here?
Why is UDP giving me the same results as TCP here?[/quote]

Data travels at same speed, so regardless of protocol, it will take the same time.

If there is packet loss, then TCP will try to recover lost packets using a standardized algorithm. This algorithm requires that no data may be sent to application, regardless of whether it has arrived or not, until previous missing packets are recovered or connection is closed.

UDP leaves recovery implementation to you, always delivering individual packets as they arrive (or don't).

If there is no packet loss and route is not saturated, both protocols behave effectively the same and achieve same ping times.


Apparently, in your test, no packets were lost, at least not during the test.


UDP is not faster (ignoring a few bytes of less overhead). They differ in error handling and throttling due to route saturation. UDP may be used to implement an algorithm which handles those two cases in a way that is better suited to the needs of application.

Why is UDP giving me the same results as TCP here?[/quote]
Data travels at same speed, so regardless of protocol, it will take the same time.
[/quote]

So TCP is not hampered by its Ack, esp since I used TCP_NODELAY?

But then why did hplus0603 suggest UDP?

If there is no packet loss and route is not saturated, both protocols behave effectively the same and achieve same ping times.
Apparently, in your test, no packets were lost, at least not during the test.
[/quote]

Well actually, I did have one case of aberrant TCP echo (1000 ms) and one occasion where the UDP packet was lost...
In TCP, once you drop a packet, any newer, un-dropped packets, will be delayed in the kernel, not delivered to you, until the dropped packet has been detected and re-sent. This causes burstiness.

In UDP, any packet that makes it through, gets delivered, and any packet that doesn't, doesn't.

The "speed" is the same, but the "latency" or "jitter" for game use cases that can stand dropped packets is higher for TCP and UDP.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement