<?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; optimization</title>
	<atom:link href="http://buildingbrowsergames.com/category/design/optimization/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>Quick &amp; Dirty Rails Scaling Tips for PBBG&#8217;s</title>
		<link>http://buildingbrowsergames.com/2009/01/02/quick-dirty-rails-scaling-tips-for-pbbgs/</link>
		<comments>http://buildingbrowsergames.com/2009/01/02/quick-dirty-rails-scaling-tips-for-pbbgs/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 14:00:00 +0000</pubDate>
		<dc:creator>bsharpe</dc:creator>
				<category><![CDATA[optimization]]></category>
		<category><![CDATA[rubyonrails]]></category>
		<category><![CDATA[scaling]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=647</guid>
		<description><![CDATA[Rails-based PBBG's can scale to handle the load that Facebook can generate.]]></description>
			<content:encoded><![CDATA[<p>I wrote a PBBG in Rails that lives on Facebook, so I&#8217;ve had some scaling issues to deal with.   Here are some tips I collected along the way on scaling Rails.</p>
<h3>Serve statics from somewhere else</h3>
<p>In the beginning, letting your Rails setup serve everything is very easy.  But as your game grows in popularity, you&#8217;ll notice that your app spends a lot of time serving up things that never change.</p>
<p>The first thing we did was separate out all the static images onto a separate server running nginx.   Nginx is notoriously fast at serving static content and it did a good job for us.  This left our Rails instances to serve only game-related activities.</p>
<p>Another useful bit was using a plugin called <a href="http://code.google.com/p/bundle-fu/">bundle_fu</a>.  Bundle_fu takes all the javascrips and stylesheets you use in your app and creates a single file for the browser to download.   So, instead of the browser having to make 6 connections to get all those pieces, it makes 1.  This functionality is built into Rails since version 2.0.</p>
<h3>Optimize your environment</h3>
<p>Initially, we ran Apache proxying to 5 to 10 mongrel servers running Rails.  Then we switched to Nginx/mongrels which gave us a bit of speed and a bit of memory back, after doing some more searching we eventually switched entirely to the Litespeed webserver with no mongrels.  <a href="http://www.litespeedtech.com/">Litespeed</a> is an awesome product and we have had rock solid performance with it for the last year.   Although, all my latest Rails deployments have been with Apache &amp; mod_rails (Passenger) running with the <a href="http://www.rubyenterpriseedition.com/">Ruby Enterprise Edition</a>.</p>
<p>One big upside to Litespeed and <a href="http://www.modrails.com/">Passenger</a> is that you don&#8217;t have to manage mongrels anymore and restarting the website is super fast.  Also, <a href="http://www.rubyenterpriseedition.com/">Ruby Enterprise Edition</a> (REE) can reduce your memory requirements up to 30%.</p>
<h3>Memcached</h3>
<p>I think the biggest anecdotal speed increase we got was from integrating support for <a href="http://www.danga.com/memcached/">memcached</a>.   It was as simple as adding the acts_as_cached plugin and marking a few models to be cached.   From there, we began optimizing which models were cached for the best performance.</p>
<h3>Watch for slow queries</h3>
<p>Edit your mysql.cnf file to start logging slow queries and then watch that log like a hawk.  When you see a query that isn&#8217;t using an index, make sure you add the appropriate index to get that query to be fast again.   This won&#8217;t help much if the query only runs once a day, but if it runs every few seconds &#8212; you&#8217;ll notice the difference.</p>
<h3>Throttling the game</h3>
<p>Early on when there were only a few hundred people in our game we added a bunch of notifications to our chat system so that people would know that others were there and something was happening.    Crank that up to several thousand people and those notifications are nothing but annoying.   So, we added code that checked for the number of currently online people and throttled those informative messages when things got busy and brought them back when things calmed down again.  This made a big improvement in the quality of play during busy times.</p>
<p>These are just a few of the things we tried, but they were the most successful at improving the performance of our game.</p>
<p>If you&#8217;d like to see it, browse over to <a href="http://www.friendsandfoesstudios.com/toothandclaw">Tooth &amp; Claw</a></p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2009/01/02/quick-dirty-rails-scaling-tips-for-pbbgs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>Scalability is not your biggest concern, so stop acting like it is</title>
		<link>http://buildingbrowsergames.com/2008/06/20/scalability-is-not-your-biggest-concern-so-stop-acting-like-it-is/</link>
		<comments>http://buildingbrowsergames.com/2008/06/20/scalability-is-not-your-biggest-concern-so-stop-acting-like-it-is/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 14:00:02 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=68</guid>
		<description><![CDATA[I can&#8217;t count the number of times that I&#8217;ve heard things like &#8216;I was thinking of doing &#60;insert approach here&#62;, but heard that it doesn&#8217;t scale well once you hit more than about 1000 users&#8217;. It happens a lot. And you know why it happens? Because people who are new to developing think that how [...]]]></description>
			<content:encoded><![CDATA[<p>I can&#8217;t count the number of times that I&#8217;ve heard things like &#8216;I was thinking of doing &lt;insert approach here&gt;, but heard that it doesn&#8217;t scale well once you hit more than about 1000 users&#8217;. It happens <strong>a lot</strong>. And you know why it happens? Because people who are new to developing think that how well their system scales is a big deal. I have a secret piece of information for you: <strong>scalability&#8217;s not the big deal you think it is</strong>.</p>
<p>At the time of this writing, <a href='http://twitter.com'>Twitter</a> is having some scaling problems. Twitter is using Ruby on Rails for their service, and a lot of their problems are being blamed on the fact that Rails apparently does not scale well to having millions of users. This has led a lot of new and prospective developers to choose something other than Rails, based on the statement that &#8220;Rails doesn&#8217;t scale&#8221;. But the reality is, Twitter is <strong>huge</strong>. And your game is not. There are users on Twitter with over 1500 followers &#8211; chances are, your game doesn&#8217;t even have that many users if you just launched it.</p>
<p>Scalability isn&#8217;t something you should be worrying about when you&#8217;re first starting out. You need to attract users, and keep them. As long as your game can handle 100+ users at once, you don&#8217;t need to worry about scaling. And trust me, <strong>most</strong> things can handle over a hundred users at once.</p>
<p>Something like 3/4&#8217;s of game projects that are started never see the light of day. When you&#8217;re first building your game, you need to focus on getting something out the door and playable &#8211; not making sure it&#8217;s absolutely perfect. That&#8217;s what the testing period and your initial playerbase will help you get figured out. Most of the other aspects of building your game aren&#8217;t a big deal &#8211; just get the original <strong>out there</strong>! Once you have something that people are playing, you&#8217;ll be able to evalulate it better and see what areas you can improve in &#8211; and hey, if your playerbase suddenly explodes, you&#8217;ll get to learn about how to make your game scale, too. But please, <strong>please</strong> &#8211; <em>stop treating scalability like it&#8217;s your biggest concern</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/06/20/scalability-is-not-your-biggest-concern-so-stop-acting-like-it-is/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

