<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Building Browsergames &#187; database</title>
	<atom:link href="http://buildingbrowsergames.com/category/design/database/feed/" rel="self" type="application/rss+xml" />
	<link>http://buildingbrowsergames.com</link>
	<description>Ever wanted to build a browsergame?</description>
	<lastBuildDate>Mon, 29 Mar 2010 14:00:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Saving Database Space through Bit-masking</title>
		<link>http://buildingbrowsergames.com/2008/09/04/saving-database-space-through-bit-masking/</link>
		<comments>http://buildingbrowsergames.com/2008/09/04/saving-database-space-through-bit-masking/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 14:00:34 +0000</pubDate>
		<dc:creator>gostyloj</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=283</guid>
		<description><![CDATA[This is a trick you can use to increase the efficiency and readability of your project.  It is an argument for good up front design as utilizing this is only plausible when you take the time and effort at the beginning.  The following is a real world example from my game TerraTanks.
The problem [...]]]></description>
			<content:encoded><![CDATA[<p>This is a trick you can use to increase the efficiency and readability of your project.  It is an argument for good up front design as utilizing this is only plausible when you take the time and effort at the beginning.  The following is a real world example from my game TerraTanks.</p>
<p>The problem is that you have an object with a ton of properties that are incredibly similar and they describe the object in a yes|no fashion.  In my case, players can do 24 types of research and the state of the player is &#8220;yes, I have done that particular research&#8221; or &#8220;no, I have not done that research&#8221;.</p>
<p>One solution is to make a table with a column that associates with the player id and a boolean column for every type of research that you have.  Now if you have 24 types of research your table is 25 columns big.  This can get out of hand pretty quickly.  The table becomes hard to read and you have to use different code (or procedurally dynamic code) to set individual columns.</p>
<p>Another solution is to add a column to your player definition table and make it type INT UNSIGNED.  Then you let your code efficiently handle interpreting the integer as the player&#8217;s research definition through bit masking.  Here&#8217;s how it works.</p>
<p>The maximum value of an unsigned INT in MySQL is <code class="literal">4294967295. </code> In binary this number looks like 11111111111111111111111111111111.  That is 32 1&#8217;s in a row.  Each of those digits can describe a research type as &#8216;have&#8217; (it is a 1) or &#8216;have not&#8217; (it is a 0).  Now in a global file for your code you need to define each research type as a number that is a power of 2.  It would look something like this in PHP:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$g_shield_research</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>              <span style="color: #666666; font-style: italic;">// in binary 001</span>
<span style="color: #000088;">$g_armor_piercing_research</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">// in binary 010</span>
<span style="color: #000088;">$g_mining_research</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>             <span style="color: #666666; font-style: italic;">// in binary 100</span></pre></div></div>

<p>
Now if you want to know whether you have a particular research you would perform a bitmask operation on the integer you retrieve from your database using the &amp; operator.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// will mask players research and return true if the mining bit is set to 1</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">research</span> <span style="color: #339933;">&amp;</span> <span style="color: #000088;">$g_mining_research</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>
The bit masking procedure is extremely efficient and fast and you can see how it compresses all the research information into the size of an integer.  Also, if you want to know everything about a player&#8217;s research you only have to retrieve a single integer from the database.</p>
<p>Assigning research to a player is also very easy.  Simply bitwise OR the current research integer with the set bitmask using the | operator:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$newPlayerResearch</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">research</span> <span style="color: #339933;">|</span> <span style="color: #000088;">$g_shield_research</span><span style="color: #339933;">;</span></pre></div></div>

<p>You can technically add the two numbers to get the same result, but this is unsafe because if you add the research when it is already there it will throw everything off.</p>
<p>There are some pitfalls to using this trick.  While it is easy to add another type of research just by assigning its mask to the next highest power of 2, you are limited to 32 total research types.  One way to get around this is to make the column type BIGINT which would give you 64 bits to work with, but at the end of the day you are still limited.  Also, once a game starts the research you choose for that bit position is pretty much stuck there unless you want to do some math maintenance.</p>
<p>While this trick will tend to make your code more readable because database statements won&#8217;t be as long, your database entry will not be human readable so it could slow down your debugging efforts.</p>
<p>So there you have it.  A very powerful tool if used wisely.  Please design well before you start writing code.  It makes life easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/09/04/saving-database-space-through-bit-masking/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</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 &#8211; 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 &#8211; it&#8217;s just a good starting point for now.
To begin with, we&#8217;ll need a users table.

CREATE [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first things I do for any new project of mine is design the database &#8211; 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 &#8211; 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" style="font-family:monospace;"><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" style="font-family:monospace;"><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 &#8211; 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 &#8211; 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 &#8211; 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" style="font-family:monospace;"><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 &#8211; 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" style="font-family:monospace;"><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; &#8211; 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" style="font-family:monospace;"><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 &#8211; 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" style="font-family:monospace;"><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" style="font-family:monospace;"><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 &#8211; so I&#8217;ll add the <em>user_items</em> table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><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 &#8211; 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" style="font-family:monospace;"><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 &#8211; 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" style="font-family:monospace;"><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" style="font-family:monospace;"><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 &#8211; spells. I&#8217;m not quite sure how I want to implement spells yet, either &#8211; 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 &#8211; 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 &#8211; I&#8217;ve got the basics of my database in place, and I can safely start developing now.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/14/diary-of-a-browsergame-setting-up-the-database/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: DRYing out our stats</title>
		<link>http://buildingbrowsergames.com/2008/07/11/drying-out-our-stats/</link>
		<comments>http://buildingbrowsergames.com/2008/07/11/drying-out-our-stats/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 14:00:35 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[DRY]]></category>
		<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=82</guid>
		<description><![CDATA[Over the course of developing our game, our database has sort of grown organically. As we added a new feature, we&#8217;d add the tables we needed to accomodate this feature. While this works(and has been working for us just fine), it&#8217;s not neccessarily the best way to design your database &#8211; because as you can [...]]]></description>
			<content:encoded><![CDATA[<p>Over the course of developing our game, our database has sort of grown organically. As we added a new feature, we&#8217;d add the tables we needed to accomodate this feature. While this works(and has been working for us just fine), it&#8217;s not neccessarily the best way to design your database &#8211; because as you can see, we now have 3 stats tables(<em>user_stats</em>,<em>monster_stats</em>, and <em>item_stats</em>) when we only actually need one &#8211; as <a href='http://blog.fetmab.com/'>sepp</a> has once again helpfully pointed out.</p>
<p>With that in mind, we&#8217;re going to create another table, to replace those three. Because lots of different things can have stats, I&#8217;m going to call the table <em>entity_stats</em> &#8211; although if you want to, you can call it whatever you want(but make sure to keep your change in mind when you&#8217;re working through this code). Here&#8217;s what we&#8217;re going to do to create the table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><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;">&#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>Now that we&#8217;ve created this new table, we&#8217;re going to need to customize our SQL queries slightly. Previously, we were only using an object&#8217;s ID value to retrieve the stats for it &#8211; now that we don&#8217;t have that separation, we will need to run the query based on two things &#8211; the object&#8217;s ID, and the object&#8217;s type.</p>
<p>Because we&#8217;ve been doing re-writing to our stats code, we&#8217;re actually in a good position to make this change &#8211; we only need to change the query in one file, instead of 3(or more). Our old SQL looked like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #ff0000;">&quot;SELECT value FROM table WHERE stat_id = (SELECT id FROM stats WHERE display_name = 'foo' OR short_name = 'bar') AND column = 'baz'&quot;</span></pre></div></div>

<p>The new SQL is going to look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #ff0000;">&quot;SELECT value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = 'foo' OR short_name = 'bar') AND entity_id = 'baz' AND type = 'bat'&quot;</span></pre></div></div>

<p>One of the benefits of doing this is that we&#8217;re actually going to be cleaning up our new DRY stats code a little bit more, too &#8211; we get to trim it down to only take a &#8216;type&#8217; argument, instead of the table and column names it needs to retrieve with. Think back to our DRY stats code from earlier:</p>
<h2>PHP</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$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 value FROM <span style="color: #009933; font-weight: bold;">%s</span> WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND <span style="color: #009933; font-weight: bold;">%s</span> = '<span style="color: #009933; font-weight: bold;">%s</span>'&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: #000088;">$tableName</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: #000088;">$statName</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: #000088;">$statName</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: #000088;">$columnName</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: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$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: #000088;">$value</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: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Perl</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</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 value FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&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;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</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;">\$value</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: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>And here&#8217;s what it looks like with the change made:</p>
<h2>PHP</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$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 value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND entity_id = '<span style="color: #009933; font-weight: bold;">%s</span>' AND entity_type = '<span style="color: #009933; font-weight: bold;">%s</span>'&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: #000088;">$statName</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: #000088;">$statName</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: #000088;">$trackingID</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: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$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: #000088;">$value</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: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Perl</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</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 value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND entity_id = ? AND entity_type = ?&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;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</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;">\$value</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: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Once we&#8217;ve made those changes, it&#8217;s easy to modify all of our code for the new database structure:</p>
<h2>PHP</h2>

<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
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'database.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$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 value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND entity_id = '<span style="color: #009933; font-weight: bold;">%s</span>' AND entity_type = '<span style="color: #009933; font-weight: bold;">%s</span>'&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: #000088;">$statName</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: #000088;">$statName</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: #000088;">$trackingID</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: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$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: #000088;">$value</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: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> setStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$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 entity_stats SET value = '<span style="color: #009933; font-weight: bold;">%s</span>' WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND entity_id = '<span style="color: #009933; font-weight: bold;">%s</span>' AND entity_type = '<span style="color: #009933; font-weight: bold;">%s</span>'&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: #000088;">$value</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: #000088;">$statName</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: #000088;">$statName</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: #000088;">$trackingID</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: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$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(value) FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND entity_id = '<span style="color: #009933; font-weight: bold;">%s</span>' AND entity_type ='<span style="color: #009933; font-weight: bold;">%s</span>'&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: #000088;">$statName</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: #000088;">$statName</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: #000088;">$trackingID</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: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$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: #000088;">$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: #000088;">$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: #000088;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// the stat doesn't exist; insert it into the database</span>
		<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO entity_stats(stat_id,entity_id,value,entity_type) VALUES ((SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>'),'<span style="color: #009933; font-weight: bold;">%s</span>','<span style="color: #009933; font-weight: bold;">%s</span>','<span style="color: #009933; font-weight: bold;">%s</span>')&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: #000088;">$statName</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: #000088;">$statName</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: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'0'</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</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: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<h2>Perl</h2>

<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
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> database<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</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 value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND entity_id = ? AND entity_type = ?&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;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</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;">\$value</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: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</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 entity_stats SET value = ? WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND entity_id = ? AND entity_type = ?&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;">$statValue</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> createIfNotExistsDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>	
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</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(value) FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND entity_id = ? AND entity_type = ?&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;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</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;">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;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;"># no entry for that stat/user combination - insert one with a value of 0</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;INSERT INTO entity_stats(stat_id,entity_id,value,entity_type) VALUES ((SELECT id FROM stats WHERE display_name = ? OR short_name = ?),?,?,?)&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;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And with that done, our change is made! Now it&#8217;s just a matter of modifying the code we created for each stat specifically(only one shown):</p>
<h2>PHP</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'stats-dry.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> getStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> setStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	setStatDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<h2>Perl</h2>

<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
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> stats<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">getStatDRY</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'user'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">setStatDRY</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'user'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And once all of the changes are done, you&#8217;re good! Now all of the stat values will be stored in a single table.</p>
<p>But what about users who have already registered for your game, or monsters and items that you&#8217;ve already added?</p>
<p>We definitely don&#8217;t want to have to tell every single person playing our game to re-register &#8211; so we&#8217;re going to write some quick SQL to copy the values over for us, before removing the tables that we no longer need:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> stat_id<span style="color: #66cc66;">,</span>user_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'user'</span> <span style="color: #993333; font-weight: bold;">FROM</span> user_stats<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> user_stats;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> stat_id<span style="color: #66cc66;">,</span>monster_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'monster'</span> <span style="color: #993333; font-weight: bold;">FROM</span> monster_stats<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> monster_stats;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> stat_id<span style="color: #66cc66;">,</span>item_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'item'</span> <span style="color: #993333; font-weight: bold;">FROM</span> item_stats<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> item_stats;</pre></div></div>

<p>Once we&#8217;ve run that SQL, we&#8217;ll have deleted our 3 new tables &#8211; but not before we moved the data over from them to our new <em>entity_stats</em> table. Once you make the necessary modifications to your stats code and upload it all, take a look at your game &#8211; it will still work just like it did before!</p>
<p>This might seem like a weird thing to get excited about, but it&#8217;s a pretty big deal &#8211; we just changed a significant portion of our database, and didn&#8217;t break any of our existing code at all. <strong>This</strong> is why the DRY approach is so useful to have, and why you should always strive to use DRY in your designs to begin with &#8211; because making this change with the database logic spread accross dozens of files would drive even the calmest developer batty.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/11/drying-out-our-stats/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Designing a flexible items system</title>
		<link>http://buildingbrowsergames.com/2008/07/02/designing-a-flexible-items-system/</link>
		<comments>http://buildingbrowsergames.com/2008/07/02/designing-a-flexible-items-system/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 14:00:36 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=75</guid>
		<description><![CDATA[When building an inventory system, there are a lot of different approaches that you can take. Some developers simply hard-code everything, while others make sure that nothing is hard-coded &#8211; and in between both of these two extremes is a comfortable middle point, where we have most of the flexibility of not having anything hard-coded, [...]]]></description>
			<content:encoded><![CDATA[<p>When building an inventory system, there are a lot of different approaches that you can take. Some developers simply hard-code everything, while others make sure that <strong>nothing</strong> is hard-coded &#8211; and in between both of these two extremes is a comfortable middle point, where we have most of the flexibility of not having anything hard-coded, while still being able to develop with the same level of ease as if we had hard-coded it.</p>
<p>Designing an inventory system like this takes time &#8211; you can&#8217;t just throw everything together and hope it works. You need to plan it out first.</p>
<p>One question you need to ask yourself is: what about different item types? If there are weapons, armor, and general items, how will you handle that?</p>
<p>A hard-coded solution would be to create three tables &#8211; <em>weapons</em>,<em>armor</em>, and <em>items</em>. But at that point, you have a problem; how will you link specific items to something like monsters? You would need to create three <strong>more</strong> tables &#8211; <em>monster_weapons</em>, <em>monster_armor</em>, and <em>monster_items</em>. And then figuring out what particular item a monster might drop at any given time would be a major headache.</p>
<p>An easier solution to this is to create a single <em>items</em> table, with a &#8216;type&#8217; column that can be used to track the type &#8211; that way, we only need to link monsters up to single items, and we can retrieve all of the monster&#8217;s droppables with a single, simple database query. Here&#8217;s what a simple items table might look like:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> 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>
	name text<span style="color: #66cc66;">,</span>
	type 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>At this point, we now have a single table that we can use to track our different items &#8211; and the flexbility to categorize them all by type if we so choose. This allows us to do something like this to create three different items(each a different type):</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<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;">'Wooden Armor'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'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> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<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;">'Wooden Sword'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'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> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<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;">'Red Potion'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'consumable'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>By building our items table in this way, we only need one table to link a monster to the items that they will drop &#8211; and we can easily make them drop any type of item we want them to. We can also create an <em>item_stats</em> table, so that all of our items can have stats applied to them:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> item_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>
	item_id int<span style="color: #66cc66;">,</span>
	stat_id int<span style="color: #66cc66;">,</span>
	value 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 this way, we can leverage our stats system to allow our items to have the same stats as our players or our monsters. We can easily add and remove stats for any item we choose &#8211; if a potion should have a defence of 4 and a maximum HP of 8, we can do that. The flexibility is there.</p>
<p>While it&#8217;s not the <strong>perfect</strong> system, this inventory system is &#8216;good enough&#8217; &#8211; as long as the only thing you know is that you will need to add and remove item types, and have different items with different stats, this item system will work perfectly for you.</p>
<p class='blurb'>Do you know of a better way to design an inventory system? Shoot me an e-mail at <a href='mailto:buildingbrowsergames@gmail.com'>buildingbrowsergames@gmail.com</a>, or leave a message in the comments!</p>
<p></p>
<p><strong>Edit:</strong> <a href='http://www.seelenradio.de/'>sepp</a> has pointed out that the <em>item.type</em> column would be a perfect location to use what&#8217;s known as an enum. According to the <a href='http://dev.mysql.com/doc/refman/5.1/en/enum.html'>MySQL documentation on enums</a>, an enum is &#8220;a string object with a value chosen from a list of allowed values that are enumerated explicitly in the column specification at table creation time.&#8221; &#8211; which is perfect for what we need. Because we will only have so many item types within our game, using an enum will ensure that we can&#8217;t have situations where we make a typo and end up with an item with a type of &#8216;weapoh&#8217; or anything. Here&#8217;s the table creation code, using a basic enum to set up 3 item types:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> 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>
	name text<span style="color: #66cc66;">,</span>
	type ENUM<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Weapon'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Armor'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Usable'</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>

]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/02/designing-a-flexible-items-system/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Designing Browsergames: a flexible stats system</title>
		<link>http://buildingbrowsergames.com/2008/05/05/designing-browsergames-a-flexible-stats-system/</link>
		<comments>http://buildingbrowsergames.com/2008/05/05/designing-browsergames-a-flexible-stats-system/#comments</comments>
		<pubDate>Mon, 05 May 2008 14:00:30 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[database]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=24</guid>
		<description><![CDATA[Most (if not all) of the browsergames I have played have, in some way or another, incorporated some sort of statistics for the player. These might be things like attack, defence, strength, etc. &#8211; or they might be more &#8216;abstract&#8217; stats, like willpower, moxy, or ego.
At any rate, pretty much every game has stats in [...]]]></description>
			<content:encoded><![CDATA[<p>Most (if not all) of the browsergames I have played have, in some way or another, incorporated some sort of statistics for the player. These might be things like attack, defence, strength, etc. &#8211; or they might be more &#8216;abstract&#8217; stats, like willpower, moxy, or ego.</p>
<p>At any rate, pretty much every game has stats in it &#8211; otherwise, there&#8217;s no way of knowing how well you&#8217;re doing in comparison to anyone else!</p>
<p>Over the course of designing your game, you might figure out that you need 3 stats &#8211; attack, defence, and magic. And so you&#8217;ll set up the &#8216;users&#8217; table in your database something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><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 varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">250</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	password varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	attack int<span style="color: #66cc66;">,</span>
	defence int<span style="color: #66cc66;">,</span>
	magic 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>Which would be fine. You&#8217;d build your game, and the game would work as expected.</p>
<p>But what happens when, later on down the road, you want to add a new stat &#8211; like magic defence or something? With the design that you have now, you&#8217;ll need to first modify your <em>users</em> table, and then modify any code that interacts with the new stat &#8211; in addition to initializing the stat for all the players who already exist but don&#8217;t have the stat.</p>
<p>Does that sound like a bit of a pain to you? Because it does to me &#8211; and I&#8217;m here to show you a better way.</p>
<p>By moving our stats into their own table, we can create a table filled with available stats for players, without needing to worry about modifying any tables later on in our game &#8211; if we want to add a stat, we just add it to the table and our code, and we&#8217;re done &#8211; we could even build something in place to check to see if users have the stat already, and if they don&#8217;t it creates the entry for them. That sounds better than having to modify our database by hand, doesn&#8217;t it? Here&#8217;s how we could set up our initial <em>stats</em> table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><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;">10</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>And this table will now store all of our stat definitions. If we wanted to add a stat called &#8220;Magic Defence&#8221; (and abbreviated as &#8220;mdef&#8221; for our code&#8217;s sake), we could run a query like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><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;">'Magic Defence'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'mdef'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>&#8230;At which point the new stat would exist in our system &#8211; and all we would need to do is modify our code to interact with it.</p>
<p>In order to store the stat values for a player, all we need to do is create another table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> user_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>
	user_id int<span style="color: #66cc66;">,</span>
	stat_id int<span style="color: #66cc66;">,</span>
	value 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>At this point, we&#8217;ll have three tables &#8211; <em>users</em>, <em>stats</em>, and <em>user_stats</em>. The purpose of <em>user_stats</em> is to link particular users to particular stats &#8211; and store their values. <em>user_stats.stat_id</em> is the value of <em>stats.id</em> for a particular stat, and <em>user_stats.user_id</em> is the value from <em>users.id</em>. <em>user_stats.value</em> will store the actual value of our stat.</p>
<p>You might be wondering why the type of <em>user_stats.value</em> is <em>text</em>, as opposed to <em>int</em> or something &#8211; it&#8217;s so that we can have as flexible a stats system as we need. By storing the value as a text type, we&#8217;re able to store text <strong>or</strong> numbers inside our column &#8211; which means that if we wanted to have a stat like &#8220;Status&#8221; that had possible values of &#8220;Awake&#8221;,&#8221;Asleep&#8221;, or &#8220;Eating&#8221; &#8211; we could, in addition to having another stat called &#8220;Restedness&#8221; that simply contained a value between 1 and 100. By using the <em>text</em> type for our column, we&#8217;re able to store whatever we want &#8211; although this does mean that you need to be more careful about how you handle the values of your stats within your actual code.</p>
<p>Hopefully by taking a look at the database structure and these explanations, you can see why this system might be a better way to store player stats than by hard-coding them into your <em>users</em> table &#8211; although really, any approach will do. But if you&#8217;re looking for flexibility down the road, this approach will give you more of that than hard-coding values into your database. Flexibility is always a benefit if you ever plan on tweaking your game.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/05/05/designing-browsergames-a-flexible-stats-system/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Designing your game&#8217;s database</title>
		<link>http://buildingbrowsergames.com/2008/04/15/designing-your-database/</link>
		<comments>http://buildingbrowsergames.com/2008/04/15/designing-your-database/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 14:00:47 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[database]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=6</guid>
		<description><![CDATA[One of the first things that I do whenever I start a new project is design the database.
In many ways, the database is the core of your game &#8211; without it, your game is nothing. You could write all the logic you wanted to, but if you didn&#8217;t have a database that logic would be [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first things that I do whenever I start a new project is design the database.</p>
<p>In many ways, the database is the core of your game &#8211; without it, your game is nothing. You could write all the logic you wanted to, but if you didn&#8217;t have a database that logic would be worthless(there&#8217;d be nothing to use it on!).</p>
<p>There are many ways to design a database, and some are better than others. For this entry, I&#8217;ll be walking you through how to design a database that has as little data replication as possible.</p>
<p>Why don&#8217;t you want data replication? Because all of the data you&#8217;ll be storing in your database adds up. Suppose you have 5 Kb of data that gets replicated needlessly for every single player of your game. Your game moves along just fine, and slowly grows &#8211; until it gets picked up by a site like Digg or Boing Boing &#8211; at which point you have thousands of registrations in a single day. Suddenly, your playerbase has gone from being manageable(1000) to <b>huge</b>! And this is what will happen when you have data replication:</p>

<div class="wp_syntax"><div class="code"><pre class="math" style="font-family:monospace;">1000 players x 5 Kb = 5000 Kb (Roughly 5Mb)
100000 players x 5 Kb = 500000 Kb (Roughly 500Mb!)</pre></div></div>

<p>Sure, 5 Mb of extra data is managable. But is 500?</p>
<p>That&#8217;s why you need to design your database properly. The less data you have replicated accross your database, the less problems you&#8217;ll encounter later on. Reducing data replication also helps when it comes to updating things &#8211; instead of having to update data in multiple locations, you can just update it in one place &#8211; and know for certain that wherever the data is accessed, it will be up to date.</p>
<p>With that in mind, let&#8217;s start designing a basic table structure for a browsergame.</p>
<p>We&#8217;re going to need users. And users will need a username, a password, and a unique ID(so that we can link them to things). For now, that&#8217;s all we&#8217;ll give our users:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><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 varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">250</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	password varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</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></td></tr></table></div>

<p>If you run that pre under mysql, you&#8217;ll have a freshly created <b>users</b> table to play with. You might be wondering what the <b>PRIMARY KEY</b> line does &#8211; basically, it forces each row to have a unique value in that column. This will help ensure that we don&#8217;t ever have any conflicts like trying to create two different users with an id of &#8216;6&#8242;, for example. You can check out the <a href='http://en.wikipedia.org/wiki/Primary_key'>Wikipedia article</a> for more information about primary keys.</p>
<p>So now we have a <b>users</b> table. What else should our game have?</p>
<p>Most games have some sort of inventory that their players have, that they can use to store items in. Let&#8217;s set up tables for the items and the user inventories:</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
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> 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>
	name varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">200</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>;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> user_inventory <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>
	item_id int<span style="color: #66cc66;">,</span>
	user_id 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></td></tr></table></div>

<p>And now we have all the tables in place to keep track of our users, and their respective inventories, with minimal data replication.</p>
<p>Suppose that, in our hypothetical game, the player picks up the <i>Vorpal Sword of Hypothetical Existence</i>. In order to add it to the player&#8217;s inventory, all we&#8217;d need to do is figure out what ID the Vorpal Sword had, and then add a new row(or update a row if they already had one of it) inside <i>user_inventory</i>.</p>
<p>The real benefit appears when it comes time to update something, however.</p>
<p>Let&#8217;s say that after your game&#8217;s userbase exploded, someone happened to find a bug: the Vorpal Sword, when used against a certain enemy, was <b>way too powerful</b>. You need to fix that, as fast as you can.</p>
<p>What do you do? Thanks to good database design, you only need to update it in one place! You can go into <i>items</i>, find the Vorpal Sword&#8217;s unique ID, and then update whatever attribute is causing the problem. You could even rename it, to the <i>Nerfed Sword of Hypothetical Existence</i> or something. </p>
<p>Because the important data for each item in the database is only stored in one central area, it&#8217;s easy to update it. But could you imagine what it would be like if you wanted to change the Vorpal Sword&#8217;s name, and it was stored inside user_inventory? For <strong>every single user who had one</strong>, you would need to change the name.</p>
<p>In the previous scenario, which would you prefer? Having to update rows upon rows of data, or just one? I know I would prefer to only update one, and I hope this has helped to communicate what you stand to gain by designing your database in such a way so that you only ever need to update one row.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/04/15/designing-your-database/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

