<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Building Browsergames</title>
	<atom:link href="http://buildingbrowsergames.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://buildingbrowsergames.com</link>
	<description>Ever wanted to build a browsergame?</description>
	<pubDate>Fri, 25 Jul 2008 00:27:58 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Offline for a while</title>
		<link>http://buildingbrowsergames.com/2008/07/24/offline-for-a-while/</link>
		<comments>http://buildingbrowsergames.com/2008/07/24/offline-for-a-while/#comments</comments>
		<pubDate>Fri, 25 Jul 2008 00:27:58 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=103</guid>
		<description><![CDATA[Building Browsergames will be going offline for a few days - I&#8217;m going to be transferring the site(and all related files) to a new server.
<script type="text/javascript">SHARETHIS.addEntry({ title: "Offline for a while", url: "http://buildingbrowsergames.com/2008/07/24/offline-for-a-while/" });</script>]]></description>
			<content:encoded><![CDATA[<p>Building Browsergames will be going offline for a few days - I&#8217;m going to be transferring the site(and all related files) to a new server.</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Offline+for+a+while&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F24%2Foffline-for-a-while%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/24/offline-for-a-while/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Making it easy for your users to get in touch with you</title>
		<link>http://buildingbrowsergames.com/2008/07/24/making-it-easy-for-your-users-to-get-in-touch-with-you/</link>
		<comments>http://buildingbrowsergames.com/2008/07/24/making-it-easy-for-your-users-to-get-in-touch-with-you/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 14:00:54 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[publicrelations]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=101</guid>
		<description><![CDATA[As the editor of a site about browsergames, I tend to e-mail browsergame creators a lot. As a result, I&#8217;ve noticed that there are some things that I really like about the ways that certain games handle having users contact them, and some things I don&#8217;t like.
First off, make it easy to get in touch [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Making it easy for your users to get in touch with you", url: "http://buildingbrowsergames.com/2008/07/24/making-it-easy-for-your-users-to-get-in-touch-with-you/" });</script>]]></description>
			<content:encoded><![CDATA[<p>As the editor of a site about browsergames, I tend to e-mail browsergame creators a lot. As a result, I&#8217;ve noticed that there are some things that I really like about the ways that certain games handle having users contact them, and some things I don&#8217;t like.</p>
<p>First off, <strong>make it easy to get in touch with you!</strong> The users who are willing to go to the extra effort of getting in touch with you are the users that you want to listen to - they&#8217;re probably also your game&#8217;s biggest evangelists.</p>
<p>What does it take to make it easy for your users to get in touch with you? The answer might surprise you: <strong>not much</strong>. Here are a few ways to make it really easy for users to contact you:</p>
<ul>
<li>
<h2>Have a &#8216;Contact&#8217; Page</h2>
<p>This has to be the very first option that I look for when I&#8217;m looking to get in touch with the owners of a game. I scan their navigation, and look for the word &#8216;Contact&#8217; - or, if I can&#8217;t find that, &#8216;About&#8217;. Usually, one of those will lead me to either a form I can use to get in touch with the owners of the game, <strong>or</strong> an e-mail address that I can just send an e-mail directly to.</p>
</li>
<li>
<h2>Use IRC</h2>
<p>While this isn&#8217;t as applicable if you don&#8217;t have technically-savvy users, for a user who <strong>does</strong> know a thing or two, being available on IRC is always a bonus - a lot of things can get resolved faster via a quick chat than over e-mail. You can simply idle in a room dedicated to your game - and who knows, maybe the really dedicated players will start idling there too.</p>
</li>
<li>
<h2>Blog</h2>
<p>If you have a blog on your game&#8217;s site, leave comments enabled - you&#8217;d be surprised at how many users will leave you comments about any piece of your game that they like or don&#8217;t like - whether it&#8217;s relevant to the content of your blog post or not.</p>
</li>
<li>
<h2>Use Twitter</h2>
<p>One more option that is starting to gain a little more traction these days is <a href='http://twitter.com'>Twitter</a> - a micro-blogging service. The idea is that you would create a Twitter account for your game, and then use it to respond to any users on Twitter who are having the problem. This is <strong>just about</strong> as good as talking to the user on IRC, because if you&#8217;re both online at the same time you can have a quick chat about whatever&#8217;s on their mind. You can also use Twitter to market your game, by sending out tweets whenever you change something or a new version rolls out.</p>
</li>
</ul>
<p>These are just a few of the myriad ways that you can keep in touch with your users - what do you use?</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Making+it+easy+for+your+users+to+get+in+touch+with+you&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F24%2Fmaking-it-easy-for-your-users-to-get-in-touch-with-you%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/24/making-it-easy-for-your-users-to-get-in-touch-with-you/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Diary of a Browsergame: Planning out the templates</title>
		<link>http://buildingbrowsergames.com/2008/07/23/diary-of-a-browsergame-planning-out-the-templates/</link>
		<comments>http://buildingbrowsergames.com/2008/07/23/diary-of-a-browsergame-planning-out-the-templates/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 14:00:13 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[design]]></category>

		<category><![CDATA[diaryofabrowsergame]]></category>

		<category><![CDATA[templates]]></category>

		<category><![CDATA[workingtitle]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=99</guid>
		<description><![CDATA[Now that I&#8217;ve set up my database, it&#8217;s time to settle on a templating system, and decide on how I want my templates to work.
Working Title only has a few pages that will need to be displayed - according to Design 1.0, there are a total of 7 - Home, Design Document, Register, Login, Logout, [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Diary of a Browsergame: Planning out the templates", url: "http://buildingbrowsergames.com/2008/07/23/diary-of-a-browsergame-planning-out-the-templates/" });</script>]]></description>
			<content:encoded><![CDATA[<p>Now that I&#8217;ve <a href='http://buildingbrowsergames.com/2008/07/14/diary-of-a-browsergame-setting-up-the-database/'>set up my database</a>, it&#8217;s time to settle on a templating system, and decide on how I want my templates to work.</p>
<p>Working Title only has a few pages that will need to be displayed - according to <a href='http://buildingbrowsergames.com/workingtitle/design/1.0.html'>Design 1.0</a>, there are a total of 7 - Home, Design Document, Register, Login, Logout, Codex, and Play. This will make developing the templates very easy, as there are only a few that I need to build.</p>
<p>I&#8217;m going to use <a href='http://search.cpan.org/dist/HTML-Template/Template.pm'>HTML::Template</a> for my templating system, just like we have been in our <a href='http://buildingbrowsergames.com/category/buildingbrowsergames/perl/'>Perl-based browsergame tutorial</a>. However, my templating setup will be slightly different; I am planning on nesting two templates within each other. I&#8217;ll have a simple outer template which defines some of the global styles for all of the pages, and then another inner template that is populated with the information unique to the page(this is an example of applying DRY to my templates).</p>
<p>To that end, I&#8217;ve whipped up a quick outer template for Working Title, that will(for the moment) do what I need it to. There isn&#8217;t much to it, but you can take a look at it <a href='http://buildingbrowsergames.com/workingtitle/design/template-outer.html'>here</a>.</p>
<p>Is it a rough template? Yes. Will it change before Working title is done? Probably. But it&#8217;s enough to get me up and running, and free up my time to work on developing the rest of the game, instead of just working on the template.</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Diary+of+a+Browsergame%3A+Planning+out+the+templates&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F23%2Fdiary-of-a-browsergame-planning-out-the-templates%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/23/diary-of-a-browsergame-planning-out-the-templates/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Balancing your game: real-time or actions-based?</title>
		<link>http://buildingbrowsergames.com/2008/07/22/balancing-your-game-real-time-or-actions-based/</link>
		<comments>http://buildingbrowsergames.com/2008/07/22/balancing-your-game-real-time-or-actions-based/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 14:00:25 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=97</guid>
		<description><![CDATA[While you&#8217;re building your browsergame, there&#8217;s one important point to consider: balancing your game.
A lot of developers create browsergames without thinking about balancing them first - this usually tends to result in games that are released with some serious balance issues. Certain characters might be over-powered in comparison to others, and certain items might be [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Balancing your game: real-time or actions-based?", url: "http://buildingbrowsergames.com/2008/07/22/balancing-your-game-real-time-or-actions-based/" });</script>]]></description>
			<content:encoded><![CDATA[<p>While you&#8217;re building your browsergame, there&#8217;s one important point to consider: balancing your game.</p>
<p>A lot of developers create browsergames without thinking about balancing them first - this usually tends to result in games that are released with some serious balance issues. Certain characters might be over-powered in comparison to others, and certain items might be complete gamebreakers - things that make the game virtually unplayable for players without the item by comparison.</p>
<p>How will you solve the balance problem in your browsergame?</p>
<p>One approach that a lot of browsergame developers take is limiting users to a certain number of turns in a day - that way, a user who has all the time in the world and a user who can only sign in for 5 minutes each day can both remain relatively close to each other in terms of in-game performance.</p>
<p>While action-point/turn-based systems are a good way to keep your players a little more evenly matched, they don&#8217;t (unfortunately) fix balance problems - at best, all they can do is prolong the amount of time that it takes for a balance issue to appear.</p>
<p>Here&#8217;s an example: you run a small browsergame, with 5000 users who are active daily. Players can play the game in real-time, and at any given moment there are at least 200 players online at once, interacting with the game. In a weekly update, you push out a new sword that can only be found after defeating a particular boss monster. Unbeknownst to you, this sword in combination with the armor you released three weeks ago combine to form the most powerful combination in the game - capable of instantly killing any player who is attacked by a player using both of them.</p>
<p>In a real-time game, you&#8217;ll notice this issue fairly quickly - all of a sudden, a handful of players will be able to instantly defeat any other player. You&#8217;ll soon start to see complaints in your forums (if you have them), and you&#8217;ll be able to watch as more players find the item and begin to exploit the balancing issues present.</p>
<p>Now think of the same scenario, in the context of a turn-based game. Users get 25 turns per day, and it takes them 40 turns to get to the boss (if they don&#8217;t use turns, they stack up). It will be at least 2 days post-update for a user to get to the boss, let alone retrieve the sword - and if it takes them a full turn to attack a player, a user who <strong>just</strong> acquired the sword (assuming they had 50 turns saved up) will be able to instantly kill 10 players. Now, is the 10 players being instantly defeated by a single player a balance issue, or just a player who is that much stronger than 10 other players?</p>
<p>As you can see, there are pros and cons to either system. If you build a real-time system, there are more balance issues related to keeping casual and hardcore players even - but you will quickly find balance issues that have to do with gameplay features. In a turn-based system, there are far less problems keeping individual players balanced - but gameplay features can easily cause balance headaches that you won&#8217;t find for a long period of time.</p>
<p>So how will you balance your game? The answer is entirely up to you - although I would recommend setting your game up in a way that suits your development style. If you heavily test your changes before deploying them to a production environment, you can probably safely get away with a turn-based system - you&#8217;ll just need to make sure you thoroughly test all of your changes before you deploy them. If you&#8217;d rather have your players do the testing for you, and just fix balance issues as they come up - go for real-time. Either way, it&#8217;s your game - and the only important thing is recovering from balance issues when they <strong>do</strong> appear.</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Balancing+your+game%3A+real-time+or+actions-based%3F&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F22%2Fbalancing-your-game-real-time-or-actions-based%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/22/balancing-your-game-real-time-or-actions-based/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Important Design Choices</title>
		<link>http://buildingbrowsergames.com/2008/07/21/important-design-choices/</link>
		<comments>http://buildingbrowsergames.com/2008/07/21/important-design-choices/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 14:00:17 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[buildingbrowsergames]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=92</guid>
		<description><![CDATA[We&#8217;ve already built an items system for our game, in addition to writing code to retrieve our items. But one thing that we haven&#8217;t done yet is plan out what sorts of items there should be in our game.
Should there by usable items? Should players be allowed to have one weapon, two weapons, or one [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Important Design Choices", url: "http://buildingbrowsergames.com/2008/07/21/important-design-choices/" });</script>]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve already built an items system for our game, in addition to writing code to retrieve our items. But one thing that we haven&#8217;t done yet is plan out what sorts of items there should be in our game.</p>
<p>Should there by usable items? Should players be allowed to have one weapon, two weapons, or one melee weapon and one ranged weapon? How many armor slots should a player have?</p>
<p>These are all questions that need to be answered - and now&#8217;s your chance to! Please vote for what you&#8217;d prefer using the polls below:</p>
<div>
<div>
	<div class='democracy'>
		<strong class="poll-question">Should there be usable items in our game?</strong>
		<div class='dem-results'>
		<form action='http://buildingbrowsergames.com/blog/wp-content/plugins/democracy/democracy.php' onsubmit='return dem_Vote(this)'>
		<ul>
			<li>
					<input type='radio' id='dem-choice-13' value='13' name='dem_poll_4' />
					<label for='dem-choice-13'>Yes - consumables that heal the player</label>
			</li>
			<li>
					<input type='radio' id='dem-choice-14' value='14' name='dem_poll_4' />
					<label for='dem-choice-14'>Yes - consumables that perform actions on the player</label>
			</li>
			<li>
					<input type='radio' id='dem-choice-15' value='15' name='dem_poll_4' />
					<label for='dem-choice-15'>No</label>
			</li>
		</ul>
			<input type='hidden' name='dem_poll_id' value='4' />
			<input type='hidden' name='dem_action' value='vote' />
			<input type='submit' class='dem-vote-button' value='Vote' />
			<a href='/feed/?dem_action=view&amp;dem_poll_id=4' onclick='return dem_getVotes("http://buildingbrowsergames.com/blog/wp-content/plugins/democracy/democracy.php?dem_action=view&amp;dem_poll_id=4", this)' rel='nofollow' class='dem-vote-link'>View Results</a>
		</form>
		</div>
	</div></div>
</div>
<div>
<div>
	<div class='democracy'>
		<strong class="poll-question">How many weapons should a player be allowed to carry?</strong>
		<div class='dem-results'>
		<form action='http://buildingbrowsergames.com/blog/wp-content/plugins/democracy/democracy.php' onsubmit='return dem_Vote(this)'>
		<ul>
			<li>
					<input type='radio' id='dem-choice-9' value='9' name='dem_poll_2' />
					<label for='dem-choice-9'>Two, either type</label>
			</li>
			<li>
					<input type='radio' id='dem-choice-8' value='8' name='dem_poll_2' />
					<label for='dem-choice-8'>Two, both melee</label>
			</li>
			<li>
					<input type='radio' id='dem-choice-7' value='7' name='dem_poll_2' />
					<label for='dem-choice-7'>One melee, one ranged</label>
			</li>
			<li>
					<input type='radio' id='dem-choice-6' value='6' name='dem_poll_2' />
					<label for='dem-choice-6'>Just one</label>
			</li>
		</ul>
			<input type='hidden' name='dem_poll_id' value='2' />
			<input type='hidden' name='dem_action' value='vote' />
			<input type='submit' class='dem-vote-button' value='Vote' />
			<a href='/feed/?dem_action=view&amp;dem_poll_id=2' onclick='return dem_getVotes("http://buildingbrowsergames.com/blog/wp-content/plugins/democracy/democracy.php?dem_action=view&amp;dem_poll_id=2", this)' rel='nofollow' class='dem-vote-link'>View Results</a>
		</form>
		</div>
	</div></div>
</div>
<div>
<div>
	<div class='democracy'>
		<strong class="poll-question">How many armor slots should there be?</strong>
		<div class='dem-results'>
		<form action='http://buildingbrowsergames.com/blog/wp-content/plugins/democracy/democracy.php' onsubmit='return dem_Vote(this)'>
		<ul>
			<li>
					<input type='radio' id='dem-choice-10' value='10' name='dem_poll_3' />
					<label for='dem-choice-10'>One</label>
			</li>
			<li>
					<input type='radio' id='dem-choice-11' value='11' name='dem_poll_3' />
					<label for='dem-choice-11'>Three - head, torso, legs</label>
			</li>
			<li>
					<input type='radio' id='dem-choice-12' value='12' name='dem_poll_3' />
					<label for='dem-choice-12'>Five - head, torso, legs, right arm, left arm</label>
			</li>
		</ul>
			<input type='hidden' name='dem_poll_id' value='3' />
			<input type='hidden' name='dem_action' value='vote' />
			<input type='submit' class='dem-vote-button' value='Vote' />
			<a href='/feed/?dem_action=view&amp;dem_poll_id=3' onclick='return dem_getVotes("http://buildingbrowsergames.com/blog/wp-content/plugins/democracy/democracy.php?dem_action=view&amp;dem_poll_id=3", this)' rel='nofollow' class='dem-vote-link'>View Results</a>
		</form>
		</div>
	</div></div>
</div>
<p>If you&#8217;ve got a completely different idea, put it in the comments - I&#8217;m looking for any and all suggestions on where to take the game as it stands now.</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Important+Design+Choices&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F21%2Fimportant-design-choices%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/21/important-design-choices/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Using the &#8220;on-view&#8221; method instead of cron</title>
		<link>http://buildingbrowsergames.com/2008/07/18/using-the-on-view-method-instead-of-cron/</link>
		<comments>http://buildingbrowsergames.com/2008/07/18/using-the-on-view-method-instead-of-cron/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 14:00:49 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=88</guid>
		<description><![CDATA[bardic commented on the cron post from yesterday, and he said:

While crons are a good way to do such a task, they aren’t the best solution. For a game with a large DB a cron can take too long to cycle through the DB.

bardic is right, here - in any situation where you need to [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Using the &#8220;on-view&#8221; method instead of cron", url: "http://buildingbrowsergames.com/2008/07/18/using-the-on-view-method-instead-of-cron/" });</script>]]></description>
			<content:encoded><![CDATA[<p><a href='http://webgamedev.wordpress.com'>bardic</a> commented on the <a href='http://buildingbrowsergames.com/2008/07/17/simple-cron/'>cron post</a> from yesterday, and he said:</p>
<blockquote><p>
While crons are a good way to do such a task, they aren’t the best solution. For a game with a large DB a cron can take too long to cycle through the DB.
</p></blockquote>
<p>bardic is right, here - in any situation where you need to deal with large amounts of data, using cron is a little less than optimal. In that case, you&#8217;d want to implement something that bardic refers to as the &#8220;on-view&#8221; event - essentially, you store information about the time a command was last run, and you use that time to figure out when the command should run next.</p>
<p>Implementing this in your own database is a trivial change; all you need to do is add a timestamp to the table you need to track times for, and then compare it to the current time. Here&#8217;s what an example table might look like:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> actions <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	user_id int<span style="color: #66cc66;">,</span>
	energy int<span style="color: #66cc66;">,</span>
	last_updated timestamp<span style="color: #66cc66;">,</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>And then all you would need to do in your code is something like this, on every page an authenticated user visits(pseudocode):</p>

<div class="wp_syntax"><div class="code"><pre>last_time = get_last_update_time()<SEMI>
current_time = get_current_time()<SEMI>
if(current_time - last_time &gt;= tick_duration) {
	number_of_updates = int((current_time-last_time)/tick_duration)<SEMI>
	for(i = 0<SEMI> i &lt; number_of_updates<SEMI>i++) {
		update_energy_value()<SEMI>
	}
}</pre></div></div>

<p>And that would be essentially all you&#8217;d need to do - just check the last time a user&#8217;s information was updated, and then update it if it&#8217;s been longer than the amount of time you want to update a user&#8217;s stats in. Also, if you write your code in such a way that you can just pass in what to update the value with, you can reduce the overhead of using a <em>for()</em> loop as well:</p>

<div class="wp_syntax"><div class="code"><pre>	update_energy_value(update_amount * number_of_updates)<SEMI></pre></div></div>

<p>Now, this will allow you to keep large amounts of data updated, without encountering any sorts of timeout issues - and is therefore perfect for making sure that things like player stats update themselves at the proper times. However, there are still some areas where it&#8217;s better to use cron.</p>
<p>For example, let&#8217;s say that you are building a browsergame where players health regenerates automatically, at a rate of 1 health every 30 minutes. In this game, time passes just like in the real world - every day counts as a &#8216;year&#8217; in the game. In this situation, you would want to use the &#8220;on-view&#8221; method to update the player&#8217;s health - but a cronjob would be a much better way to update the &#8220;year&#8221; value every day. The in-gameyear isn&#8217;t really linked to a particular player, and it&#8217;s a micro-value - something that is only available in a single place. While you could certainly use the &#8220;on-view&#8221; method to update the year as well, it&#8217;s not quite as practical - a simple cronjob can easily keep your year updated for you, with the added benefit of only running as it&#8217;s needed - as opposed to every single time a player visits certain pages.</p>
<p>In summary, &#8220;on-view&#8221; is another way to achieve virtually the same functionality as cron - with a far more reliable way to keep large amounts of data up-to-date when there are many users playing your game. However, there are still places for cron - and both approaches can be used together to provide the best of both worlds.</p>
<p></p>
<h1>Update</h1>
<p>In a quick e-mail, bardic has mentioned that this idea came out of a discussion from his blog - most notably, these two posts:</p>
<ul>
<li><a href='http://webgamedev.wordpress.com/2007/04/03/tickstimed-eventscrons-etc/'>http://webgamedev.wordpress.com/2007/04/03/tickstimed-eventscrons-etc/</a></li>
<li><a href='http://webgamedev.wordpress.com/2007/12/13/the-tick/'>http://webgamedev.wordpress.com/2007/12/13/the-tick/</a></li>
</ul>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Using+the+%26%238220%3Bon-view%26%238221%3B+method+instead+of+cron&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F18%2Fusing-the-on-view-method-instead-of-cron%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/18/using-the-on-view-method-instead-of-cron/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Simple Cron</title>
		<link>http://buildingbrowsergames.com/2008/07/17/simple-cron/</link>
		<comments>http://buildingbrowsergames.com/2008/07/17/simple-cron/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 14:00:51 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[cron]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=86</guid>
		<description><![CDATA[One of the questions that I seem to get asked most about building a browsergame is &#8220;how do I make things happen periodically?&#8221;.
The answer is actually very simple, and lies with a utility that comes on all Linux servers called cron.
Cron exists to run periodic, scheduled tasks for you - based on a file called [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Simple Cron", url: "http://buildingbrowsergames.com/2008/07/17/simple-cron/" });</script>]]></description>
			<content:encoded><![CDATA[<p>One of the questions that I seem to get asked most about building a browsergame is <strong>&#8220;how do I make things happen periodically?&#8221;</strong>.</p>
<p>The answer is actually very simple, and lies with a utility that comes on all Linux servers called <em>cron</em>.</p>
<p>Cron exists to run periodic, scheduled tasks for you - based on a file called a &#8220;crontab&#8221;. You can run any command you want at any time that you want using cron.</p>
<p>In order to edit your crontab, get access to the console of your webserver and type the following command:</p>

<div class="wp_syntax"><div class="code"><pre>crontab -e</pre></div></div>

<p>If your server doesn&#8217;t have any cronjobs currently in place, you&#8217;ll just see an empty file. We will be editing this file to make things happen periodically.</p>
<p>The first five columns in your crontab correspond to measurements of time; the sixth column is the command to run. The time columns are for the hour, minute, day of the month, month, and day of week to run the command on. Here&#8217;s what a command that runs every day at 3:30 AM might look like:</p>

<div class="wp_syntax"><div class="code"><pre>30 3 * * * echo &quot;ran cron at 3:30 AM&quot; &gt; /var/log/misc/crons.log</pre></div></div>

<p>If you wanted to make something happen periodically in your game, you would just need to write the code for whatever you wanted to have happen periodically, and then write a cronjob to call it with the proper parameters.</p>
<p>You can also configure cronjobs to run in shorter intervals, or even at multiple intervals:</p>

<div class="wp_syntax"><div class="code"><pre>0 */3 * * * echo &quot;this cronjob runs every 3 hours&quot;</pre></div></div>

<p>The above cronjob will run every 3 hours - and the one below will run only once a month:</p>

<div class="wp_syntax"><div class="code"><pre>0 0 1 * * echo &quot;this cronjob runs every 3 hours&quot;</pre></div></div>

<p>If you don&#8217;t have access to your server&#8217;s command line to play around with cron, try talking to your webhost or investigating your control panel if you have one - in most cases, webhosts that won&#8217;t allow you command-line access will still allow you to create your own crontabs.</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Simple+Cron&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F17%2Fsimple-cron%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/17/simple-cron/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Building Browsergames: Securing our hashes (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/07/16/securing-our-hashes-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/07/16/securing-our-hashes-perl/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 14:00:59 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[buildingbrowsergames]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[perl]]></category>

		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=85</guid>
		<description><![CDATA[Yesterday, we worked on securing our hashes in PHP - and today, we&#8217;re going to take a look at our Perl systems.
According to tilly from perlmonks, crypt() is horribly insecure - which is definitely a big problem. We&#8217;re going to need to update our login and registration system, so that our user&#8217;s passwords are a [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Building Browsergames: Securing our hashes (Perl)", url: "http://buildingbrowsergames.com/2008/07/16/securing-our-hashes-perl/" });</script>]]></description>
			<content:encoded><![CDATA[<p>Yesterday, we worked on <a href='http://buildingbrowsergames.com/2008/07/15/securing-our-hashes-php/'>securing our hashes</a> in PHP - and today, we&#8217;re going to take a look at our Perl systems.</p>
<p>According to <a href='http://perlmonks.org/?node=tilly'>tilly from perlmonks</a>, crypt() is horribly insecure - which is definitely a big problem. We&#8217;re going to need to update our login and registration system, so that our user&#8217;s passwords are a little bit more secure if a malicious user ever gained access to our database.</p>
<p>First off, we&#8217;re going to convert our code to use the <a href='http://search.cpan.org/~gaas/Digest-MD5-2.36/MD5.pm'>Digest::MD5</a> module so that we can MD5 our passwords - in addition to salting them. If you don&#8217;t have it already, you&#8217;ll need to install Digest::MD5. Enter this at your shell(or get your web host to install it for you if they haven&#8217;t already):</p>

<div class="wp_syntax"><div class="code"><pre>cpan install Digest::MD5</pre></div></div>

<p>After installing Digest::MD5, we need to change each line that calls <em>crypt()</em> inside register.cgi and login.cgi. Here&#8217;s what the relevant line in register.cgi looks like now:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>33
34
</pre></td><td class="code"><pre class="perl">			<span style="color: #000000; font-weight: bold;">use</span> Digest<span style="color: #339933;">::</span><span style="color: #006600;">MD5</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>md5<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> . <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And that&#8217;s the only change that you need to make to your register or login code - just adjusting your execute() statements to md5 the password, and making sure that you
<pre>use Digest::MD5</pre>
<p> in each code file.</p>
<p>However, if you upload your new files and take a look, you&#8217;ll notice something - you can no longer log in!</p>
<p>Unfortunately, making this change has broken logins for all of our users who signed up before we had to make this change. Now, if your game hasn&#8217;t been released to the public yet or everyone is used to you &#8216;resetting&#8217; the game, this is fine - but if users are already playing your game, this is a bit of an issue. So we&#8217;re going to modify <strong>login.cgi</strong>, so that it first checks to see whether a user is still using a crypt()&#8217;d password or not - and if they are, it will redirect them to a page where they can change their password. Here&#8217;s what login.cgi looks like now:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
</pre></td><td class="code"><pre class="perl"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI<span style="color: #339933;">::</span><span style="color: #006600;">Carp</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>fatalsToBrowser warningsToBrowser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>		<span style="color: #666666; font-style: italic;"># this is our database settings</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Digest<span style="color: #339933;">::</span><span style="color: #006600;">MD5</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>md5<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'login.tmpl'</span><span style="color: #339933;">,</span>
		associate	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$query</span><span style="color: #339933;">,</span>		<span style="color: #666666; font-style: italic;"># for argument memory</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%parameters</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT COUNT(id) FROM users WHERE UPPER(username) = UPPER(?) AND password = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #000066;">crypt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span>\<span style="color: #0000ff;">$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span>
				<span style="color: #339933;">-</span>name	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'username+password'</span><span style="color: #339933;">,</span>
				<span style="color: #339933;">-</span>value	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span> . <span style="color: #ff0000;">'+'</span> . <span style="color: #000066;">crypt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
				<span style="color: #339933;">-</span>expires	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'+3M'</span><span style="color: #339933;">,</span>
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$uri</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'changepass.cgi'</span><span style="color: #339933;">;</span>
		<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>cookie<span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">$cookie</span><span style="color: #339933;">,-</span>location<span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT COUNT(id) FROM users WHERE UPPER(username) = UPPER(?) AND password = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> . <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span>\<span style="color: #0000ff;">$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE users SET last_login = NOW() WHERE UPPER(username) = UPPER(?) AND password = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> . <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT is_admin FROM users WHERE UPPER(username) = UPPER(?) AND password = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$is_admin</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> . <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span>\<span style="color: #0000ff;">$is_admin</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span>
					<span style="color: #339933;">-</span>name	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'username+password'</span><span style="color: #339933;">,</span>
					<span style="color: #339933;">-</span>value	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span> . <span style="color: #ff0000;">'+'</span> . md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> . <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
					<span style="color: #339933;">-</span>expires	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'+3M'</span><span style="color: #339933;">,</span>
				<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$uri</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'index.cgi'</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$is_admin</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #666666; font-style: italic;"># redirect to admin page</span>
				<span style="color: #0000ff;">$uri</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'admin.cgi'</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>cookie<span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">$cookie</span><span style="color: #339933;">,-</span>location<span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>error<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'That username and password combination does not match any currently in our database.'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>It might be hard to tell what&#8217;s different, there - but take a look at our code to check and see if the user&#8217;s information matched anything in our database. We start off by checking the username and password using crypt() - and if it matches anything, we redirect them to <strong>changepass.cgi</strong> - which we&#8217;ll be building shortly. If it doesn&#8217;t match with crypt(), we check to see if it matches with Digest::MD5&#8217;s md5() function - and if it doesn&#8217;t match either of those, we tell the user that it didn&#8217;t match anything.</p>
<p>If you haven&#8217;t guessed it yet, <strong>changepass.cgi</strong> is going to be the page users use to change their password. Here&#8217;s what the template(<strong>changepass.tmpl</strong>) looks like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre>&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Change Password&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;tmpl_if name='error'&gt;
		&lt;span style='color:red'&gt;Error: &lt;!--tmpl_var name='error'--&gt;&lt;/span&gt;
	&lt;/tmpl_if&gt;
	&lt;tmpl_if name='message'&gt;
		&lt;span style='color:green'&gt;&lt;!--tmpl_var name='message'--&gt;&lt;/span&gt;
	&lt;/tmpl_if&gt;
	&lt;form method='post' action='changepass.cgi'&gt;
		Password: &lt;input type='password' name='password' id='password' /&gt;&lt;br /&gt;
		Confirm Password: &lt;input type='password' name='confirm' /&gt;&lt;br /&gt;
		&lt;input type='submit' value='Change Password' /&gt;
	&lt;/form&gt;
	&lt;script type='text/javascript'&gt;
	document.getElementById('password').focus()<SEMI>
	&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>Here&#8217;s the code for <strong>changepass.cgi</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="perl"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Digest<span style="color: #339933;">::</span><span style="color: #006600;">MD5</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>md5<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">require</span> login<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%params</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">ne</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>confirm<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$params</span><span style="color: #009900;">&#123;</span>error<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'Passwords do not match!'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE users SET password = ? WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> . <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$params</span><span style="color: #009900;">&#123;</span>message<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;Password updated successfully.&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'changepass.tmpl'</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And that&#8217;s all there is to it! By making this quick change, we&#8217;ve secured our user passwords a little better against any malicious users - and as an added bonus, we&#8217;ve created a change password page!</p>
<p><strong style='color:red'>Note</strong>: don&#8217;t forget to change &#8217;saltgoeshere&#8217; to an actually random value, like &#8217;s79dj@#*(hd&#8217; or something - you won&#8217;t make any security gains if malicious users can easily guess your password salt. If you&#8217;re feeling <strong>really</strong> adventurous, you could(and probably should) turn the salt into a configuration parameter - but I&#8217;ll leave how to do that up to you.</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Building+Browsergames%3A+Securing+our+hashes+%28Perl%29&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F16%2Fsecuring-our-hashes-perl%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/16/securing-our-hashes-perl/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Building Browsergames: Securing our hashes (PHP)</title>
		<link>http://buildingbrowsergames.com/2008/07/15/securing-our-hashes-php/</link>
		<comments>http://buildingbrowsergames.com/2008/07/15/securing-our-hashes-php/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 14:00:04 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[buildingbrowsergames]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=84</guid>
		<description><![CDATA[John Munsch recently pointed out that there&#8217;s a bit of a glaring security hole in our login and registration systems: at the moment, we&#8217;re extremely vulnerable to Rainbow Table attacks. In John&#8217;s words:

The MD5 hash doesn’t actually protect you if someone were able to dump your table of users or gain access to the database [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Building Browsergames: Securing our hashes (PHP)", url: "http://buildingbrowsergames.com/2008/07/15/securing-our-hashes-php/" });</script>]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.johnmunsch.com/'>John Munsch</a> recently pointed out that there&#8217;s a bit of a glaring security hole in our login and registration systems: at the moment, we&#8217;re extremely vulnerable to <a href='http://en.wikipedia.org/wiki/Rainbow_table'>Rainbow Table</a> attacks. In John&#8217;s words:</p>
<blockquote><p>
The MD5 hash doesn’t actually protect you if someone were able to dump your table of users or gain access to the database in some fashion.
</p></blockquote>
<p>And you know what? <strong>He&#8217;s absolutely right</strong>. If a malicious user managed to get access to our database at the moment, our user&#8217;s logins wouldn&#8217;t be protected at all. This is a <strong>big problem</strong>, and something we need to fix.</p>
<p>Unfortunately, because password hashing is one-way, we can&#8217;t just get users to reset their password. They&#8217;ll either need to re-register entirely, or we can setup a special page(and stat) in order to make sure that users have reset their passwords. John recommends adding what&#8217;s known as a &#8217;salt&#8217; value to user&#8217;s passwords - that way, you might have something like this:</p>

<div class="wp_syntax"><div class="code"><pre>password = 'foo'
password + salt = 'foobrownfox'
hashed password = hash('foobrownfox')</pre></div></div>

<p>And if a user were to attack our login information using a rainbow table, they might manage to figure out that the passwords being stored in the database were values like &#8216;foobrownfox&#8217; - but they&#8217;d have a bit of a harder time figuring out what was the salt value and what was the actual password.</p>
<p>Luckily, this is a pretty easy fix to implement - we just modify our two calls to md5() in our login and register code to add a salt to the user&#8217;s passwords. Here&#8217;s the changes we make to <strong>register.php</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>24
</pre></td><td class="code"><pre class="php">				<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Unfortunately, at this moment making these changes breaks things for users who signed up before we had to make this fix. In order to try and keep things as seamless as possible for the user, we&#8217;ll be modifying our login code slightly:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
46
47
48
49
50
51
52
53
54
55
</pre></td><td class="code"><pre class="php">	<span style="color: #000033;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT COUNT(id) FROM users WHERE UPPER(username) = UPPER('%s') AND password='%s'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$count</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000033;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'authenticated'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		<span style="color: #000033;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$username</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location:changepass.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000033;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT COUNT(id) FROM users WHERE UPPER(username) = UPPER('%s') AND password='%s'&quot;</span><span style="color: #339933;">,</span>
			<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
			<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$count</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000033;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'authenticated'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">;</span>
			<span style="color: #000033;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$username</span><span style="color: #339933;">;</span>
			<span style="color: #000033;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE users SET last_login = NOW() WHERE UPPER(username) = UPPER('%s') AND password = '%s'&quot;</span><span style="color: #339933;">,</span>
				<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
				<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000033;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT is_admin FROM users WHERE UPPER(username) = UPPER('%s') AND password='%s'&quot;</span><span style="color: #339933;">,</span>
				<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
				<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$password</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$is_admin</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$is_admin</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location:admin.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>			
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location:index.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>				
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>	
			<span style="color: #000033;">$error</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'There is no username/password combination like that in the database.'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>We&#8217;ve made a small change to our login code, so that it first tests to see if the user&#8217;s attributes match up to any users who haven&#8217;t had their passwords salted - if they do, we redirect them to the page where they can change their password. Here&#8217;s what the template for our &#8216;change password&#8217; page(<strong>change_pass.tpl</strong>) looks like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre>&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Change Password&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	{if $error ne &quot;&quot;}
		&lt;span style='color:red'&gt;Error: {$error}&lt;/span&gt;
	{/if}
	{if $message ne &quot;&quot;}
		&lt;span style='color:green'&gt;{$message}&lt;/span&gt;
	{/if}
	&lt;form method='post' action='changepass.php'&gt;
		Password: &lt;input type='password' name='password' id='password' /&gt;&lt;br /&gt;
		Confirm Password: &lt;input type='password' name='confirm' /&gt;&lt;br /&gt;
		&lt;input type='submit' value='Change Password' /&gt;
	&lt;/form&gt;
	&lt;script type='text/javascript'&gt;
	document.getElementById('password').focus()<SEMI>
	&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>With the template created, all we need to do is build the page that handles changing the user&#8217;s password - like so:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
</pre></td><td class="code"><pre class="php"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'smarty.php'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'login-check.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$_POST</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000033;">$password</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000033;">$confirm</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'confirm'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$password</span> <span style="color: #339933;">!=</span> <span style="color: #000033;">$confirm</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000033;">$error</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Passwords do not match!'</span><span style="color: #339933;">;</span>	
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'config.php'</span><span style="color: #339933;">;</span>		<span style="color: #666666; font-style: italic;">// our database settings</span>
		<span style="color: #000033;">$conn</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$dbhost</span><span style="color: #339933;">,</span><span style="color: #000033;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #000033;">$dbpass</span><span style="color: #009900;">&#41;</span>
			or <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error connecting to mysql'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$dbname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000033;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE users SET password = '%s' WHERE username = '%s'&quot;</span><span style="color: #339933;">,</span>
					<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
					<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000033;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000033;">$message</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Password updated successfully.'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
<span style="color: #000033;">$smarty</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assign</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'error'</span><span style="color: #339933;">,</span><span style="color: #000033;">$error</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$smarty</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assign</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'message'</span><span style="color: #339933;">,</span><span style="color: #000033;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$smarty</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">display</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'change_pass.tpl'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>And that&#8217;s all there is to it! With a fairly simple change, we&#8217;ve managed to secure our user&#8217;s information a bit better - a malicious user with direct access to our database won&#8217;t be able to easily figure out what a user&#8217;s password is just by using a Rainbow table. As an added bonus, we&#8217;ve also created an extra piece of functionality - a change password page!</p>
<p><strong style='color:red'>Note</strong>: don&#8217;t forget to change &#8217;saltgoeshere&#8217; to an actually random value, like &#8217;s79dj@#*(hd&#8217; or something - you won&#8217;t make any security gains if malicious users can easily guess your password salt. If you&#8217;re feeling <strong>really</strong> adventurous, you could(and probably should) turn the salt into a configuration parameter - but I&#8217;ll leave how to do that up to you.</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Building+Browsergames%3A+Securing+our+hashes+%28PHP%29&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F15%2Fsecuring-our-hashes-php%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/15/securing-our-hashes-php/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Diary of a Browsergame: Setting up the database</title>
		<link>http://buildingbrowsergames.com/2008/07/14/diary-of-a-browsergame-setting-up-the-database/</link>
		<comments>http://buildingbrowsergames.com/2008/07/14/diary-of-a-browsergame-setting-up-the-database/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 14:00:02 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
		
		<category><![CDATA[SQL]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[database]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[diaryofabrowsergame]]></category>

		<category><![CDATA[workingtitle]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=83</guid>
		<description><![CDATA[One of the first things I do for any new project of mine is design the database - so that&#8217;s what&#8217;s going to happen to Working Title today. This design will probably change slowly over the course of development - it&#8217;s just a good starting point for now.
To begin with, we&#8217;ll need a users table.

CREATE [...]<script type="text/javascript">SHARETHIS.addEntry({ title: "Diary of a Browsergame: Setting up the database", url: "http://buildingbrowsergames.com/2008/07/14/diary-of-a-browsergame-setting-up-the-database/" });</script>]]></description>
			<content:encoded><![CDATA[<p>One of the first things I do for any new project of mine is design the database - so that&#8217;s what&#8217;s going to happen to Working Title today. This design will probably change slowly over the course of development - it&#8217;s just a good starting point for now.</p>
<p>To begin with, we&#8217;ll need a users table.</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> users <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	username text<span style="color: #66cc66;">,</span>
	password text<span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>And once we have that, a <em>stats</em> table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> stats <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	display_name text<span style="color: #66cc66;">,</span>
	short_name varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">25</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>If this all looks familiar so far, that&#8217;s because it should - this is the exact same table structure(currently, anyway) as the game we&#8217;ve been working on. I&#8217;m taking all of the design decisions and changes that we made in our other project, and doing my best to apply them here - thereby continually improving my code, and my design.</p>
<p>Because Working Title will have a few distinct &#8216;entities&#8217;, my <em>entity_stats</em> is going to look a little bit different than the one we&#8217;re using right now. According to <a href='http://buildingbrowsergames.com/workingtitle/design/1.0.html'>the design document</a>, there are 4 main entities - players, rooms, monsters, and items. Those will make the enum in the <em>entity_stats</em> table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> entity_stats <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	stat_id int<span style="color: #66cc66;">,</span>
	entity_id int<span style="color: #66cc66;">,</span>
	value text<span style="color: #66cc66;">,</span>
	entity_type ENUM<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'User'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Monster'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Room'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Thinking about it a little more, I&#8217;m pretty sure that I don&#8217;t <strong>need</strong> separate tables for each of the entities that can exist within Working Title - all I need is a single table to keep track of their name, ID, description, and type. So that&#8217;s what I&#8217;m going to do:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> entities <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	name text<span style="color: #66cc66;">,</span>
	entity_type ENUM<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Monster'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Room'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	description text<span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>One of the things that the design document mentions is that &#8220;users will move between rooms&#8221; - which means that I will need way to track which room a user is currently in. I&#8217;m going to use a stat to do this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Current Room'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'cur_room'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>There are also supposed to be players, monsters, <strong>and</strong> items inside rooms - so I&#8217;ll need a table to keep track of all the entities within a room:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> room_entities <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	room int<span style="color: #66cc66;">,</span>
	entity_id int<span style="color: #66cc66;">,</span>
	entity_type ENUM<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Monster'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'User'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>	
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Monsters will be able to drop items, so I&#8217;m going to need to add a table to do that. Because all they&#8217;re going to be able to drop is items(not other monsters or rooms or anything), I can make it so that the <em>monster_drops</em> table only contains information on what items, and what the percentage chance is for them to drop:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> monster_drops <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	monster int<span style="color: #66cc66;">,</span>
	item int<span style="color: #66cc66;">,</span>
	drop_rate int<span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>The next table I need to add is one to track a user&#8217;s inventory - so I&#8217;ll add the <em>user_items</em> table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> user_items <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	user_id int<span style="color: #66cc66;">,</span>
	item int<span style="color: #66cc66;">,</span>
	quantity int<span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>The design document mentions <em>&#8220;____ of holding&#8221;</em>&apos;s, which is something I haven&#8217;t quite figured out yet. I <strong>could</strong> just use a stat to keep track of the player&#8217;s current inventory limit, or I could come up with a better idea. For the moment, I&#8217;m going to leave this piece of functionality out of my database design - I&#8217;m not sure how to build it yet.(If you know a good way to do this, send me an e-mail at <a href='mailto:buildingbrowsergames@gmail.com'>buildingbrowsergames@gmail.com</a>, or comment on this blog post)</p>
<p>Based on the list of commands players can use, there are a few stats that I can add into the database right now:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Maximum Health'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'max_hp'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Current Health'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'cur_hp'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Current Weapon'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'cur_weapon'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Current Armor'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'cur_armor'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Current Ring (Left Hand)'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'cur_ring_left'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Current Ring (Right Hand)'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'cur_ring_right'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Gold In Bank'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'bank_gc'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Gold In Hand'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'hand_gc'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Current Level'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'cur_lvl'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Current Experience'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'cur_exp'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Experience to Next Level'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'next_exp'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>That sets me up with some of my starter stats, although it&#8217;s definitely not all of them - I&#8217;m sure I&#8217;ll end up adding more stats as Working Title grows into more of a finished product.</p>
<p>The last table that I&#8217;m going to add for now is simply for keeping track of exits off of rooms: <em>room_exits</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> room_exits <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	name text<span style="color: #66cc66;">,</span>
	from_room int<span style="color: #66cc66;">,</span>
	to_room int<span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>I&#8217;ll be tracking the <em>entity_id</em> of both of the rooms, and using the <em>name</em> value to select which exit. For example, an exit to the North from room 1 to 2 might look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> room_exits<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>from_room<span style="color: #66cc66;">,</span>to_room<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'North'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>With all this finished, there&#8217;s only one more system to add - spells. I&#8217;m not quite sure how I want to implement spells yet, either - do I want to have them do a set amount of damage, or base it on level, or something else? I&#8217;m going to hold off on designing any database tables for my spells system for now - once I have Working Title in a playable state, I&#8217;ll work on adding spells. For now though, I&#8217;m going to stick with what I have - I&#8217;ve got the basics of my database in place, and I can safely start developing now.</p>
<p><a href="http://sharethis.com/item?&wp=2.6&amp;publisher=f11f31da-d672-44f6-a586-88fe8e5adb5b&amp;title=Diary+of+a+Browsergame%3A+Setting+up+the+database&amp;url=http%3A%2F%2Fbuildingbrowsergames.com%2F2008%2F07%2F14%2Fdiary-of-a-browsergame-setting-up-the-database%2F">ShareThis</a></p>]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/14/diary-of-a-browsergame-setting-up-the-database/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
