Building Browsergames: Creating the bank (PHP)

Earlier, we built a combat system with which players can fight monsters, and gain gold when they defeat those monsters. Today, we’re going to build a bank for them to put that gold into.

To begin with, we’ll add another link to our index page – this link will go to bank.php, the page that will handle all of the logic on that page.

16
	<p><a href='bank.php'>The Bank</a></p>

And now that the link is there, we’re going to actually create the page. As usual, we’ll start off with a basic template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
	<title>The Bank</title>
</head>
<body>
	<p>Welcome to the bank. You currently have <strong>{$inbank}</strong> gold in the bank, and <strong>{$gold}</strong> gold in hand.</p>
	<form action='bank.php' method='post'>
		<input type='text' name='amount' /><br />
		<input type='submit' name='action' value='Deposit' /> or 
		<input type='submit' name='action' value='Withdraw' />
	</form>
	<p><a href='index.php'>Back to main</a></p>
</body>
</html>

Even though players have a gold stat, they’re missing one: gold in the bank. So we’re going to add another stat to our database, so that we can keep track of how much gold the player currently has in the bank. Here’s the SQL you’ll need to run:

INSERT INTO stats(display_name,short_name) VALUES ('Gold In Bank','bankgc');

Now that that’s finished, we’ll write the starter code for our bank page. Because the amount of gold that a player has in the bank starts at 0, we won’t need to add any special code to auto-set it to anything.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
 
require_once 'smarty.php';
 
session_start();
 
require_once 'config.php';		// our database settings
require_once 'stats.php';
$conn = mysql_connect($dbhost,$dbuser,$dbpass)
	or die('Error connecting to mysql');
mysql_select_db($dbname);
// retrieve user ID
$query = sprintf("SELECT id FROM users WHERE UPPER(username) = UPPER('%s')",
			mysql_real_escape_string($_SESSION['username']));
$result = mysql_query($query);
list($userID) = mysql_fetch_row($result);
 
$smarty->assign('gold',getStat('gc',$userID));
$smarty->assign('inbank',getStat('bankgc',$userID));
$smarty->display('bank.tpl');
 
?>

Now, we can start writing the logic to handle what happens when a player presses one of the action buttons. We’re going to modify our template slightly, so that it can display two different messages – one for when a user deposits some gold, and one for when a user withdraws some gold:

7
8
9
10
11
12
	{if $deposited ne 0}
		<p>You deposited <strong>{$deposited}</strong> gold into your bank account. Your total in the bank is now <strong>{$inbank}</strong>.</p>
	{/if}
	{if $withdrawn ne 0}
		<p>You withdraw <strong>{$withdrawn}</strong> gold from your bank account. Your total gold in hand is now <strong>{$gold}</strong>.</p>
	{/if}

We’re also going to make a slight modification to the area users input the amount they want to put into the bank, and make it auto-focus:

14
15
16
17
18
19
20
21
		<input type='text' name='amount' id='amount' /><br />
		<input type='submit' name='action' value='Deposit' /> or 
		<input type='submit' name='action' value='Withdraw' />
	</form>
	<p><a href='index.php'>Back to main</a></p>
	<script type='text/javascript'>
		document.getElementById('amount').focus();
	</script>

Now that that’s finished, we can get to writing the code that handles all of the interactions on this page.

One of the things that always seems to get handled differently in browsergames is what they do when you enter a value they don’t expect into a textbox – like trying to deposit 200 gold when you only have 100, or just hitting enter without entering a value at all. Some games stop and tell you that you made a mistake, before forcing you to try again. Another approach that I’ve encountered is to just assume that something ‘weird’ means ‘use the maximum’ – so the game just quietly shifts your 200 into the 100 you have, and then tells you how much it deposited. I like the second option, so that’s how I will write my logic – but in your game you’re completely free to do whatever you want(and it shouldn’t be too hard to cusomize this code to display an error message if you need to):

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$gold = getStat('gc',$userID);
if($_POST) {
	$amount = $_POST['amount'];	
	if($_POST['action'] == 'Deposit') {
		if($amount > $gold || $amount == '') {
			// the user input something weird - assume the maximum
			$amount = $gold;	
		}
		setStat('gc',$userID,getStat('gc',$userID) - $amount);
		setStat('bankgc',$userID,getStat('bankgc',$userID)+$amount);
		$smarty->assign('deposited',$amount);
	} else {
		$bankGold = getStat('bankgc',$userID);
		if($amount > $bankGold || $amount == '') {
			// the user input something weird again - again, assume the maximum
			$amount = $bankGold;
		}
		setStat('gc',$userID,getStat('gc',$userID) + $amount);
		setStat('bankgc',$userID,getStat('bankgc',$userID)-$amount);
		$smarty->assign('withdrawn',$amount);
	}
}

And that’s really all there is to handling a deposit or a withdrawal within our simple banking system. We check to see what action the user is taking, and then we perform almost exactly the same operation – the only differences are the value that we’re testing our posted amount against, and whether we’re increasing or decreasing their gold in hand vs. gold in the bank. Finally, we assign a variable in each case that will display the amount that the user either deposited or withdrew. The code is so similar I’m sure it could be implemented in a little less repetitious format using references – but I’ll leave that as an exercise for you, the reader.

Here’s all the code for the bank in a single block:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
 
require_once 'smarty.php';
 
session_start();
 
require_once 'config.php';		// our database settings
require_once 'stats.php';
$conn = mysql_connect($dbhost,$dbuser,$dbpass)
	or die('Error connecting to mysql');
mysql_select_db($dbname);
// retrieve user ID
$query = sprintf("SELECT id FROM users WHERE UPPER(username) = UPPER('%s')",
			mysql_real_escape_string($_SESSION['username']));
$result = mysql_query($query);
list($userID) = mysql_fetch_row($result);
 
$gold = getStat('gc',$userID);
if($_POST) {
	$amount = $_POST['amount'];	
	if($_POST['action'] == 'Deposit') {
		if($amount > $gold || $amount == '') {
			// the user input something weird - assume the maximum
			$amount = $gold;	
		}
		setStat('gc',$userID,getStat('gc',$userID) - $amount);
		setStat('bankgc',$userID,getStat('bankgc',$userID)+$amount);
		$smarty->assign('deposited',$amount);
	} else {
		$bankGold = getStat('bankgc',$userID);
		if($amount > $bankGold || $amount == '') {
			// the user input something weird again - again, assume the maximum
			$amount = $bankGold;
		}
		setStat('gc',$userID,getStat('gc',$userID) + $amount);
		setStat('bankgc',$userID,getStat('bankgc',$userID)-$amount);
		$smarty->assign('withdrawn',$amount);
	}
}
 
$smarty->assign('gold',getStat('gc',$userID));
$smarty->assign('inbank',getStat('bankgc',$userID));
$smarty->display('bank.tpl');
 
?>

Wish there was more?

I'm considering writing an ebook - click here.

.

Luke is the primary editor of Building Browsergames, and has written a large portion of the articles that you read here. He generally has no idea what to say when asked to write about himself in the third person.

Friday, June 13th, 2008 buildingbrowsergames, code, php
  • Great tutorial . Very useful selection. I think to me it is useful and really It will be

    very useful for all. Thanks for sharing . Keep it up .

  • S Keilani

    Just do:

    $amount = abs($_POST['amount']);

    That would be one line of code done once :)

  • An easy way to fix it is to use PHP's abs() function to force the number to be positive :)

  • MrLollige

    Thanks mattias, that function is helpful!

  • Hi Mattias,

    Nice catch! I completely missed that that bug was there. I will post a fix shortly.

  • Hi, I just noticed something about your code. If the user is to enter a negative amount and deposit it, they would get more gold than they had in their hand and get a negative bank value.

    Just thought I'd point it out.

blog comments powered by Disqus

About

Building Browsergames is a blog about browsergames(also known as PBBG's). It's geared towards the beginner to intermediate developer who has an interest in building their own browsergame.

Sponsors

Got Something to Say?

Send an e-mail to luke@buildingbrowsergames.com, or get in touch through Twitter at http://twitter.com/bbrowsergames