7 min read
.
on Nov 12, 2015
In this guest post, Marc Nitzsche shares his experience building a realtime, live audience participation voting application for a game show.

This is a guest post from Marc Nitzsche, a student from Hohen Neuendorf, a small town next to Berlin. He wants to figure out how everything works and will become an astronaut. He likes looking at perfectly designed websites and playing the piano.


11017024_1567464963525279_5373789315662933229_nIn Germany, we have a game show called “Schlag den Raab?” (“Beat the Raab?”), where a candidate plays up to 15 games to win a prize of more than €500,000. If the candidate loses, the jackpot gets even bigger. The games are diverse, including games of sport, knowledge or dexterity.

Using the show as inspiration, myself and a group of students made our own version. We called it “Schlag den Paul?” or in English “Beat the Paul?” We ran the show for over three years in a small school hall for 200 spectators. Growing increasingly popular, we developed a new concept and called it “Wer besiegt Paul?” (“Who defeats Paul?”).

This year we were proud to rerun the show with different games. But we had a plan: We wanted to make the whole experience more immersive. So we thought about creating a live audience participation game. We wanted to include the audience. And what better way to make our experience immersive then to utilize realtime data streaming to an audience armed with smartphones.

For example, one of our games is an estimation game, where questions like "how much does it weight?" or "how many of those people are vegetarians?" Instead of the users in the audience guessing silently to themselves, they have the opportunity to participate. In order to achieve this, we had to build a realtime app for any number of users in the audience to participate, and stream results to a live scoreboard.

12063456_1666381490300292_5019064609193772687_n

Building the Interactive, Realtime App

Our plan was to have every visitor who wants to take part register on a page. They should use only their first and last name. After that, there should be a waiting screen until the question appears on the big screen in front of them. Then they have 30 seconds to answer, together with Paul and the candidate. After answering (or after time is up) they should see another screen that says that the user should wait. At the end, there should be a scoreboard that lists the top ten participants.

Initial Challenges

We had a number of initial issues. First, we had already written another program to control the views (the content) on the big screen (e.g. playing a video or displaying the program that shows the scores). The system had to work autonomously and had to be controlled by hand.

Likewise, when you have a lot of users, there might be problems with the radio cell or the data plan of the user. And we had to keep in mind that the server might crash if there are so many people (I have to admit, I’ve never had that many users. That means that I was not able to know what to expect).

Because we have a live situation, the user should only have to load the page once. And, if possible, everything should be realtime.

12189068_1666287910309650_1381109052999434515_n

The Need for Realtime Data Streaming

In an effort to revitalize the project and remove the manual commitments, I wondered what kinds of web technologies I could use. I hadn't done anything like this before, and the only server language I was comfortable with was PHP, together with Laravel. Because my application had to be realtime, I wanted to use Websockets, but had no experience implementing a Websockets application. How would I build a realtime backend infrastructure, and how would it work with Laravel?

I started searching the web for other options. First I found with Ratchet, a library for PHP-WebSockets. Then I came across Socket.IO. Everything they wrote looked promising and I looked around how to use it with my PHP framework. There was a way to use it together with Redis, a Key/Value-Database that had a Publish/Subscribe-model you could use together with Laravel. I tried to implement it but it seemed not to work. And I’ve worried about the workload on my server.

After that I browsed the web and found PubNub. It seemed to me like Socket.IO, just without having to set up my server. They offered a ton of SDKs, even for PHP. And the web even offered some packages for Laravel. However, I began thinking about Node.js. It seemed much easier to implement all the realtime-logic in Node, while login and managing the points could stay where it was - in Laravel. I only had to connect the database to Node.js.

Combining Node.js, Laravel, and PubNub

My application now consists out of two parts: Laravel and Node.js.

I used Laravel for routing, authenticating and database-management, like giving points. Everything realtime was implemented in Node.js. Node.js processed the user submissions, validated them and stored them into the database. It was also responsible for sending data back to users.

PubNub

I used PubNub for controlling the view for user and scoreboard, transmitting the guesses and sending data back to the user (eg. their rank).

One of my most beloved features is the “Refiningmethod”. If there is a user who has not used his real name, but something like “I hate this show” while registering, then his name will get refined. We can’t obviously show those names on the big screen, so his alias would be, for example, “Gigantic Parrotgiraffe” or “Adventurous Hedgehogflamingo” (this sounds funny in German). Those names are randomly generated, they consist of an adjective and two different animal-names. Still, I have to check every name in the top ten before showing the scoreboard and press a button if one is not.

Rating the User Submissions

The most interesting part of the whole application is the algorithm for rating the guesses. Trust me, it caused quite a headache for a long time. Imagine, one round is over and no user is able to make a new guess. After inserting the data into a form by me (which round was played and what is the final result), several things happen:

  1. Check if the round was already rated by this algorithm before
  2. Save the final result in the database, as well as the so-called global-point-index (GPI), which is 0 for the beginning
  3. Get the magnitude for each user guess and save it
  4. The user with the lowest magnitude gets one point, then the one with the second-lowest two points, etc.
  5. If two users or more have the same magnitude they all get n points, the one that follows gets n + (amount of users with n points) points
  6. The GPI gets updated every time n increases (GPI = n)
  7. If somebody joins the game later (-> has not participated at all) he gets the GPI + 1 for each game
  8. If somebody does not participate in one particular game but in all the others he gets GPI + 1 points
  9. I have to manually send the ranks to the users and refresh the scoreboard (this means: I have to press a button)

Example: There are 5 participants. The Magnitudes are ordered in ascending order. Now everybody is getting their points. Because there are 5 users, there should be (not in every case!) a GPI of 5:

ID
Magnitude
Points
1
11
1
2
12
2
3
12
2
4
19
5
5
15
4

First, saved the GPI to the database. This is not needed because you could just look for the guess with the most points and deduce the GPI from that. Second, we save the magnitude to the database. This could be calculated if needed as well. But, because the program doesn’t need a non-redundant database, so I kept it like this. This would be one of the things that could be improved.

Another aspect I should improve in the future is security. First, every user got the PubNub keys for both subscribing and publishing messages. So, if one of these users wants to cause a ruckus, they could just send as many messages as he like, to every channel he likes. Because we are in a live show and nobody had the ability to check the site earlier or with something other than a smartphone, that was not a problem. But of course, if you want to have a working and secure application you should use a feature like PubNub Access Manager.

Wrapping Up

For me, the show was a huge success. Not only were a lot of the visitors (and me) surprised that everything worked out that nicely, I have also acquired some new skills concerning PHP and Node.ks. And I am finally able to say, that I’ve developing my first real (and working!) application.

I want to thank PubNub for supporting me and “Wer besiegt Paul?”. Without them, I would not have been able to complete everything I’ve imagined the way I did it now. Thank you, PubNub!

More From PubNub