This article is an overview of how a multiplayer game written in LiveCode works, and examines the specifics of handling the login process.
How easy is it to make a multi-player game with LiveCode Server? As an experiment, I started with a classic Stock Market game which is a simple single player game that simulates the trading of stocks at a stock market. The prices rise and fall and you try to increase the value of your assets by buying and selling the stocks. Hopefully buying when the price is low, and watching the value increase as the price goes up. Then selling before the prices inevitably fall again.
The stack for Stock Market is here. It is single stack with a couple of cards. Nothing very complicated. But how to turn it into a multi-player game?
With LiveCode are the two main ways to approach such a conversion.
- Add code to the existing stack to talk to a "back-end" database on a server.
- Convert the entire program to LiveCode Server so all code runs remotely.
The first approach of extending the existing stack to include code to talk to a server still requires writing some LiveCode on the server-side, but overall much less code needs to be changed. It could be distributed as a standalone and the game could run on any platform LiveCode supports, or it could be supplied as a stack requiring LiveCode to be installed to run.
With the second approach, converting to run completely on a server, more work is required to make a new interface and change the code for the different environment. On the upside, it would run from any browser without extra files to distribute. This allows for easier updating of the program when changes are required.
Once the completely server-side approach was chosen, the basic organisation needed to be worked out. As a chart, the basic flow is like this.
The complete code of Stock Trader is too long to examine here in detail, but as a multiplayer game some form of login is required and since this is not part of the single player version, it will be interesting to examine it here.
Maintaining the session
Keeping a player logged into an online game (or any website) requires some way of keeping the login valid across each page refresh. This is usually called keeping state or session data. To keep a login active, or any information that must persist when the web page changes, there are 4 general techniques.
- GET parameters in the query
- Hidden fields on a form for POST data
- Session variables
The first two methods don't require cookies and are suitable for many applications. In the Stock Trader game, two hidden fields are added to the HTML form to keep track of the login.
When a player successfully logs in with a valid password, a "token" is generated. The token is a big number that is difficult for an imposter to guess so she can play without a valid login. This token and the user name is passed and maintained on the web page as hidden text fields.
Below are the steps of the login process.
- Player enters a name and password in browser and clicks Submit.
- Server gets the name and password as POST data.
- Server gets a database record that matches the player name.
- The entered password is hashed and compared with the password field in database record.
- If the passwords match, generate a random number for the token and store it in the database record.
- Server creates a HTML form with the name and token as hidden fields and return the form with the page to browser.
- Browser displays the form with the hidden fields.
put "SELECT user_password FROM stockuser WHERE user_name = '" & \
$_POST["name"] & "'" into sqlQuery
put revDataFromQuery(comma,cr,pDBID,sqlQuery) into buffer
if passwordHash($_POST["password"]) = buffer then
put $_POST["name"] into username
put random(1000000000) into usertoken
put "UPDATE stockuser SET user_token = " & usertoken & \
" WHERE user_name = '" & username & "'" into sqlQuery
The username and usertoken are the variables that store the name and token that are later substituted into the HTML form.
A little SQL
The schema of the SQL database table that works with this code is:
CREATE TABLE stockuser(
There are other fields in the table related to the stock prices, but these are not shown here.
The password is not stored as plain text but as a "hash". This means the password is put into a function that returns what appears to be a random and unique string, that is based on the password. So the actual password is not actually stored anywhere. The function below is used and returns a string no longer than 40 characters to store in the user_password field.
function passwordHash pPassword
When the user logs in, the entered password is put into the same hash function. If the resulting hash matches what is stored in the player data record, then the correct password has been entered. Then a new random token is put into the player data.
The HTML form that is part of the main interface has two hidden fields so the name and token are present every time the web page refreshes. Here is an example of this part of the form. The two values shown here are examples generated from the code above and the values from the username and usertoken variables.
<form action="index.lc" method="POST">
<input type="hidden" name="username" value="scott" />
<input type="hidden" name="usertoken" value="545248391" />
These hidden fields allow the login to be persistent as long as the page is open in the browser. Each time the player submits the form, these fields are checked to make sure the token is correct. Closing the browser window loses the information and the player needs to login again. A similar technique could be used with cookies, but by using this technique there is no need to warn the player about cookies being stored in the browser.
Handling the login process and keeping a session active is just the beginning of making a Multi-Player Online Game like Stock Trader. It is a basic foundation and getting it working is important before even thinking about the rest of the actual game and the gameplay. You can examine the rest of the Stock Trader code here.
Or for more fun you can register and play the game.