4

I'm currently building an interactive game which has a very special use case : The game is displayed on a giant screen on stage in a theatre, and the audience can play it with their smartphones (http://www.augmented-magic.com/)

My tools are :

  1. A desktop app made with Unity, displayed on stage
  2. A web server (RoR) who provides the javascript app to audience members

The game is :

  1. You can move a fireflie on you mobile screen, and see all the fireflies of the audience on the stage screen.
  2. That is all. I want to keep it simple for now

For my proof of concept, I had the following architecture :

  1. The web apps sends their own positions to the web server every 0.5ms (it's 500ms, sorry)
  2. The web server stores and updates all these positions (in memory, no database)
  3. The unity app asks the web server for all the positions every 0.5ms (500ms, again) and updates the game displayed on the stage screen accordingly

It worked well at first sight, but my tiny web server was on the knees when too many people played at the same time (which is really unfortunate for my kind of game).

So, I want to redesign this into :

  1. The web apps send their own positions directly to the Unity app, not the the web server
  2. The unity app is the real game server, storing and updating positions
  3. Yes, I like lists.

Now, here is my question : Would you communicate with TCP or UDP protocol between the JS in the web app and the unity game server ?

I'd like to know your thoughts :)

[EDIT] : I ended up creating a websocket server in my unity game with github.com/sta/websocket-sharp . Works very well

4

UDP vs TCP

UDP is lightweight, stateless, and lossy.

TCP is heavy, statefull, and robust.

UDP is best when transmission errors can be ignored. TCP is best when transmission errors need correction. Voice over IP uses UDP because of how time sensitive voice conversations are. It's better to just hear a hiccup and be back in sync then to ask for another copy of a lost packet and end up lagging further behind.

In your use case I'd hate to find myself stabbing at the phone trying to get it to move only to see it sporadically show my movements later in a burst. Keep up with me.

Frequency

Every 0.5ms (a tuning variable) is 2000Hz and frankly faster then most monitors 60Hz-120Hz refresh rate. Adjusting this may solve some of your problems. It should allow you to have about 20 times the people connected before the same problem shows up. Write your software so this number is decided in one place so you can adjust it easily to experiment with your real needs.

If you want to make a bigger impact then just 20 times as big, consider cutting down the overhead. Rather then continually transmitting one x and y packet, try transmitting a few of them in a burst. The duration of the burst will add to your lag but it will be consistent. Small enough and it will be barely perceptible.

This idea would work well with frame buffering. Rather then just have one frame being rendered at a time video games work on rendering multiple ones at a time and let them be consumed in order. If you have 10 frames buffered and a packet comes in with 10 sampled locations you render each to their buffered frames.

Doing all this takes your .5ms rate to 0.1s and means your audience can be 200 times as big. That might not be acceptable lag for some video games but it should work fine for fireflies.

Some people might be connected but not actually moving their firefly at the moment. Some unreliable savings can be gained by having their smartphones keep quiet until they have something useful to say.

UI

Your firefly game reminds me of a myth busters where they tried to burn a ship by having a crowd hold mirrors in the sun. The biggest problem they had was no one could tell whose reflection was whose. This meant they couldn't focus because they couldn't tell if they needed to move up, down, left, or right to be on target.

Consider giving out groups of colors. If I'm one green dot among hundreds I have no hope of following my dot. If I'm one of ten red dots I have a chance even if there are 90 other colors bouncing around. Assuming I'm not color blind (red/green is the most common). Good color choices should be able to minimize this impact.

Directly to the Unity app

You are basically making a server when you do this. You will need to listen on a port for users to connect.

Remember to clean up the old location before moving them to a new location if you keep them on screen even after they've stopped transmitting for the moment. If you do your statefull again and must remember to keep drawing them in place until they time out. A way to handle that is to make them keep their own state and transmit where they were before so you can use that to clean up the old location.

Or you can only draw when told to draw. This is simpler but now packet loss turns into firefly flicker.

  • Oh i meant every 500ms, not 0.5ms, sorry ^^' – Caillou Jun 5 '17 at 14:57
  • I already have the web app silent when not moving, not a problem ;) – Caillou Jun 5 '17 at 15:00
  • Thanks by the way ! Great answer with lots of tips. You advise tcp then ? – Caillou Jun 5 '17 at 15:00
  • I recommend trying both but like I already said, you care more about time then lost packets. See what UDP does. – candied_orange Jun 5 '17 at 15:22
  • Actually, it seems like UDP is not a possibility in Javascript. And the allowed TCP is actually WebSockets, with a heavy header and all... We'll see how it goes. – Caillou Jun 5 '17 at 20:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.