<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0UFR3Yzeyp7ImA9WhBSFEs.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034</id><updated>2013-02-21T08:46:56.883-08:00</updated><category term="opengles2.0" /><category term="FileIO" /><category term="ray tracing" /><category term="debugging" /><category term="html5" /><category term="books" /><category term="blending" /><category term="development" /><category term="graphics" /><category term="games" /><category term="memory" /><category term="Chrome Web Store" /><category term="networking" /><category term="industry" /><category term="threading" /><category term="compression" /><category term="virtual memory" /><category term="3D" /><category term="Chrome" /><category term="performance" /><category term="NaCl" /><category term="Native Client" /><category term="G+" /><category term="alpha blending" /><category term="management" /><category term="distribution" /><category term="google" /><title>The Workbench</title><subtitle type="html">"If at first, the idea is not absurd, then there is no hope for it"</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://mainroach.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>69</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/TheWorkbench" /><feedburner:info uri="theworkbench" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A0IERHo5eSp7ImA9WhNaFEs.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-6620421633064155227</id><published>2013-01-29T06:18:00.000-08:00</published><updated>2013-01-29T06:25:05.421-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-29T06:25:05.421-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="industry" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>The past and future of game development education</title><content type="html">&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.21896292525343597" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;With most things, when you get to the end of an adventure, you start thinking about the beginning, which for me, started waaaay before our &lt;/span&gt;&lt;a href="https://www.udacity.com/course/cs255"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;upcoming UDACITY &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;course on HTML5 Game Development.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-r6lNlqUczkw/UQfZas87ZDI/AAAAAAAAAOo/HmBQjMUkPBs/s1600/professor_layton.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-r6lNlqUczkw/UQfZas87ZDI/AAAAAAAAAOo/HmBQjMUkPBs/s320/professor_layton.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Education has always been an important portion of my career. Back in the early 90’s, when I started getting into game-development, education on the subject didn’t publicly exist; I had to teach myself what was needed through scraping together tutorials, Quake 1 / 2 source code, and hounding the &lt;/span&gt;&lt;a href="http://gamedev.net/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;gamedev.net&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; forums. It was slow, painful, lonely, annoying work, and the results were often hit and miss. By the time I hit college my obsession had driven me from a novice to a self-educated semi-stable games-programmer, which caused nothing but grief for my &lt;/span&gt;&lt;a href="http://www.cs.tcu.edu/faculty.htm"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;CS professors&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; (looking back, I greatly apologize to all of them ;)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The constant lamentation that I had during my self-education was the isolation. Honestly if it wasn't for a handful of contributors on the &lt;/span&gt;&lt;a href="http://flipcode.org/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;flipcode.org&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; pages and &lt;/span&gt;&lt;a href="http://gamedev.net/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;GameDev.net&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; forums, my career in Game development would never have happened.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;That’s why I jumped at the opportunity to work as a part-time Adjunct professor at &lt;/span&gt;&lt;a href="http://guildhall.smu.edu/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;SMU Guildhall school for game development&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;; Firstly I was impressed that this school even happened: you had heard of specialty schools like &lt;/span&gt;&lt;a href="https://www.digipen.edu/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;DigiPen&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and &lt;/span&gt;&lt;a href="http://www.fullsail.edu/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Full Sail&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, which were mostly specialty technical schools, but an accredited university picking up game dev? Wow. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Secondly, I couldn't help but see myself in the process; If I had some formal system of grizzled developers educating me on game dev, I might have been a better developer, faster. In some ways, this opportunity would be a way to try and help these pending game-developers with mentor-ship that I never had. I spent a great &amp;nbsp;4 years working there, teaching courses on Math, Physics, Graphics, and Concurrent programming. During that time, I was able to connect with hundreds of students and bring to them knowledge of all the crazy &lt;/span&gt;&lt;a href="http://www.introgamedev.com/resource_gpg7.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;game-dev stuff &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;that was stuck into my head. Quite frankly, I loved working with the SMU staff, and was really sad to have to move on from that chapter in my career.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;I also found during that time, &lt;/span&gt;&lt;a href="http://www.gameenginegems.net/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Engineering in Game Development&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; is the most unique, difficult, and complex skill set across disciplines for programming; It’s very hard to find a set of programmers that have to produce &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=P5ORTIHfBWQ"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;as much content&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; in a short &lt;/span&gt;&lt;a href="http://freesdk.crydev.net/display/SDKDOC2/Rendering+Performance+Guidelines"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;millisecond frame time&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. Seriously, think about it; an &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=SEKZ15Q-TM0"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;RTS &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;has to do &lt;/span&gt;&lt;a href="http://code.activestate.com/recipes/577457-a-star-shortest-path-algorithm/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;pathing&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Client-side_prediction"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;network prediction&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.havok.com/products/physics"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;physics/collision detection&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.unrealengine.com/en/features/animation/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;animation&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=5h4QgDBwQhc"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;visibility culling&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=s2yRYpPqL9k"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;scene setup&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=vPQ3BbuYVh8"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;lighting&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=X6OwBWkmspc"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;shadowing&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and finally &lt;/span&gt;&lt;a href="http://vimeo.com/25953235"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;graphics submission/rendering&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;; in 30ms. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;In contrast, a web-developer is considered as doing &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;really good&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt; if their site &lt;/span&gt;&lt;a href="http://blog.kissmetrics.com/loading-time/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;loads in under 3 &lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;seconds&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;. &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Game dev is &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;hard&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and most times &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;unrewarding&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; considering that most game-players won’t spend their time talking about your long hours optimizing the terrain rendering, and instead will complain about a 0.02s change in the &lt;/span&gt;&lt;a href="http://us.battle.net/wow/en/forum/topic/7416066576"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;cast-rate of your Druid build....&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; So part of teaching game developers involves a bit of ego-breaking; You have to let them know that any of their work is only part of the larger picture. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Back to the point, fast forward 3 years (Seriously? WTF?) I’m sitting in a cafe at &lt;/span&gt;&lt;a href="http://google.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Google’s &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Mountain View campus where I’ve spent the past year as a &lt;/span&gt;&lt;a href="https://code.google.com/team/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Developer Advocate&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, writing code, planning strategically, and largely &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;educating developers&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. &lt;/span&gt;&lt;a href="https://plus.sandbox.google.com/u/0/112811650518962267774/posts"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;+Peter Lubbers&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, and I were chatting about how to reach more developers on best practices in web-game development, when he said:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;“What if we did a &lt;/span&gt;&lt;a href="https://www.udacity.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;UDACITY&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt; course on making an HTML5 game?” &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;I’m not really sure I ever agreed to do any work, or formally asked to be part of the project, I just started rambling on about curriculum, time frames, and started mail-bombing Peter with ideas and code snippets. We had recently wrapped up our exercise building the &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=Prkyd5n0P7k"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;HTML5 PvP game GRITS&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, so there was plenty of content available, and it seemed like the perfect chance to bring that knowledge to more developers.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Fast forward 4 months to January 2013, where &lt;/span&gt;&lt;a href="https://plus.google.com/105495497383489174073/posts"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;+Sean Bennet&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and &lt;/span&gt;&lt;a href="https://plus.google.com/104524032874535098840/posts"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;+Calvin Hu&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; are hunched over a video timeline, trying to find the best way to edit out my usage of the phrase “&lt;/span&gt;&lt;a href="http://xkcd.com/366/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Your mom&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;” from a &lt;/span&gt;&lt;a href="https://www.udacity.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;UDACITY&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; video snippet for our &lt;/span&gt;&lt;a href="https://www.udacity.com/course/cs255"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;upcoming class&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;; meanwhile Peter is syntax checking all the code snippets, grumbling about how awful our code looks. It’s a massive understatement to say that working with the &lt;/span&gt;&lt;a href="https://www.udacity.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;UDACITY&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; folks has been an amazing experience; Peter, Sean and Calvin are world-class superstars to work with, and have made creation of the course a fun and awesome process; Those guys built this course, I just opened my mouth and vomited out all the crazy game dev stuff locked in my head. The entire endeavor has proven something I’ve been thinking for a while now, standard-education for game-development is a difficult path to climb. Game devs are young, energetic, ambitious, impatient and generally focus on challenging the status quo; they need their attention funneled into an intense education curriculum to get them up and moving fast. SMU, DigiPen, FullSail and UDACITY are changing how developers make games, in the &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;right ways&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;So what’s the course about? Directly we've broken down the &lt;/span&gt;&lt;a href="https://code.google.com/p/gritsgame/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;GRITS&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; framework into a Client-side, and Server-side curriculum, and this first course focuses entirely on the client. We tried to approach the content to present all the tips, tricks, tools and ‘useless info’ that’s needed to make a fast, functional, client-side-only web game. The team has worked in overdrive mode to make sure that we present the right amount &lt;/span&gt;&lt;a href="http://gameenginegems.net/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;education&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://tedxpeachtree.com/program/2012-presenters/fake-grimlock/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;humor&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, and great &lt;/span&gt;&lt;a href="http://www.beyond3d.com/content/articles/8"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;games-industry stories&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; to keep people interested. (also, trying to balance the right amount of &lt;/span&gt;&lt;a href="https://twitter.com/fakegrimlock"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;@FAKEGRIMLOCK&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; references...)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;So if you’re looking to start making HTML5 games, &lt;/span&gt;&lt;a href="https://www.udacity.com/course/cs255"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;sign up for the class now&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;! If we’re lucky, and there’s enough feedback to warrant it, we just &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;might&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; be able to do the 2nd course, where we teach you how to write all the server-side portions of the GRITS code base; So no pressure, but if you like the course, tell your friends ;)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The class is set to go live on &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/February_4"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;February 4th&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, followed up by a series of live-streamed weekly study groups, from the &lt;/span&gt;&lt;a href="https://maps.google.com/maps?q=google+san+francisco&amp;amp;fb=1&amp;amp;gl=us&amp;amp;hq=google&amp;amp;hnear=0x80859a6d00690021:0x4a501367f076adff,San+Francisco,+CA&amp;amp;cid=0,0,17700118300110021036&amp;amp;t=m&amp;amp;z=16&amp;amp;iwloc=A"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Google offices in San Francisco&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;; So if you’re in the area, make sure you stop by for some face-to-face tech talk on a weekly basis!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Until then, here’s a nice &lt;/span&gt;&lt;a href="http://youtu.be/PWJRPh_HYaw"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;blooper reel&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; for you folks to sink your teeth into :)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/PWN3_-yL12g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/6620421633064155227/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=6620421633064155227" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/6620421633064155227?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/6620421633064155227?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/PWN3_-yL12g/the-past-and-future-of-game-development.html" title="The past and future of game development education" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-r6lNlqUczkw/UQfZas87ZDI/AAAAAAAAAOo/HmBQjMUkPBs/s72-c/professor_layton.jpg" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2013/01/the-past-and-future-of-game-development.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYFSXw7eyp7ImA9WhNWF0g.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-8467577585944520025</id><published>2012-12-17T06:54:00.002-08:00</published><updated>2012-12-17T06:55:18.203-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-17T06:55:18.203-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="development" /><category scheme="http://www.blogger.com/atom/ns#" term="industry" /><category scheme="http://www.blogger.com/atom/ns#" term="management" /><title>What GameDevs should learn from Nate Silver</title><content type="html">&lt;div&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;One of the most critical points of &lt;/span&gt;&lt;a href="http://mainroach.blogspot.com/2012/11/feeding-iteration-engine.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Feeding the Iteration Machine&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; is taking a numerical look at what your product is doing. You can’t truly iterate-to-improve your idea unless you know &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;what’s wrong&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; with it. As a game dev, you need to cut through the jargon and gut feelings and embrace big-data to develop a better game.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-hDQh_HL5pPg/UM8yUdkJ5FI/AAAAAAAAAOM/JQtPnrQzNyU/s1600/Big-Data-disguises-digital-doubts-UU1M91QI-x-large.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="235" src="http://1.bp.blogspot.com/-hDQh_HL5pPg/UM8yUdkJ5FI/AAAAAAAAAOM/JQtPnrQzNyU/s320/Big-Data-disguises-digital-doubts-UU1M91QI-x-large.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 dir="ltr"&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal;"&gt;&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Viewing the future using numbers&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal;"&gt;&lt;a href="https://www.google.com/search?q=nate+silver&amp;amp;oq=nate+silver"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Nate Silver&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; recently gained fame after he &lt;/span&gt;&lt;a href="http://mashable.com/2012/11/07/nate-silver-wins/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;accurately predicted&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; 50/50 states for the 2012 US presidential election, (following his 2008 prediction of 49/50 states, where he gained less fame for some odd reason). This was a fantastic opportunity for big-data to get back into the light of the lives of common, everyday lives. It was amazing to see how Nate was able to use data prediction and modeling, a counter-intuitive process in a political system that is still driven by people following their gut feelings. And much like &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Moneyball"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Moneyball&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, it’s apparent that the political system will never be the same; for those of us in Silicon valley, this was old news, but for most people, what Nate did was magic:&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-align: center; text-indent: 36pt;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;img height="570px;" src="https://lh5.googleusercontent.com/tW5prRymMjt3RFDZiZlg2WN_Is5AcHtRaQY5UsDFKObj2qc_bDU6I00lAt2TiEkbXxuxE8-qnqq4K88VqPhct36LmYIGm_wzpYSRSEma3YN5Pv4415w" width="468px;" /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The reality is that &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Big_data"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;big data&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; rules the 21st century, and any business developer that’s not utilizing every statistic available is immediately at a disadvantage; you’re flying blind. That’s one of the great things about having your business be digital, you get input and feedback instantly.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.15536386938765645"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.15536386938765645"&gt;&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;This type of statistical analysis &lt;/span&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;doesn't just extend to your product in the wild, but should also be used to track the information about your game in pre production too. Utilizing big-data in order to track your game’s frame rate, stability, and content-churn are all great predictors. We've seen this being used to great success for &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.wired.co.uk/magazine/archive/2012/01/features/test-test-test?page=all"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;social casual games&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, and even &lt;/span&gt;&lt;a href="http://www.coolinfographics.com/blog/2009/1/12/halo-3-heatmaps.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;hardcore FPS games&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;. Directly, you shouldn't be asking &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;if&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; your game should track data, but rather &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;what data should I track&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.15536386938765645"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Big data checklist&lt;/span&gt;&lt;/h2&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Here’s a simple data-checklist on the things you should be tracking and how you should be responding to it.&lt;/span&gt;&lt;br /&gt;&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;What you should be tracking:&lt;/span&gt;&lt;/h3&gt;
&lt;br /&gt;&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Stability each day&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Track your crashes, against platform, region, map, callstacks etc.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Track a user click-stream&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;What are they clicking on the most, what &lt;/span&gt;&lt;span style="font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;aren’t&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; they clicking on?&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;How do you &lt;/span&gt;&lt;a href="http://www.amazon.com/Web-Analytics-2-0-Accountability-Centricity/dp/0470529393"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;analyze &lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;it?&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Track a user purchase profile&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;If you’re using a freemium style, it’s important you not expecting every user to monetize the same way. Create &lt;/span&gt;&lt;a href="http://ufert.se/user-acquisition/mobile-game-monetization/the-average-user-doesnt-exist-in-freemium-gamin/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;a profile&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; for your users and react to them properly. use location&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;How are users discovering your game&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Do you know how you’re acquiring users? is your marketing campaign working? Should you be spending advertising money on &lt;/span&gt;&lt;a href="http://kotaku.com/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;kotaku.com&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;, or &lt;/span&gt;&lt;a href="http://thebump.com/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;thebumb.com&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;?&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Track player progress&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;How many players make it to level 7? How many players buy item Y?&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;What you’ll need to use the data properly&lt;/span&gt;&lt;/h3&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Automatically Generate daily reports&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Generate reports from your data each day.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Make sure that you can easily access your reports. If it’s too difficult, then you’ll ignore it over time, or not get a chance to look the data the right way. You’ll ignore the signals before it’s too late.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Availability to drill-down as needed&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Make sure that your data isn’t static, and that there’s ways to look at the information in different ways. It’s not beneficial if it takes an extra 3 days to track a new metric, or chart a graph plot against another value.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;A flexible backend&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Make sure your backend can easily accept new events, or discard old events.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Make sure your backend can easily be duplicated / redundantly stored; You should be able to track all the data for your game since inception.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Semi-regular “What does this mean” sessions&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;It’s important to schedule semi-regular sessions with the stakeholders of the product to determine what the data means. After all, there’s lies, damn lies, and statistics, and it’s important to get multiple validated viewpoints on the data coming in before making any actions&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Ability to push builds quickly&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;We’ve already discussed how important this is for the life of your game&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Big data fixes failures&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal; text-indent: 0px;"&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Failure is not an option, it’s a requirement. If you’re a game developer, and expecting to not fail, then you’re delusional. The best studios hide these failures from being commercial by moving the iteration process into something that’s not tied to their bottom line (internal testing, beta tests etc)&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The truth is, that if you fail,and &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;don’t know why&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; then you’re going to keep failing, and success isn’t coming any time sooner. Too many game devs will fail on a product, and not know why; they end up blaming tangential things which may not be correlated. Once the failure has occurred, you should know why, and be able to fix it next time.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;“Insanity is the act of doing the same thing but expecting a different result”&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;
&lt;b id="internal-source-marker_0.15536386938765645" style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Make sure you know why you’re failing, so you can stop doing it.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;
&lt;b style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/span&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/9nSECaTlQnI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/8467577585944520025/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=8467577585944520025" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/8467577585944520025?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/8467577585944520025?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/9nSECaTlQnI/what-gamedevs-should-learn-from-nate.html" title="What GameDevs should learn from Nate Silver" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-hDQh_HL5pPg/UM8yUdkJ5FI/AAAAAAAAAOM/JQtPnrQzNyU/s72-c/Big-Data-disguises-digital-doubts-UU1M91QI-x-large.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/12/what-gamedevs-should-learn-from-nate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcHQXo7fyp7ImA9WhNQGUk.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-3855903559830842865</id><published>2012-11-26T06:35:00.000-08:00</published><updated>2012-11-26T07:00:30.407-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-26T07:00:30.407-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="development" /><category scheme="http://www.blogger.com/atom/ns#" term="industry" /><category scheme="http://www.blogger.com/atom/ns#" term="management" /><title>Feeding the iteration engine</title><content type="html">&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-align: left; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;During my humble time in the games industry, the most prominent feedback I would receive about ‘how to make successful games’ was &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Iteration"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;‘iteration’&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;; &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;that is, constantly polishing, grinding and working on a video game would continue to make it better, more focused, and more qualitative. One problem with this, however, was that there was never a &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;methodology&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; behind it; but rather a wandering vague guideline to &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;iterate to be great&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-align: left; text-indent: 36pt;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" height="232" src="http://3.bp.blogspot.com/_jhiaT6dZgx0/TOYCauXc-mI/AAAAAAAADew/r-XPL339u0E/s320/Leonardo+da+Vinci+Codex+Water.jpg" width="320" /&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-align: center; text-indent: 36pt;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;As with most things, the games industry didn’t create this mantra, and certainly web-companies have done a better job at embracing this concept in their battle cry “&lt;/span&gt;&lt;a href="http://www.codinghorror.com/blog/2009/12/version-1-sucks-but-ship-it-anyway.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;ship early, ship often.&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;” This methodology has been proven multiple times as a cornerstone of the creative process. &lt;/span&gt;&lt;a href="http://37signals.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;37Signals&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;’ book&lt;/span&gt;&lt;a href="http://37signals.com/rework"&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Rework&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, a clear counter-culture process is presented for product development:&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;
&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;
&lt;ol style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;
&lt;li dir="ltr" style="color: #222222; font-family: Arial; font-size: 15px; list-style-type: decimal; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Ship a product super early&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="color: #222222; font-family: Arial; font-size: 15px; list-style-type: decimal; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Let the users tell you what’s wrong and what needs to be fixed&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="color: #222222; font-family: Arial; font-size: 15px; list-style-type: decimal; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Fix all the stuff in #2&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="color: #222222; font-family: Arial; font-size: 15px; list-style-type: decimal; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Repeat&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="color: #222222; font-family: Arial; font-size: 15px; list-style-type: decimal; vertical-align: baseline;"&gt;&lt;a href="http://www.youtube.com/watch?v=tO5sxLapAts"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;Profit&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/b&gt;&lt;/ol&gt;
&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;
&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Lean startups have been adopting this philosophy more aggressively lately; with their champion &lt;/span&gt;&lt;a href="http://fakegrimlock.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;FakeGrimlock&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; offering &lt;/span&gt;&lt;a href="https://twitter.com/FAKEGRIMLOCK"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;sound advice&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; in bite size form:&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;
&lt;div style="text-align: left;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;img height="171px;" src="https://lh6.googleusercontent.com/Mta4rIfohLSza5zamRAl8gxaE3ajIthfHS8Z6y98t4meNQRcxsoe-IuKyEiTxzCLtZ6TG3TlijHxqeAIVOAd3wCXXDWIv2Th4XnWL70b2YkWHc2ukVg" width="548px;" /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-size: x-small;"&gt;Make sure that you're on FAKEGRIMLOCK's &lt;a href="http://fakegrimlock.com/2011/11/rules-for-noeatfriday-2/"&gt;#NOEATFRIDAY&lt;/a&gt; list; As he says "you on the list, or you on the run."&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;In the modern digital age, iteration is sound advice, however once adopted, you’ll quickly find that the provided tomes contain plenty of information on the &lt;/span&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;why&lt;/span&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; but quite lacking on the &lt;/span&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;how&lt;/span&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. There’s a disconnect between the dogmatic message and the mechanical operation. Especially in game development, where most often, devs ignore proper iteration during pre-production and production phases,focusing only on beta/post-ship feedback; This is a great shame, after all, content creators should have the ability to iterate on their craft as well.&lt;/span&gt;&lt;/div&gt;
&lt;h2 dir="ltr"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Iterative gaming wins&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Often, game developers are adverse to early feedback of their product, fearing that if exposed to the criticism of the outside world too early, will cause the game to fail. Interestingly enough, all the data shows the contrary, that games which ship early in alpha, beta, and continue to grind and make improvements in the public eye have been shown to have &lt;/span&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;stronger&lt;/span&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; user engagement, and have MORE success over time.&lt;/span&gt;&lt;a href="https://minecraft.net/"&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Minecraft&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and&lt;/span&gt;&lt;a href="http://www.realmofthemadgod.com/"&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Realm of the Mad God&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; are perfect success stories in this space, having launched in early forms, and didn’t see success until being in development which included the public feedback loop, which quickly vaulted them into massive success stories.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;While desktop and Web games have this ability directly, mobile game development exhibits this phenomena in a different way; where smaller companies, trying to power-level the limited space distribution platform, ship multiple games in a short time to attempt to stay on the top of the rankings. Implicitly, this creates a user-feedback cycle; &lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;This fast amount of iteration allowed the developer to get a great deal more feedback about their ecosystem and habits of their customers, in addition to doing a &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Breadth-first_search"&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;breadth first search&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; on what content will become popular. An often difficult task to &lt;/span&gt;&lt;a href="http://www.amazon.com/dp/159420411X"&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;predict&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, given the general random nature of the marketplaces.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Poster-child success story&lt;/span&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.rovio.angrybirds"&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Angry Birds&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; is heralded as the secret sauce that caused the mobile gaming boom, but often forgotten is that developer&lt;/span&gt;&lt;a href="http://www.rovio.com/"&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Rovio Entertainment&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; had shipped&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Rovio_Entertainment"&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;30 other mobile games over the course of 3 years&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. And this has proven to be a process that works, with early 2012 success story&lt;/span&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.imangi.templerun&amp;amp;hl=en"&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Temple Run&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; being the 10th title from game developer&lt;/span&gt;&lt;a href="http://www.imangistudios.com/"&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Imangi&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;on the mobile platform, resulting in over 100 million downloads of the app.&lt;/span&gt;&lt;/div&gt;
&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h2 dir="ltr"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Iteration means focusing on what counts&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;This approach to development methodology can be a breath of fresh air for most game studios who complain about feature creep. As &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Donald_Knuth"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Donald Knuth&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; was once attributed to saying "&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Program_optimization"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;premature optimization&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; is the root of all evil.” And web developers / lean startups are right on target with this effort. Rather than spending years grinding internally, only focusing on internal feedback about priorities and power-struggles associated with &lt;/span&gt;&lt;a href="http://search.dilbert.com/comic/Internal%20Communication"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;internal politics&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, these developers were getting their product directly into the hands of the consumers, and prioritizing feedback based upon that first. These developers don’t have the capacity to prematurely optimize; There is such strong dialogue with their potential user base, they knew exactly what to work on, and the impact it would have on the end product. Which is the important part; after all, the &lt;/span&gt;&lt;a href="http://notalwaysright.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;customers&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; are the ones keeping your company in business.&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2 dir="ltr"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Your Iteration Engine Checklist:&lt;/span&gt;&lt;/h2&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Your train to success should be driven by the iteration engine, and like any complex system, you need to understand the parameters before building anything. As such, here’s you’re iteration engine checklist:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h3 dir="ltr"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Pre Production:&lt;/span&gt;&lt;/h3&gt;
&lt;br /&gt;&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; font-weight: bold; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Make a place to keep, sort, and find iterations &amp;amp; feedback.&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt; As you start iterating and collecting feedback, you’ll soon want a log of &lt;/span&gt;&lt;span style="font-style: italic; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;what didn’t work, and why&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;. And as your project rambles on, you’ll need to refer back to that data over time, so find a &lt;/span&gt;&lt;a href="http://docs.google.com/"&gt;&lt;span style="color: #1155cc; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;good place&lt;/span&gt;&lt;/a&gt;&lt;span style="font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt; to store your successes and failures.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; font-weight: bold; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Iterate the hell out of your idea&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;. Share it with others, get their feedback; Automatically assume that you’re too close to the idea, and need others to validate it. Start with your co-developers for feedback, then slowly grow your circle to friends/family before opening up to unknown people.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Embrace a 1-off technology for prototyping. &lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Don’t be afraid to generate tech that you’re &lt;/span&gt;&lt;a href="http://2dboy.com/2009/05/27/rapid-prototyping-framework/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;going to throw away&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;; You learn a lot from those efforts. Have your designers work in &lt;/span&gt;&lt;a href="http://impactjs.com/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;HTML5&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.flashdevelop.org/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;Flash&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://unity3d.com/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;Unity&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;, or &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Microsoft_XNA"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;XNA &lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;to quickly build a prototype, and maintain a fork of their efforts so they aren’t blocked on product features. &lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Start with someone elses’ idea and make it better&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;. Some of the most successful games of all time have been more spinoffs of already successful games. &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=lqW8KdnQ-gk"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;Halo&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=YWisI2lSc_A"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;World Of Warcraft&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; and &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=lpk5U70MQBg"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;Braid&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; are great examples of this. They were able to duplicate the successful parts, fix the crummy parts, and add their own unique twists and improvements to make a much better product.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Make something fun without the features&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;. Your goal out of pre production should be to have a fun game mechanic, that feels fun without the need for millions of bells and whistles. Take this time to prove your hook, interest, and goals; the extended feature set should add to your product quality, not define it.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Clearly define what your ARE / ARE NOT.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; During iteration, it’s easy to ramble on down a path which may not be directed towards your initial goals; while sometimes this can yield amazing success, it’s important to put an upper limit on your efforts. If you’re trying to make a platformer, don’t start programming an &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=bMxYEoG5lEQ"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;FPS&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;. Your definition of what the target is should be constantly evaluated and appear in every iterative decision process.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h3 dir="ltr"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Production:&lt;/span&gt;&lt;/h3&gt;
&lt;br /&gt;&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Design in parallel. &lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Keep designers working in the prototype build, in parallel to commercial builds. This will allow your designers to prove ideas and gameplay that won’t force new task ripples through code, art and production groups, this is a critical path that keeps feature creep at bay; You can test if something is fun without having to move heaven and earth to test it in-game.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Embrace tools for small content-creation loops. &lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Content creators should have a tight feedback loop to getting content into the game. Optimize your content creation tools to allow Artists to get content in as fast as possible, as easily as possible. Reduce the number of steps, clicks, and exports needed.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Always Be Stable Builds (ABSB).&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; Production builds should be continuous and easy to create. Make sure that you have a way to kick off manual builds, alongside automated builds that occur daily. &lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Bonus points: Make sure that the developer knows what build they are running at all times.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Double Bonus: Zip up the source code and asset trees for that build, so that you can properly roll back changes and issue tests on historic code.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Track your stats.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; Track crashes and automate testing in as many ways as possible; Make this part of your build system; Incorporate &lt;/span&gt;&lt;a href="http://code.google.com/p/googletest/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;Google’s testing unit testing framework&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;. Can you chart the FPS changes over the past month? Do you know if a checked-in asset is causing out-of-memory crashes? Where’s your memory going today?&lt;/span&gt;&lt;/li&gt;
&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: circle; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;Bonus Points: Embrace &lt;/span&gt;&lt;a href="http://d3js.org/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;great data visualization tools&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; to view your daily stats&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Don’t get comfortable with your game.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; Once you get comfortable, you’re too close to give feedback. Don’t playtest your own game too much; instead get friends, family, close testers to keep trying your game and give you feedback. Don’t let them become familiar with the game, or their feedback becomes useless. You should listen to your user feedback and iterate quickly to update your build with better content.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Make time to clean up.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; By constantly iterating, your art and code can become a mangled mass of items that don’t exist any more. Make sure that on regular intervals you’ve scheduled &lt;/span&gt;&lt;a href="https://groups.google.com/a/chromium.org/forum/?fromgroups=#!topic/chromium-os-dev/L3ES5GvSw7M"&gt;&lt;span style="color: #1155cc; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;gardening duty&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; where everyone pitches in to make sure the garden is free of goblins that will inhibit future endeavors.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h3 dir="ltr"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Post Ship:&lt;/span&gt;&lt;/h3&gt;
&lt;br /&gt;&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Create a shippable product.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; Make sure you’re extending your ABSB to the customer. There comes a point which you will need to patch up all the holes and issues before shipping a polished, stable build. Shipping unstable builds reduces the user experience and &lt;/span&gt;&lt;a href="http://8020startup.com/ship-early-and-ship-often-but-do-not-ship-any"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;does nothing but cause stress&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Ship Early.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; The only way to get feedback is to have other people play your game. Ship early versions of your game &lt;/span&gt;&lt;a href="http://www.codinghorror.com/blog/2009/12/version-1-sucks-but-ship-it-anyway.html"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;sooner than you’re comfortable doing&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;; Put your ego aside and embrace the feedback.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Ship Often.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; Make shipping updates part of your product lifecycle. &lt;/span&gt;&lt;a href="http://www.codinghorror.com/blog/2011/05/the-infinite-version.html"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;And then keep doing it&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;. Make sure that your technology &lt;a href="http://www.altdevblogaday.com/2012/11/12/a-simple-system-to-patch-your-game-content/"&gt;supports easy patching&lt;/a&gt; and &lt;a href="http://mainroach.blogspot.com/2012/11/distributing-your-game-content-via.html"&gt;content updates&lt;/a&gt;; make the user happy to see that a new patch is available.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Understand your user.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; Ensure you’re deeply tracking user-clicks and actions, &lt;/span&gt;&lt;a href="http://www.wired.co.uk/magazine/archive/2012/01/features/test-test-test?page=all"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;mining the data for meaning&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;. Issuing tests and checking results should be part of your normal process. &amp;nbsp;How many players make it to the 3rd level? How many have purchased armor? Constantly run and &lt;/span&gt;&lt;a href="http://www.smashingmagazine.com/2010/06/24/the-ultimate-guide-to-a-b-testing/"&gt;&lt;span style="color: #1155cc; vertical-align: baseline; white-space: pre-wrap;"&gt;A|B tests&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt; to find the best results. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h2 dir="ltr"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;All aboard the iteration train!&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The iteration engine can be considered a fractal algorithm. Directly you should be focusing on how to track user feedback playing the game, and then quickly respond to it in order to make better products. Truthfully though, this action extends to production and pre production as well, where you need to iterate on your ideas and content creation processes, just at a smaller level.&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The iterative engine is not about saying ‘no’, it’s about proving ‘yes’ . &lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;More importantly, it’s about proving &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;success.&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;div style="text-align: center;"&gt;
&lt;b id="internal-source-marker_0.7391951053868979" style="font-weight: normal;"&gt;&lt;img height="342px;" src="https://lh5.googleusercontent.com/sFPgoO5jxoSfFC2saRwD3JhlQ0plLhsWvgJ_rxbcAPW11b_jaVlboJPf3h9wpFqg8enfHQtETPj1PQFHAAUA3MdlHwnl9IFdhXd6mjUooj3i1WgmTH4" width="228px;" /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/b&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/QBGRKGuiT5o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/3855903559830842865/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=3855903559830842865" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/3855903559830842865?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/3855903559830842865?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/QBGRKGuiT5o/feeding-iteration-engine.html" title="Feeding the iteration engine" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_jhiaT6dZgx0/TOYCauXc-mI/AAAAAAAADew/r-XPL339u0E/s72-c/Leonardo+da+Vinci+Codex+Water.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/11/feeding-iteration-engine.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4CQX86eyp7ImA9WhNQE0k.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-2242196694664393224</id><published>2012-11-19T07:53:00.002-08:00</published><updated>2012-11-19T09:42:40.113-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-19T09:42:40.113-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="FileIO" /><category scheme="http://www.blogger.com/atom/ns#" term="distribution" /><category scheme="http://www.blogger.com/atom/ns#" term="networking" /><title>Distributing your game content via Torrenting</title><content type="html">&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.5880685446318239" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;In my &lt;/span&gt;&lt;a href="http://www.altdevblogaday.com/2012/10/22/cover-your-assets-the-cost-of-distributing-your-games-digital-content/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;previous article&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, we covered the processes to distribute your game via CDNs and the costs involved with that process. Thankfully quite a few people read the article, and a number of them pointed out to me that &lt;i&gt;torrenting&lt;/i&gt; is also a valid, and cost-effective way to distribute large game content to users too.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style="font-weight: normal;"&gt;&lt;b id="internal-source-marker_0.5880685446318239" style="font-weight: normal;"&gt;&lt;/b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="display: inline !important; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;b id="internal-source-marker_0.5880685446318239" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Which was a great point. There’s some upper limit that you’ll eventually run into when distributing your data from &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Content_delivery_network"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;CDNs&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, namely the cost involved with distribution of content. As we showed previously, this is a pretty low-cost operation overall, but if you’ve got a massively successful product, then this can create un-need costs that eat into your overhead.&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-OkzoH-u-Ln4/UKpvihyrcrI/AAAAAAAAAN0/dbfbvsIhWbo/s1600/usb_newyork.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://3.bp.blogspot.com/-OkzoH-u-Ln4/UKpvihyrcrI/AAAAAAAAAN0/dbfbvsIhWbo/s320/usb_newyork.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-indent: 48px;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Torrenting is a process that creates a &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Peer-to-peer"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Peer-To-Peer&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; network that allows your users to transfer your data files between each other, rather than solely relying on your CDN for the data transfer. This can be a great benefit to your system, as it reduces distribution costs on your side, as well as gives your users an available option if your CDN goes down: they can still get the files from each other.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Torrenting isn’t new, and large companies, like &lt;/span&gt;&lt;a href="http://marcgayle.com/blizzard-uses-bit-torrent-or-other-p2p-for-do"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Blizzard&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and &lt;/span&gt;&lt;a href="http://www.zeropaid.com/news/8938/microsoft_finally_embraces_bittorrent/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Microsoft&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; have been using it over the past few years for the very same reasons I mentioned. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red; font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;disclaimer &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;: Torrenting for piracy usage is not advocated by myself or any organizations I’m associated with. It’s an interesting technology to distribute files, and that’s where this article starts.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;h2 dir="ltr"&gt;
&lt;b style="font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;How torrenting works&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;b style="font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul style="margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;A user who wants to upload a file first creates a small torrent descriptor file that they distribute to other users by conventional means.&lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;They then make the file itself available through a BitTorrent node acting as a seed. &lt;/span&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;Those with the &lt;/span&gt;&lt;span style="background-color: white; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;torrent descriptor file&lt;/span&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt; can give it to their own BitTorrent nodes which, acting as &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Terminology_of_BitTorrent#Peer"&gt;&lt;span style="background-color: white; color: blue; vertical-align: baseline; white-space: pre-wrap;"&gt;peers&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: blue; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;or &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Terminology_of_BitTorrent#Leech"&gt;&lt;span style="background-color: white; color: blue; vertical-align: baseline; white-space: pre-wrap;"&gt;leechers&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Uploading_and_downloading"&gt;&lt;span style="background-color: white; color: blue; vertical-align: baseline; white-space: pre-wrap;"&gt;download&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: blue; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;it by connecting to the seed and/or other peers.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;The file being distributed is divided into segments called pieces. As each peer receives a new piece of the file it becomes a source (of that piece) for other peers, relieving the original seed from having to send that piece to every computer or user wishing a copy. &lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;Pieces are typically downloaded non-sequentially and are rearranged into the correct order by the BitTorrent Client, which monitors which pieces it needs, and which pieces it has and can upload to other peers.&lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt; Pieces are of the same size throughout a single download (for example a 10 MB file may be transmitted as ten 1 MB Pieces or as forty 256 KB Pieces). Due to the nature of this approach, the download of any file can be halted at any time and be resumed at a later date, without the loss of previously downloaded information, &lt;/span&gt;&lt;/li&gt;
&lt;li dir="ltr" style="font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;"&gt;&lt;span style="background-color: white; vertical-align: baseline; white-space: pre-wrap;"&gt;When a peer completely downloads a file, it becomes an additional seed. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h2 dir="ltr"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Utilizing torrenting for your game&lt;/span&gt;&lt;/h2&gt;
&lt;h3 dir="ltr"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Creating a private torrent network&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;I’m going to go out on a limb, and assume that you don’t want your game data files lounging around all over the internet; and as such, you’ll most likely want to create a private torrent system to use. I highly suggest &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;"&gt;not &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;rolling your own code here:&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;img height="132px;" src="https://lh4.googleusercontent.com/SrUXZCNFN3exsONVVQF4R3dXa36NEjhhQcOFdkLdHKEUG0CK8IQx4WId-c3GojYCLEIDnJE_5R4qDJSEAcUVRsjeKlCEr2Rf3LWMS18Kn6NwjyrYKOs" width="587px;" /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h3 dir="ltr"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Setting up a seeding server&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Rather than reinventing the wheel, you can take advantage of existing work for torrenting. For example, using &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/%CE%9CTorrent"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;uTorrent&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; will allow you to run a torrent seeder on a linux/windows box easily, which brings the question of &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;where to host the box?&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Simple web-hosting won’t suffice to create a torrent seeder, you’ll actually need a compute layer, meaning that you’ll need some machine sitting out in the intertubes. &lt;/span&gt;&lt;a href="http://www.codinghorror.com/blog/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Jeff Atwood&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; has a &lt;/span&gt;&lt;a href="http://www.codinghorror.com/blog/2012/10/building-servers-for-fun-and-prof-ok-maybe-just-for-fun.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;great article&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; on comparative costs between EC2 Compute units ($17k/yr) vs building his own high-end server for $2,750. in which he argues:&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;div dir="ltr"&gt;
&lt;table style="border-collapse: collapse; border: none; width: 624px;"&gt;&lt;colgroup&gt;&lt;col width="*"&gt;&lt;/col&gt;&lt;/colgroup&gt;&lt;tbody&gt;
&lt;tr style="height: 0px;"&gt;&lt;td style="border: 1px solid rgb(0, 0, 0); padding: 7px; vertical-align: top;"&gt;&lt;span style="background-color: white; color: #333333; font-family: Calibri; font-size: 16px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;Of course, that figure doesn't include the cost in time to build and rack the server, the &lt;/span&gt;&lt;a href="http://blog.pinboard.in/2012/06/going_colo/"&gt;&lt;span style="background-color: white; color: #a2427c; font-family: Calibri; font-size: 16px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;cost of colocating the server&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; color: #333333; font-family: Calibri; font-size: 16px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;, and the ongoing cost of managing and maintaining the server. But I humbly submit that the one-time cost of paying for three of these servers, plus the cost of colocation, plus a bunch of extra money on top to cover provisioning and maintenance and support, will still be significantly less than $17,000 for a single year of EC2 web application hosting. &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Of which, you have a separate question: How much performance do I really need? Jeff is certainly targeting &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;web applications&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; which need to execute high performance computations, where a simple torrent seeder will only need a minor fraction of that performance, since the lion’s share of the file transfer process is between peers.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;This limited-performance need may allow you to branch out to other types of server technologies, for example &lt;/span&gt;&lt;a href="http://repo.cat-v.org/atrack/"&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;torrent-server&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; is a torrent seeder that runs on &lt;/span&gt;&lt;a href="https://developers.google.com/appengine/"&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Google App Engine&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and allows you to scale production, reduce costs, and avoid having to maintain a large server infrastructure. Which, as a small developer could be a great way to get started.&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h3 dir="ltr"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Adding a torrent system to your game client&lt;/span&gt;&lt;span style="background-color: white; color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="background-color: white; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;As we discussed in the article about patching, you’ll most likely have some separate system for bringing new build data off the web, and caching it locally, which is a great place to put tons of heavy torrenting / transfer code that you won’t want munging up your game code. Which should be an easy process, a &lt;/span&gt;&lt;a href="http://code.google.com/p/libtorrent/"&gt;&lt;span style="background-color: white; color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;quick search&lt;/span&gt;&lt;/a&gt;&lt;span style="background-color: white; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; yields hundreds of client libraries for doing torrenting, most of which are open source, and exist in whatever language you happen to be targeting. Once integrated, a simple modification to your file-transfer logic should allow your client to wait for file completion, regardless if it’s coming from a torrent network, or a CDN.&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;One down side is that to use this type of setup, you need the &lt;/span&gt;&lt;a href="http://marcgayle.com/blizzard-uses-bit-torrent-or-other-p2p-for-do"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;user to agree&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; to allow their bandwidth to be used for the greater good. Otherwise you can run into some fussy &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;legal&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; problems; which I am not allowed to comment about, &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;because I am not legal council&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h2 dir="ltr"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;When to torrent, when to CDN?&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;It’s worth noting that torrenting may provide a worse experience for distributing content to your users. Especially if the number of seeds are low, or if connections between peers is less than ideal. There’s certainly a break-even point, in which it makes more sense to utilize one over the other, or even find ways to use both where ideal. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;For example, the &lt;/span&gt;&lt;a href="http://highscalability.com/blog/2010/2/8/how-farmville-scales-to-harvest-75-million-players-a-month.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;farmville &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;folks have &lt;/span&gt;&lt;a href="http://highscalability.com/blog/2010/3/10/how-farmville-scales-the-follow-up.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;two seperate servers&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;; They found if the number of daily users is below 5 million, it was cheaper to route those games through their own servers, than using a scalable CDN and the costs involved with it.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;By all means the best solution here is a combination of CDN and Torrenting. For instance, using the CDN to help seed new patches and content updates, while letting torrenting do the lions share. Or even if there’s &amp;nbsp;a low-peer network for torrenting, it’s better to swap over to the CDN structure. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;And if rolling-your-own isn’t your thing, I highly recommend Highwinds’ &lt;/span&gt;&lt;a href="http://www.highwinds.com/gdn/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Game Delivery Network&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, which provides all of the items in this article in a nice, awesome package. &lt;/span&gt;&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;In general, for distributing assets, the Torrent-CDN approach is a great middle ground, as it allows you the flexibility and cost structures that are used by lots of powerhouse game developers.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/2Ijh-8P-RPU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/2242196694664393224/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=2242196694664393224" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/2242196694664393224?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/2242196694664393224?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/2Ijh-8P-RPU/distributing-your-game-content-via.html" title="Distributing your game content via Torrenting" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-OkzoH-u-Ln4/UKpvihyrcrI/AAAAAAAAAN0/dbfbvsIhWbo/s72-c/usb_newyork.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/11/distributing-your-game-content-via.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8GQHw4fyp7ImA9WhNREU4.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-370634933982445826</id><published>2012-11-05T07:15:00.000-08:00</published><updated>2012-11-05T07:53:41.237-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-05T07:53:41.237-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="graphics" /><title>HTML5 canvas: Advanced image picking</title><content type="html">&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Let’s take a look at some more advanced ways to do picking with HTML5 canvas for game development. In this article, we’ll cover two techniques to address problems with pixel-perfect picking; using convex hulls, and using grid binning.&lt;/span&gt;&lt;br /&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="230" src="http://1.bp.blogspot.com/-M1pktB9-62M/UJfTg9bMqjI/AAAAAAAAAMk/IjhaCl_Fk5Q/s400/canvas+picking.jpg" width="400" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Advanced data structures can&amp;nbsp;accelerate&amp;nbsp;our picking code, while in some cases,&amp;nbsp;sacrificing&amp;nbsp;resolution perfection.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;span id="internal-source-marker_0.9271817971020937"&gt;&lt;b style="font-weight: normal;"&gt;&lt;span style="color: red; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Using convex hulls for picking&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;As discussed in the last article, Pixel-Perfect picking can increase the memory footprint, and potential performance burden for slower devices. For example, if we had a 1024x1024 image, that may only be 64k in PNG form, but once we fetch it to main memory, it’s now 4MB. There’s really no (good) way around this, since the &lt;i&gt;getImageData &lt;/i&gt;function on canvas returns RGBA data uncompressed, even if we pass in a grayscale image, we’d get the full pixel footprint. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Ideally, it would be great to get a lower-memory &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;representation&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; of the image, without having to store the whole thing in memory. And to that degree, we’re going to introduce the concept of using &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Convex_hull"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Convex Hulls&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; for picking.&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Effectively, a convex hull is a minimum representation of the &lt;/span&gt;&lt;a href="http://www.humus.name/index.php?page=Cool&amp;amp;ID=8"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;shape&lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; of our sprite;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; Once the mouse is pressed, we’ll test the mouse-point against the convex hull of sprite instances to determine if it’s inside, or outside of a target object. &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;We will lose some resolution on this process; that is, our results won’t be pixel-perfect any longer, but there’s a whole separate discussion about &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;how precise&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; your picking code needs to be, especially on mobile, where pixels are (generally) &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=8DtbPOXFk00"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;smaller than peoples’ fingers&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="color: red; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Generating the convex hull&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Generating a convex hull is should be done offline, ahead of time, so that we can reduce the loading time for our HTML5 game. As such, I threw together a simple C++ app that loads a sprite, calculates its convex hull, and outputs &lt;/span&gt;&lt;a href="http://www.json.org/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;JSON &lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;data that we include in the HTML file. Your &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;mileage&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; may vary.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;I’ll spare you walking through the C++ details here, as the code itself is simple. It opens an image and calculates, for each scan-line what the min/max pixels are that represent alpha boundaries. From there, we use a modified &lt;/span&gt;&lt;a href="http://www.qhull.org/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;QHull algorithm&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; to determine what the maximum convex hull is for the set of spatial points.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;The hull points are dumped to individual files, which for simplicity, I've manually added the hull data to the HTML file :&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div dir="ltr" style="text-indent: 0px;"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;
var cHullData=[
{"name":"0.png", "hull":[{"x":0,"y":16}, {"x":1,"y":15}, {"x":31,"y":0}, {"x":34,"y":0}, {"x":64,"y":15}, {"x":65,"y":16}, {"x":65,"y":25}, {"x":64,"y":26}, {"x":34,"y":41}, {"x":31,"y":41}, {"x":1,"y":26}, {"x":0,"y":25}, {"x":0,"y":16}]},
&lt;/span&gt;//etc. etc.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold; text-indent: 0px;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold; text-indent: 0px;"&gt;
&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img height="130px;" src="https://lh6.googleusercontent.com/h9I998nDCEqTLC_21e-mxi9rRoKYdhUOPzZjSiLw2yyKLMuPjJfp_P9mzgv3wDCKJ0MhotH04ga86LPgMAZZt5Kp9ico_tbw5A3hT-mIwLOmpdqIrpU" style="margin-left: auto; margin-right: auto;" width="446px;" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Hull generation process. Per-scan-line we find the min-max pixels for that row, and toss those at a convex hull generator.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b&gt;&lt;span style="color: red; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Doing picking against the convex hull&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;To transition from &lt;/span&gt;&lt;a href="http://mainroach.blogspot.com/2012/10/html5-canvas-simple-per-pixel-image.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;per-pixel picking&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; to hull picking, we need to make a few small changes. Firstly, a sprite prototype needs to load the hull data, rather than fetching the image pixel data. This is an easy task, as the C++ app will spit out the image name for a hull, so that when an image loads, we can look up with the proper hull is for the image.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-family: 'Times New Roman'; font-size: medium; text-indent: 0px; white-space: normal;"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;SpriteProto = Class.extend({
//...

load : function(filename,w,h)
{
//...

var img = new Image();
img.onload = function(){

 targetSpriteProto.imgHandle = img;
 &lt;b&gt;for(var u =0; u &amp;lt; cHullData.length; u++)
 {
  var thull = cHullData[u];
  if(thull.name == filename)
  {
   targetSpriteProto.hullData = cHullData[u].hull;
   break;
  }
 }&lt;/b&gt; 
}
img.src = filename;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-family: 'Times New Roman'; font-size: medium; font-weight: bold; text-indent: 0px; white-space: normal;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-family: 'Times New Roman'; font-size: medium; font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt; white-space: normal;"&gt;
&lt;/div&gt;
&lt;div style="font-family: 'Times New Roman'; font-size: medium; font-weight: bold; text-indent: 0px; white-space: normal;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;To determine if a mouse click (ie point) is inside of our new convex polygon hull, we utilizing a method of &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Point_in_polygon"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;point in polygon&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt; testing&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; known as &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Ray_casting"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;ray casting&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; which performs it’s test by casting a line through the 2D polygon, through the point in question. For each line that our ray intersects, we toggle a boolean value to determine if we’re in or out of the polygon. The simplistic algorithm I used in the source code came from&lt;/span&gt;&lt;a href="http://http//www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html"&gt;&lt;span style="color: black; font-family: Arial; font-size: 15px; text-decoration: initial; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;SpriteProto = Class.extend({
//...
//--------------
isPixelContained:function(lclx,lcly)
{
 &lt;/span&gt;&lt;span style="line-height: 14px;"&gt;var inPoly = false;
 var numPoints = this.hullData.length;
 var j = numPoints-2;
 var latLng={x:lclx,y:lcly};
  
 for(var i=0; i &amp;lt; numPoints; i++)
 {
  
  var vertex1 = this.hullData[i];
  var vertex2 = this.hullData[j];

  if ((vertex1.x &amp;lt; latLng.x &amp;amp;&amp;amp; vertex2.x &amp;gt;= latLng.x) || (vertex2.x &amp;lt; latLng.x &amp;amp;&amp;amp; vertex1.x &amp;gt;= latLng.x) )
  {
   if (vertex1.y + (latLng.x - vertex1.x) / (vertex2.x - vertex1.x) * (vertex2.y - vertex1.y) &amp;lt; latLng.y)
   {
    inPoly = !inPoly;
   }
  }
  j=i;
 }
 return inPoly;&lt;/span&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;
 
}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img height="326px;" src="https://lh4.googleusercontent.com/ZrjHoZQrztP5BHSViTECpO7R5RTBpGUjJSoQVNV9BLcyCse5KV19QLKULWhOXB92BY7XgdEW4kZzLzQB3eVy0V43nn-E6kIR0XwQrOAHFAA7olGj0RE" style="margin-left: auto; margin-right: auto;" width="407px;" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;An example of &lt;i&gt;ray casting&lt;/i&gt;&amp;nbsp;to&amp;nbsp;determine&amp;nbsp;if a point is in a polygon. The line through the polygon an even number of times, signaling that the point is not inside the polygon&amp;nbsp;boundaries.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: center;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;/div&gt;
&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;/h3&gt;
&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Caveats&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;As mentioned, this method will reduce the overall memory footprint for your data significantly, and on some platforms can have the added benefit of faster execution for a given pick operation. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;One down side is that this process doesn't fit well into a pipeline for atlases; You’ll need to calculate the convex hulls of your loose sprites before placing them into your atlas. Of course the lower memory performance comes at the cost of less resolution, something that you should consider before adopting this technique.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Faster picking via bucketing&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;Let’s say you’re complex app, and have 4096 images in flight when a user clicks. Obviously, you’d want to reduce the number you did a pixel or convex-hull test on, and although a simple bounding-box test will be the quickest to implement, you still end up touching a lot of items that aren't even remotely &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;near&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; the point in question. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The solution to this is to introduce a &amp;nbsp;&lt;/span&gt;&lt;a href="http://coitweb.uncc.edu/~krs/courses/5010/ged/lectures/spatial2.pdf"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;spatial acceleration structure&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; to our canvas; A process which organizes / separates our sprites spatially, such that we speed up spatial tests by only referencing items which are reasonably co-located. There’s lots of &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Quadtree"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;variants&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; for SAS which have pros, cons, and lots of trade-offs, and for our purposes, we will use a very simplistic 2D binning algorithm, which will divide our canvas into a grid of cells; each cell will contain a list of objects which touch that cell, allowing a sprite to be listed in multiple cells.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Our bucket Grid class will effectively create a 2D array, of &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;arrays&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, such that when a sprite is spawned, we calculate what grid cells it overlaps, and add a pointer to this instance to each of those cell’s lists.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-family: 'Times New Roman'; font-size: medium; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt; white-space: normal;"&gt;
&lt;/div&gt;
&lt;div dir="ltr" style="text-indent: 0px;"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;BucketGrid = Class.extend({
 tileSize:16,
 numXTiles:0,
 numYTiles:0,
 tileData:null,
 
 init:function()
 {
  this.tileData = new Array();
  //16pixels is an arbitrary number from testing.
  this.tileSize = 16;
  this.numXTiles= 512 / this.tileSize; //512 = canvas size
  this.numYTiles= 512 / this.tileSize;
  
  this.tileData.length = this.numXTiles * this.numYTiles;
  for(var k =0; k &amp;lt; this.tileData.length;k++)
   this.tileData[k] = new Array();
 },&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;Marking a sprite instance on the grid is pretty simple, we simply run some math on the corners of the sprite to calculate the min/max boundaries of it, and what tiles those boundaries fall into; and for each grid cell, we add the sprite to the containing list.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;
//--------------
 markInstanceInAccelGrid:function(sp)
 {
  var gridminX = Math.floor(sp.pos.x / this.tileSize);
  var gridmaxX = Math.floor((sp.pos.x + sp.size.w) / this.tileSize);
  var gridminY = Math.floor(sp.pos.y / this.tileSize);
  var gridmaxY = Math.floor((sp.pos.y + sp.size.h) / this.tileSize);
 
  //we cheat here, knowing that our rand() placement doesn’t allow neg numbers
  if(gridmaxX &amp;gt;= this.numXTiles) gridmaxX = this.numXTiles-1;
  if(gridmaxY &amp;gt;= this.numYTiles) gridmaxY = this.numYTiles-1;
  
  for(var y = gridminY; y &amp;lt;=gridmaxY; y++)
  {
   var idx = y*this.numXTiles;
   for(var x = gridminX; x &amp;lt;=gridmaxX; x++)
   {
    this.tileData[idx+x].push(sp);
   }
  }
 },&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;This makes finding entities extremely quick, because we've already pre-sorted the environment. When a mouse-click comes in, we simply find the bucket it resides in, and return the list of entities that we've already calculated.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;
//--------------
 getEntsForPoint:function(x,y)
 {
  var gridminX = Math.floor(x / this.tileSize);
  var gridminY = Math.floor(y / this.tileSize);
  var idx = gridminX + gridminY*this.numXTiles;
  var ents = this.tileData[idx];
  return ents;
 }
});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Which makes modification to our existing code very nice and tidy&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;//--------------
function findClickedSprite(x,y)
{
 
 var alphaThreshold = 50;
 var pickedSprite = null;
&lt;b&gt; var tgtents = acclGrid.getEntsForPoint(x,y);&lt;/b&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The acceleration grid reduces performance overhead by reducing the number of times the &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;inner loop&lt;/span&gt;&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; is called, regardless of how many sprites we have universally, this bucketing will only care about what sprites reside in a grid cell. An easy trade-off in bang-for-the-buck; We didn't have to derail ourselves by worrying how JavaScript is handling the math for convex hulls, or the array-access times for pixel-perfect picking. It’s a simple technique that can be used for static and dynamic environments.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Closing thoughts&lt;/span&gt;&lt;/h2&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;span class="Apple-tab-span" style="font-family: Arial; font-size: 15px; font-weight: bold; white-space: pre;"&gt; &lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;Hopefully, you've got enough information from these past two articles to implement a very fast, efficient picking system in HTML5 canvas. note that there’s lots of other improvements you could continue on with; For example, having a separate Spatial Grid for dynamic vs. static objects; Compressing the Hull data for faster load times; and even caching click results for grid cells. Go forth and pick stuff!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Source Code&lt;/span&gt;&lt;/h2&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;You can find the &lt;a href="https://github.com/mainroach/sandbox/tree/master/canvas-faster-picking"&gt;source code&lt;/a&gt; to this article on &lt;a href="https://github.com/mainroach"&gt;my github&lt;/a&gt;. It’s fairly simple, and shows how to use the polygon system, alongside bucketing. &lt;/span&gt;&lt;br /&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/BvO5C15Auv0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/370634933982445826/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=370634933982445826" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/370634933982445826?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/370634933982445826?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/BvO5C15Auv0/html5-canvas-advanced-image-picking.html" title="HTML5 canvas: Advanced image picking" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-M1pktB9-62M/UJfTg9bMqjI/AAAAAAAAAMk/IjhaCl_Fk5Q/s72-c/canvas+picking.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/11/html5-canvas-advanced-image-picking.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIDQH08eSp7ImA9WhNSFUk.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-7979716984487137748</id><published>2012-10-29T12:53:00.000-07:00</published><updated>2012-10-29T12:56:11.371-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-29T12:56:11.371-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="graphics" /><category scheme="http://www.blogger.com/atom/ns#" term="memory" /><title>HTML5 canvas: Simple per-pixel image picking</title><content type="html">&lt;b id="internal-source-marker_0.9343035309575498" style="font-weight: normal; text-align: center;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;If you’re writing a 2D game in HTML5, chances are that you’ll want the user to have the ability to pick an object on the screen; Since there’s no direct API for this type of notion, and no good results / examples on the web, let’s take a look at how to properly do picking with an HTML5 canvas.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="265" src="http://2.bp.blogspot.com/-tULpOekbjC4/UI7e-a8GlsI/AAAAAAAAAMQ/kyXVhrGBkK8/s400/picking-teams.jpg" width="400" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Picking can be a tricky, troublesome, and socially awkward process; especially in kickball...&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.9343035309575498"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span id="internal-source-marker_0.9343035309575498"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Pixel Perfect picking&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;span id="internal-source-marker_0.9343035309575498"&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.9343035309575498"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;For games that utilize picking for desktop applications, pixel-perfect response to a mouse click is crucial. Multiple images can be overlaid against each other, each one that can have varied alpha footprints which in no-way match their conservative bounding box estimates. As such, to do a pixel-perfect pick, you’ll need to be able to determine what pixel, from what image was clicked on; mainly identifying that you’ll need to keep a &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;copy&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; of the image data in memory so that your code can query the pixel array.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.9343035309575498"&gt;
&lt;/span&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.9343035309575498"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;In order to do this in HTML5, we need to introduce two separate data structures, a &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;sprite prototype&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, which represents a single loaded image sprite, and a &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;sprite instance&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; which represents an instance of the prototype on the canvas, that is, we assume that a single image is used multiple times on a canvas. Our sprite prototype then will need to contain the pixel data for it’s image element, such that we can query against it later. &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.9343035309575498"&gt;
&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Loading pixel data&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The cornerstone of our picking process is assuming that your images &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;contain&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; alpha values, which we generally assume is loaded this way:&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="text-indent: 0px;"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;var img = new Image();
img.onload = function(){alert(‘loaded!”);}
img.src = filename; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-family: 'Times New Roman'; font-size: medium; font-weight: bold; text-indent: 0px; white-space: normal;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-family: 'Times New Roman'; font-size: medium; font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt; white-space: normal;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Notice the problem here is that in Javascript, we don’t directly handle the pixel data; it’s handled behind the scenes on our behalf. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;To get the data then, we need to do some extra work. We could start by writing a Javascript PNG decoder, but that would be massive overkill, considering PNGs support lossless compression. Since we’re really only concerned with the &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;alpha&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; values of an image, we could store the alpha channel in a separate .RAW file that we fetch in parallel, however this would increase the transfer and asset size of the app.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;For the sake of our purposes, we ignore those two options, and instead decide to keep the code footprint low, and transfer sizes low by using the &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;canvas&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; element to fetch the data. To do this, we create an off-screen canvas, render our image to it, and &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;fetch the pixels&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; of the canvas object back to memory.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;table style="border-collapse: collapse; border: none; width: 624px;"&gt;&lt;colgroup&gt;&lt;col width="*"&gt;&lt;/col&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;var offScreenCanvas= document.createElement('canvas');
var fetch_ctx = offScreenCanvas.getContext('2d');
offScreenCanvas.width = 128;
offScreenCanvas.height = 128;
function fetchImageData(imgObject, imgwidth,imgheight)
{
 fetch_ctx.clearRect(0,0,128,128);
 fetch_ctx.drawImage(imgObject, 0, 0);

 //note this keeps an additional in-memory copy 
 var imgDat = fetch_ctx.getImageData(0,0, imgwidth, imgheight);
 
 return imgDat;
}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;This allows us to transfer a smaller asset footprint, keep using our PNGs / GIFs or whatever other compression footprint you want, and still get the RGBA data available in main memory during load time. to utilize this, once an image has been loaded, we fetch it’s image data using the function above :&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;var img = new Image();
img.onload = function(){

targetSpriteProto.imgHandle = img;
targetSpriteProto.imgData = fetchImageData(targetSpriteProto.imgHandle,w,h);
   
}
img.src = filename; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Testing a mouse click&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Once we have the per-image data in memory, we need to test against it when a user clicks. This is broken down into a few sections of a larger function.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Firstly the &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;findClickedSprite &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;function will loop through all the sprite instances in memory, and do a conservative bounding box test against the picking point; we assume that array-lookup is a performance limiting action in javascript, and this bounding-box test allows an early out for items that don’t potentially intersect with the pick position.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; text-indent: 36pt; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div dir="ltr" style="text-indent: 0px;"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="background-color: transparent; font-size: 12px; line-height: 14px;"&gt;//--------------
function findClickedSprite(x,y)
{
 var pickedSprite = null;
 var tgtents = spriteInstances;

 //loop through all sprites 
 for(var i =0; i &amp;lt; tgtents.length; i++)
 {
  var sp = tgtents[i];
  //pick is not intersecting with this sprite
  if( x &amp;lt; sp.pos.x || x &amp;gt; sp.pos.x + sp.size.w ||
   y &amp;lt; sp.pos.y || y &amp;gt; sp.pos.y + sp.size.h)
   continue;&lt;/span&gt;&lt;span style="font-size: 12px; font-weight: normal; line-height: 14px;"&gt; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;div style="font-weight: normal;"&gt;
&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold; text-indent: 0px;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold; text-indent: 0px;"&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; text-indent: 36pt; white-space: pre-wrap;"&gt;Once we find a sprite instance whose bounding box intersects with the picking point, we grab the sprite prototype, and translate the canvas-relative mouse position to a sprite-instance-relative position that we use to test against. These values are passed to a function on the sprite prototype to determine if the target pixel is transparent or not. If we’re clicking an opaque pixel for this sprite, we set this as the selected sprite.&lt;/span&gt;&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: Arial; font-size: 15px; font-weight: bold; white-space: pre-wrap;"&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="vertical-align: baseline;"&gt;
&lt;/span&gt;
&lt;div&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;span style="vertical-align: baseline;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;  var ps = sp.spriteHandle;
  //get local coords and find the alpha of the pixel
  var lclx = x - sp.pos.x;
  var lcly = y - sp.pos.y;
  if(ps.isPixelTransparent(lclx,lcly))
  {
   pickedSprite = sp;
  }
 }
 
return pickedSprite;
 
}&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-family: 'Times New Roman'; font-size: medium; font-weight: bold; white-space: normal;"&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-family: 'Times New Roman'; font-size: medium; font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt; white-space: normal;"&gt;
&lt;/div&gt;
&lt;div style="font-family: 'Times New Roman'; font-size: medium; font-weight: bold; white-space: normal;"&gt;
&lt;/div&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;b style="font-family: 'Times New Roman'; font-size: medium; font-weight: normal; white-space: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="vertical-align: baseline;"&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;Note that an important part of isometric and top-down 2D games is the notion of zOrder, in which a separate index is used to determine and describe how to properly render the elements on the screen. Our picking algorithm needs to take this into account, so that what the user thinks is top-most, is actually represented as top-most.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;if(ps.isPixelTransparent(lclx,lcly))
{
 //do depth test (if applicable)
 if(pickedSprite &amp;amp;&amp;amp; sp.zIndex &amp;lt; pickedSprite.zIndex)
  continue;
 pickedSprite = sp;
}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold;"&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;isPixelTransparentI&lt;/span&gt;&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; function for the proto-sprite does very simple logic. Firstly it determines what the proper pixel is in the image data that we’re targeting; (Note that data given back from the canvas is always in RGBA form!) and tests the alpha value against some threshold. The threshold is important, as most artists can add gradient falloffs, drop shadows, and other items which increase the visual of the item, but shouldn't be considered for picking purposes.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div dir="ltr" style="text-indent: 0px;"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); overflow: auto; padding: 5px; width: 653px;"&gt;&lt;code style="background-color: white;"&gt;&lt;span style="font-size: 12px; line-height: 14px;"&gt;isPixelTransparent:function(lclx,lcly)
{
 var alphaThreshold = 50;
 var idx = (lclx*4) + lcly * (this.imgData.width*4);
 var alpha = this.imgData.data[idx + 3];
 //test against a threshold
 return alpha &amp;gt; alphaThreshold;
}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold; text-indent: 0px;"&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;/div&gt;
&lt;div style="font-weight: bold; text-indent: 0px;"&gt;
&lt;/div&gt;
&lt;b style="font-weight: normal; text-indent: 0px;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div style="text-indent: 0px;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;h3 dir="ltr" style="font-weight: bold; text-align: left;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Results&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span style="color: black; font-size: 15px; text-indent: 48px;"&gt;The results are quite nice. We can select the right object out of a very complex pixel coverage area.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span style="color: black; font-size: 15px; text-indent: 48px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3 dir="ltr" style="font-weight: bold; text-align: center;"&gt;
&lt;img height="186px;" src="https://lh5.googleusercontent.com/mOVcnPKCZjBxkNuxaCfVuHJX7VuvIIiwgWtLhCl3rdclLHpoZToVRIfAxmz1JKL0AMNMFkrQ6omONH6Ge_fwblro0HB0q5r-PCjQS6ceI6neLLiW0YM" width="639px;" /&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Caveats&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;While this method works, and produces pixel-perfect results, it presents two primary issues:&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;1) Image data, which is normally stored in your javascript layer behind the scenes, now has to be duplicated in your scripts. As such, this results in a larger memory footprint; Often more than double the size, since your in-memory copy is uncompressed.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;2) It’s currently unclear how an array look-up affects performance in javascript under the hood. In C++ you have the ability to avoid CPU addressing issues like L2 Cache optimization for array traversal, which is completely missing in Javascript. On my 12 core work-machine, a single pick against 4096 images takes around ~2ms. I’d imagine on a phone, that would be &lt;i&gt;significantly &lt;/i&gt;higher.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;And finally, it’s unclear if you &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;really&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; need pixel-perfect picking for your game; For instance, the user may benefit from a more loosely defined picking area, that is allowing an extension of the valid picking area beyond the pixel boundaries around the object, in an attempt to reduce user picking frustration. &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h2 dir="ltr"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Next Time&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;In the next article, we'll talk about some advanced and faster ways to do picking on an HTML5 canvas, Stay tuned!&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Source Code&lt;/span&gt;&lt;/h2&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;You can grab the working source-code from my &lt;/span&gt;&lt;a href="https://github.com/mainroach/sandbox/tree/master/canvas-pixel-picking"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;github page&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. Note that you’ll have to access the page via the python server (run python httpd.py first, and browse to localhost:5103) as the &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;getImageData&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; function on a canvas can’t be accessed locally.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/vh19-Nx02_4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/7979716984487137748/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=7979716984487137748" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/7979716984487137748?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/7979716984487137748?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/vh19-Nx02_4/html5-canvas-simple-per-pixel-image.html" title="HTML5 canvas: Simple per-pixel image picking" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-tULpOekbjC4/UI7e-a8GlsI/AAAAAAAAAMQ/kyXVhrGBkK8/s72-c/picking-teams.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/10/html5-canvas-simple-per-pixel-image.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMBR389eCp7ImA9WhNTFEw.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-5288617866321985793</id><published>2012-10-16T10:56:00.002-07:00</published><updated>2012-10-16T11:00:56.160-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-16T11:00:56.160-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="industry" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>Costs of a cloud gaming backend</title><content type="html">&lt;b id="internal-source-marker_0.04960350878536701"&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.04960350878536701"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;There's a critical eye on &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Cloud_gaming"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Cloud Gaming&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; right now, especially with the &lt;/span&gt;&lt;a href="http://www.forbes.com/sites/erikkain/2012/07/03/sony-buys-gaikai-for-380-million-are-consoles-headed-to-the-cloud/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;purchase of Gaikai by Sony&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and &lt;/span&gt;&lt;a href="http://www.gamasutra.com/view/news/176180/OnLive_lays_off_all_employees_assets_sold_to_new_company.php"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;OnLive’s metamorphosis&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; having just occurred. So the question lately has been “Is cloud-gaming still the future?” &amp;nbsp;In order to answer that, we will need to have a technical look at the process involved, and hopefully understand a bit more about the cost of this process.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Kb1w583zB9o/UH2gw8S3rRI/AAAAAAAAAL8/kck66b0QHT0/s1600/clouds.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="190" src="http://4.bp.blogspot.com/-Kb1w583zB9o/UH2gw8S3rRI/AAAAAAAAAL8/kck66b0QHT0/s320/clouds.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Mario knew what it took to get cloud-gaming working; Cutting corners at all costs.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;b id="internal-source-marker_0.04960350878536701"&gt;&lt;br /&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;h3 dir="ltr" style="font-weight: normal;"&gt;
&lt;b id="internal-source-marker_0.04960350878536701"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Understanding how a video service works&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;span id="internal-source-marker_0.04960350878536701"&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.04960350878536701"&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;Most video services, like &lt;/span&gt;&lt;a href="http://www.youtube.com/" style="font-weight: normal;"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;YouTube&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt; work by caching the video data on a &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Content_delivery_network" style="font-weight: normal;"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;CDN&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;, serving the content to clients via &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Streaming_media" style="font-weight: normal;"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;video streaming&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;. A technology that will send small chunks of compressed video content to the client, which consumes and combines to display to the user while new chunks are coming in. Which takes advantage of the fact that sending 30 seconds of compressed video data to the client &lt;/span&gt;&lt;span style="color: #222222; font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;should&lt;/span&gt;&lt;span style="color: #222222; font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; be faster than the 30 seconds it takes to display it to the user. This allows video streams to buffer and load over time; that is the whole file isn't getting transferred to you, but small chunks of it, which then allow something to be displayed while the rest of the content is loading behind the scenes. This isn't a new concept, but it’s an important one to ensure that you’re not waiting for the ‘whole freaking video’ to come down before being able to see the first frame of the video.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.04960350878536701"&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.04960350878536701"&gt;&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;Live video streams work in much the same way; You have a point of origin that’s generating frames, compressing them, and uploading them to a server cache, which broadcasts them to clients through the inter-tubes. Clients around the world who are watching the ‘live stream’ will be getting content from the server cache, and displaying as it can receive it. As such, there’s generally a significant delay between the live event and what’s seen on the internet to viewers; Not only does it take time to capture, compress, and upload the data to the server, but then it has to come from a single-physical location to a single location in the cloud. Which generates a large latency bottleneck for most live-streamed events.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.04960350878536701"&gt;
&lt;/span&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.04960350878536701"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;These delays are generally forgiven by the end user. They have no way to know that their data stream is delayed, other than to compare it to a live-viewing. Most importantly, there’s no gauge to know how slow things are compared to the live event. It’s really a black box.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.04960350878536701"&gt;
&lt;h3 dir="ltr" style="font-weight: normal;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Interactive Video breaks the rules.&lt;/span&gt;&lt;/h3&gt;
&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Cloud gaming is best thought of as “&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Interactive_video" style="font-weight: normal;"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Interactive Video&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;” a term which removes some of the mystique and business hype from the equation. Interactive video changes the concept of streaming video, since input from the user directly changes what the video content will be over the next few seconds. The video stream is now dependent on the user input, which the user feels it can gauge. So latency is very noticeable to the user.&lt;/span&gt;&lt;br /&gt;&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The first thing interactive video breaks is that clients can no longer buffer-present the video frames to the user, as it does not know what the future frames are going to be yet, given the current state of user input. This means that the speed in which the client grabs the input video data off the wire, directly gates how fast they can render them on the screen. The best the server can do is render frames that may not be dependent or updated by the user input, waiting for that to be received.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;As such, interactive video is very concerned about latency and &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Lag"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;lag&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, since it’s actually noticeable by the user. Most models for cloud-gaming services build an &lt;/span&gt;&lt;a href="http://www.eurogamer.net/articles/digitalfoundry-geforce-grid-cloud-performance"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;estimation of ~100ms&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; for latency between input controller and user seeing a &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Display_lag"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;visual on the screen&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;A standard desktop game running @ 60fps expects about 16ms for a frame of the game. For an interactive streaming service though, this gets tricky. Let’s assume you've got a 4ms ping from server to client, this already gives you only 12ms left to compute your frame. Then the server box has to compress it, let’s give that 2 ms, and this leaves your frame with about 10ms of time to compute in order to stay @ 60fps.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3 dir="ltr" style="font-weight: normal;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Understanding cloud-compute in relation to video streaming&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Since interactive video needs to &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;compute&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; something, the data can’t just be distributed from a CDN to the masses. No, we need the power of &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Cloud_computing"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Cloud Computing&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; to drive this beast. Think of cloud compute as a large automated way to run chunks of c&lt;/span&gt;&lt;a href="http://youtu.be/tPtJd6AzU8c?t=40m13s"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;ode across millions of cores&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, resulting in awesome performance. Services like &lt;/span&gt;&lt;a href="https://developers.google.com/compute/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Google Compute Engine&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; offer the ability to upload applications which can be run across thousands of cores &lt;/span&gt;&lt;a href="https://developers.google.com/compute/io"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;online&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;Our cloud gaming service will spin up a box on the cloud and start the game. Once a connection to the client is established, a stream of video frames will be captured, compressed and sent to the user through a socket connection. Thankfully, we can continue to send frames to the client at regular intervals, even the server hasn't received input yet.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;It should be clear that the infrastructure to do this is not easy, or cheap to put together. Google already has data centers across the globe, with machines sitting around already. A private company attempting to produce the same results would have to dump hundreds of millions into setting up the same physical structure to compete in the same regard. So it’s not wise, if you were trying to build a system, to create your own hardware racks; &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=1SCZzgfdTBo#!"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Trust me.&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h2 dir="ltr" style="font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;The costs of doing business&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;Using these types of cloud compute services come with a cost however. Just to toss a dart towards a number, let’s assume that your cloud-gaming service has &lt;/span&gt;&lt;a href="http://www.appdata.com/apps/facebook/102452128776-farmville" style="font-weight: normal;"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;3.4 million daily active users&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;, each one receiving 1GB of video in a day. At &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.vcodex.com/h265.html" style="font-weight: normal;"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;H.265&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt; compression should be roughly 46 minutes of play time, or around 2.6 million hours of computation a day to compute the video stream. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;In this scenario, we should note that the costs of using &lt;/span&gt;&lt;a href="https://developers.google.com/compute/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;GCE&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; are two fold:&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;ol style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt;"&gt;
&lt;li style="font-family: Arial; font-size: 15px; list-style-type: lower-alpha; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;$1923 to transfer 1GB of data to 3.4 million users&lt;/span&gt;&lt;/li&gt;
&lt;li style="font-family: Arial; font-size: 15px; list-style-type: lower-alpha; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;$377,000 to hold the compute machines for 2.6 million hours&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;With some estimated math, these numbers might be obtainable, if you assume that each user is paying &lt;/span&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;b&gt;$5 a month fee, which would net you around $17,000,000 /mo&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 15px; font-weight: normal; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Engineers reading this should have an immediate gut reaction to that number. Holding a single cloud-instance machine for an entire 46 minutes for a single client is obviously not utilizing all the resources on the box. If we were able to multiplex the machines, putting X users on each machine, we can cut the daily costs by X users-per-box. So, if we allowed 10 players to share a single box, that would cut our compute costs per day down to around $37,000 / day.&lt;/span&gt;&lt;/div&gt;
&lt;h2 dir="ltr" style="font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Skew all the numbers&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;And these numbers &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;only&lt;/span&gt;&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; include CPU side computation, completely ignoring GPU overhead. GPUs generally pull more wattage, and introduce more instability into a server rack, resulting in higher costs for cloud compute. In addition, trying to host multiple client sessions on a single GPU isn't an easy task; most games have a hard enough time making the GPU work properly with one instance of the game, not to mention multiple ones.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Thankfully this is getting easier, recently &lt;/span&gt;&lt;a href="http://www.eurogamer.net/articles/digitalfoundry-geforce-grid-cloud-performance"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;NVidia announced their new GeForce GRID &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;hardware, which comes with hardware video compressors, alongside lower power wattage consumption, and the ability to virtualize, or mutli-slice the machine. This means you can run multiple game instances on a single box, reducing the cost of compute time. For instance, the Nvidia brochure denotes the ability to run 4 streams per GPU, reducing the daily cost for 3.4 million down to $94,250 / day; assuming that there’s no modifications to cost for extra GPU support (which is naive to assume.)&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;These modified GPU racks also have a separate optimization, reduced wattage. &amp;nbsp;If you calculate the &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.tomshardware.com/charts/2011-gaming-graphics-charts/3D-Power-Draw,2678.html" style="font-weight: normal;"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;wattage of the average household GPU&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;, * 3.4 million, you end up with about half the daily output of &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Hoover_Dam" style="font-weight: normal;"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Hoover Dam&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Reality though is that $5 a month may not be tolerated by most gamers. Certainly the 3.4 million DAU are free players, which if you roughly estimate 2% are willing to pay $5/mo for a premium service, would result in around 68k players, paying $5 a month, resulting in ~$11k &amp;nbsp;in revenue a day. &lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Which is not exactly a slam dunk in the business sense.&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;However Sony did buy Gaikai, and we’re seeing other &lt;/span&gt;&lt;a href="http://venturebeat.com/2012/08/29/square-enixs-core-online-service-lets-you-play-high-definition-games-in-your-browser/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;competitors&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; popping up, including your local &lt;/span&gt;&lt;a href="http://www.gamespot.com/news/cable-providers-to-offer-cloud-gaming-report-6397115"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Cable providers&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. So there’s got to be some numbers that I’m not factoring in.&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;h2 dir="ltr" style="font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;What’s it mean for game devs?&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;As we see more of these services pop up, I estimate we’ll see more service fragmentation as everyone rushes to get a critical mass of users-to-games ratio. A post-nuclear view could be a world where video-streaming services are as prolific as &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Game_portal"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;flash-portals&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; are today. As noted though, the cost of investment is so high, the number of platform holders will be quite small. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;For a game developer, this is generally a good thing; you’ll be able to use these streaming services to make your game easier to access, even allow users to try your game for free w/o having to modify your application, segment assets, or pay to transfer data to that user.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: normal; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Cloud gaming silos should be looked at in the proper light, they are still silos, with the issues and benefits of it, attached alongside a tool for &lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=dAp-l3gUcPY"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;webification&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. Until these items truly take off the ground, it’s difficult to predict when all the planets will align, but chances are, it’s still on the horizon.&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/GBYXviUJt4U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/5288617866321985793/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=5288617866321985793" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/5288617866321985793?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/5288617866321985793?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/GBYXviUJt4U/costs-of-cloud-gaming-backend.html" title="Costs of a cloud gaming backend" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-Kb1w583zB9o/UH2gw8S3rRI/AAAAAAAAAL8/kck66b0QHT0/s72-c/clouds.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/10/costs-of-cloud-gaming-backend.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04CQnw8cCp7ImA9WhNSEks.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-1112484337286483428</id><published>2012-10-08T13:10:00.003-07:00</published><updated>2012-10-26T07:32:43.278-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-26T07:32:43.278-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="industry" /><category scheme="http://www.blogger.com/atom/ns#" term="management" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome Web Store" /><title>Indie Dev? You should be selling your game on the web.</title><content type="html">&lt;b id="internal-source-marker_0.25868222676217556" style="font-weight: normal;"&gt;&lt;/b&gt;&lt;br /&gt;
&lt;h3 dir="ltr" style="text-align: center;"&gt;
&lt;b id="internal-source-marker_0.25868222676217556" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;If you’re an indie developer, and you’re not selling your game on the web, you might be doing it wrong.&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3 dir="ltr" style="text-align: center;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-GgHFnwJY8cs/UHMzcuvA8qI/AAAAAAAAALo/QlQI2UtB6LI/s1600/say_what.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-GgHFnwJY8cs/UHMzcuvA8qI/AAAAAAAAALo/QlQI2UtB6LI/s320/say_what.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;
&lt;b style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3&gt;
&lt;b style="font-weight: normal;"&gt;The Success Story&lt;/b&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.25868222676217556" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;In 2009, &lt;/span&gt;&lt;a href="https://minecraft.net/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Minecraft &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;was launched in alpha, available from the author's website, in which you could download and try for free. Alternatively, you could donate to the development of the game, in which case when it was release, you’d get it for free. &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;"&gt;The results were staggering&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. People realized early on that the game was fun, and quickly payed for it, and most importantly, &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;told their friends&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; because they were so passionate about it. The message was easy to spread; the early builds were in java, and I remember playing a version of it &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;in my browser&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. A year later, &lt;/span&gt;&lt;a href="http://www.mojang.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Mojang&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; was founded after the author's &lt;/span&gt;&lt;a href="https://www.paypal.com/home"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;PayPal&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; account was temporarily suspended for suspicious activity when $700k appeared in the account almost overnight. That was entirely without any digital distribution ecosystem, or social sharing middle ware. It was just a great game being sold on a website. &lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.25868222676217556" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Today, Minecraft has over 9 million sales, and has builds for console, mobile, and desktop. And it all started by selling on the web to passionate users who were willing to carry the message.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;h3 dir="ltr"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3 dir="ltr"&gt;
&lt;b id="internal-source-marker_0.25868222676217556" style="font-weight: normal;"&gt;&lt;span style="color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Indies gone wild&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.25868222676217556" style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Another great example is &lt;/span&gt;&lt;a href="http://www.positech.co.uk/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Positech games&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, makers of &lt;/span&gt;&lt;a href="http://www.positech.co.uk/gratuitousspacebattles/index.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Gratuitous Space Battles&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. &lt;/span&gt;&lt;/b&gt;&lt;span id="internal-source-marker_0.25868222676217556"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Cliff Harris, owner/founder/indie gave a &lt;/span&gt;&lt;a href="http://vimeo.com/18630215"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;great talk&lt;/span&gt;&lt;/a&gt;&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; at a conference back in 2009 where he described about how important it is for him to sell his games on the web. In his goal to sell a game every 52 seconds, he overviews how using tools like &lt;a href="http://www.google.com/analytics/"&gt;Google &lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;a href="http://www.google.com/analytics/"&gt;Analytics&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; allows him to reach and understand his users.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;table style="border-collapse: collapse; border: none; width: 624px;"&gt;&lt;colgroup&gt;&lt;col width="*"&gt;&lt;/col&gt;&lt;/colgroup&gt;&lt;tbody&gt;
&lt;tr style="height: 0px;"&gt;&lt;td style="border: 1px solid rgb(0, 0, 0); padding: 7px; vertical-align: top;"&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;“Advertising online is a real time strategy game that geeks like you are good at. … It’s a game that you’re playing with real money, and if you win, you make money.”&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Other indies are realizing that eyeballs = profits, and are starting to branch out to find new ways of creating success. For example, &lt;/span&gt;&lt;a href="http://www.desktopdungeons.net/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Desktop Dungeons&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, a yet-unreleased game is looking to model it’s early development states after Minecraft’s success, alongside the the recent &lt;/span&gt;&lt;a href="http://www.kickstarter.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Kickstarter&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; boom, by allowing users to fund the development of the game by &lt;/span&gt;&lt;a href="http://www.desktopdungeons.net/pre-order-desktop-dungeons/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;buying early build&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; for different tiers of investment, including a level that includes a reference to you, somewhere in the game.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;And let’s not forget the massively successful &lt;/span&gt;&lt;a href="http://www.humblebundle.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Humble Indie Bundle&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, which allows consumers to &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;donate&lt;/span&gt;&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; an amount of their choosing to charity, and in return, gets DRM Free versions of the games provided in the bundle. To date, &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;they've&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt; made over $19 million dollars for charity, selling directly through their website.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;The barriers that don’t exist.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Many game devs I talk to shy away from selling their content online. In their minds, it’s a cumbersome process to market and handle money exchange etc etc. The truth is, these barriers are no longer relevant in 2012, and we should re-visit some of the big issues.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;“Taking money for purchases is difficult online”&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;/span&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;&lt;span style="vertical-align: baseline;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;Back in the day, it was a tough process to sell digital goods through the interwebs. Thankfully through the rise of merchandising on the web, you've got &lt;a href="http://www.google.com/wallet/#utm_source=RE&amp;amp;utm_medium=re-wal"&gt;more options&lt;/a&gt; than you can shake a stick at. Take a look at the page from &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.positech.co.uk/gratuitousspacebattles/register.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;GSB &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;:&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span id="internal-source-marker_0.25868222676217556"&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-align: center; text-indent: 36pt;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div dir="ltr" style="display: inline !important; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-align: center; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.25868222676217556" style="font-weight: normal;"&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div dir="ltr" style="display: inline !important; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.25868222676217556" style="font-weight: normal;"&gt;&lt;img height="143px;" src="https://lh4.googleusercontent.com/sxTgsLIAiKdxQ02bDE8UM_kHuYXoHd0OYfX7R5j-XY8q5XqwG4qynYNOwNpdY1PppQVCSJS70EnoImbAlLWtESxoSz7vwEo5sxKZ9hzooOrqON3ebXw" width="422px;" /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Cliff is an indie developer, and he goes out of his way to make it as &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;easy as possible&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; for a potential customer to become a paying one, because that’s how he feeds his family. In Fact, he goes the extra mile to tell you &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;why&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; you should buy from &lt;/span&gt;&lt;a href="http://www.positech.co.uk/about.shtml"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;his site directly&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="font-weight: bold; margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;div dir="ltr" style="font-weight: bold;"&gt;
&lt;table style="border-collapse: collapse; border: none; width: 624px;"&gt;&lt;colgroup&gt;&lt;col width="*"&gt;&lt;/col&gt;&lt;/colgroup&gt;&lt;tbody&gt;
&lt;tr style="height: 0px;"&gt;&lt;td style="border: 1px solid rgb(0, 0, 0); padding: 7px; vertical-align: top;"&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 13px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;When you buy games from us, we get about &lt;/span&gt;&lt;span style="background-color: white; color: red; font-family: Arial; font-size: 13px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;91%&lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 13px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt; of the money. the 9% goes to our credit card payment provider. There is &lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 13px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;NO MIDDLEMAN&lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 13px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;. We do not have any &lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 13px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;RIAA&lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 13px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt; or &lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 13px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;MPAA&lt;/span&gt;&lt;span style="background-color: white; color: #222222; font-family: Arial; font-size: 13px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt; or other organisation that is profiting from our work. If you care about supporting people who make the kinds of games you want to play, here is your chance to ensure the money goes straight to them.&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 13px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;“It’s too difficult to support multiple platforms.”&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Selling your game on the web means users will be able to buy your game on various types of platforms, operating systems, and hardware. This can be a daunting operation, considering the amount of time and dedication that goes into solving platform fragmentation.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Thankfully, with the influx of indie game developers coming onto the scene since 2009, technology middleware vendors have been priding themselves on creating tool-chains for cross-platform development. After all, not every user is on every gaming platform, so making your game accessible across multiple platforms and services increases the number of users that can become customers. &lt;/span&gt;&lt;a href="http://unity3d.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Unity&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.unrealengine.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Unreal&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://getmoai.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Moai&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.blitzgamesstudios.com/blitztech"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Blitz&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and &lt;/span&gt;&lt;a href="http://www.yoyogames.com/gamemaker/studio"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Game Maker&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; are all examples of middle ware systems that pride themselves on going multi-platform first, most of which even allow a web-specific build so the user won’t have to install the game locally. Now that’s not saying that supporting multiple platforms is &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;automatic&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. You still have to deal with issues of screen resolution, input, and performance differences, but that’s a different article ;)&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;With these technologies available, selling your game on the web is even easier, as you can ensure that your app supports all the platforms that the web can find you on.&lt;/span&gt;&lt;/div&gt;
&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;h3 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="color: #666666; font-family: Arial; font-size: 16px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;“It’s too difficult to market online.”&lt;/span&gt;&lt;/h3&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;For current game developers “&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;Discoverability!”&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; is the lamentation of the day. The largest feedback I get from developers is about how &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;hard&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; it is to be successful in the modern industry. It seems everyone is content to fight for 96x128 pixels worth of screen real estate on a mobile store, working to get more eyeballs on your content by opting in to networks that will cross-promote your digital swag.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;However, a &lt;/span&gt;&lt;a href="http://www.gamasutra.com/view/news/178516/Research_How_mobile_players_find_new_games_to_play.php#.UIqe9Uq-iHM"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;recent article&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; has discovered a great data chain about how mobile users discover new content. Not surprisingly, the two dominant forms of finding out about new content was via social channels, where on-mobile stores came in &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;3rd&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Going ‘viral’ has always been touted as the power of the web, and allowing your users to link, share, comment and buy your content, right there in the web-browser is a powerful metric to &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;allow&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; your content to be shared and consumed virally, and selling your content online is a &lt;/span&gt;&lt;a href="http://www.entrepreneur.com/sellingonline/index.html#"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;very well researched science&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; at this point. There’s been entire college courses devoted to this ecosystem, and all of the results of this type of intense focus is available online for you to learn from. &lt;/span&gt;&lt;/div&gt;
&lt;span style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;h2 dir="ltr" style="font-weight: bold;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;The big picture&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;It’s quite easy to toss aside this device claiming Return on Investment; saying “it’s not worth my time to support that platform” and all that jazz. The truth is that as a developer, you have no idea how your content is going to be received. There’s been really no rhyme or reason to why &lt;/span&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.imangi.templerun&amp;amp;hl=en"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;some games&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; suddenly &lt;/span&gt;&lt;a href="http://penny-arcade.com/report/editorial-article/a-pregnancy-an-enthusiastic-editor-and-the-worst-name-ever-the-unlikely-suc"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;become successful&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; lately, other than users attaching themselves to content they love, and doing everything they can to tell their friends about it.&lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;I caught up with Cliff Harris recently where he mentioned that even though GSB has a tablet build, alongside being available on &lt;/span&gt;&lt;a href="http://store.steampowered.com/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;STEAM&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, he can still make over ~$1,000 / month for GSB through direct sales on his website.&amp;nbsp;
&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; text-indent: 36pt; vertical-align: baseline; white-space: pre-wrap;"&gt;

A game that’s over &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; text-indent: 36pt; vertical-align: baseline; white-space: pre-wrap;"&gt;three years old.&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; text-indent: 36pt; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;b style="font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/H2UVDLtpPAo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/1112484337286483428/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=1112484337286483428" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/1112484337286483428?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/1112484337286483428?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/H2UVDLtpPAo/indie-dev-you-should-be-selling-your.html" title="Indie Dev? You should be selling your game on the web." /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-GgHFnwJY8cs/UHMzcuvA8qI/AAAAAAAAALo/QlQI2UtB6LI/s72-c/say_what.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/10/indie-dev-you-should-be-selling-your.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkECQnw9fSp7ImA9WhJaE0U.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-3852485381754704506</id><published>2012-10-04T15:06:00.001-07:00</published><updated>2012-10-04T15:11:03.265-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-04T15:11:03.265-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="FileIO" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="threading" /><title>Simulating Blocking PPAPI functions in Native Client</title><content type="html">&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h1 dir="ltr"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;&lt;span style="background-color: white; font-family: Arial; font-size: 24px; vertical-align: baseline; white-space: pre-wrap;"&gt;Simulating blocking functions in Native Client&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;One of the largest hurdles in porting to Native Client is the Pepper API; a powerful, secure plugin api for Chrome, which NaCl utilizes to gain access to lower-level operations through the sandbox. Along with being secure, Pepper has two specific restrictions that &lt;/span&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;we’ve covered before&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;ol style="margin-bottom: 0pt; margin-top: 0pt;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;
&lt;li style="font-family: Arial; font-size: 15px; list-style-type: decimal; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;All pepper calls must come from the main thread&lt;/span&gt;&lt;/li&gt;
&lt;li style="font-family: Arial; font-size: 15px; list-style-type: decimal; vertical-align: baseline;"&gt;&lt;span style="vertical-align: baseline; white-space: pre-wrap;"&gt;All pepper calls must be non-blocking&lt;/span&gt;&lt;/li&gt;
&lt;/b&gt;&lt;/ol&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Which, as a developer porting over to NaCl, may throw a wrench in the works, considering that most C library APIs for system access are blocking functions (&lt;/span&gt;&lt;a href="http://www.cplusplus.com/reference/clibrary/cstdio/fread/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;fread&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, &lt;/span&gt;&lt;a href="http://www.cplusplus.com/reference/clibrary/cstdio/fopen/"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;fopen &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;come to mind directly). We’ve mentioned that this is a&lt;/span&gt;&lt;a href="http://www.youtube.com/watch?v=1zvhs5FR0X8"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;temporary&lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; restriction&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, and soon you’ll be able to call pepper functions off the main thread. In the meantime, however, it’d be nice to have a way to allow calls coming from the main thread to interact with Pepper in a blocking manner; this will reduce the amount of code you’ll have to change in your codebase to support the NaCl platform.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;
&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Thanks to some great insight and help from NaCl engineer Bradley Nelson, we can offer just that capability using a fancy technology : &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;coroutines&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;
&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;span style="background-color: white;"&gt;&lt;img border="0" height="266" src="http://3.bp.blogspot.com/-fWPB1KsvhWc/UG4IzsxWUOI/AAAAAAAAALU/FMcU53qwPsA/s400/dt.common.streams.StreamServer.jpg" width="400" /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span style="background-color: white;"&gt;Sometimes, Blocking is the right thing to do.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;&lt;/b&gt;&lt;/b&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;From &lt;a href="http://www.blogger.com/"&gt;&lt;span id="goog_1143579845"&gt;&lt;/span&gt;wikipedia &lt;span id="goog_1143579846"&gt;&lt;/span&gt;&lt;/a&gt;: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr"&gt;
&lt;table style="border-collapse: collapse; border: none; width: 624px;"&gt;&lt;colgroup&gt;&lt;col width="*"&gt;&lt;/col&gt;&lt;/colgroup&gt;&lt;tbody&gt;
&lt;tr style="height: 0px;"&gt;&lt;td style="border: 1px solid rgb(0, 0, 0); padding: 7px; vertical-align: top;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;Coroutines&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt; are computer program components that generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations. When subroutines are invoked, execution begins at the start and once a subroutine exits, it is finished; an instance of a subroutine only returns once. Coroutines are similar except they can also exit by calling other coroutines, which may later return to the point of calling in the original coroutine; from the coroutine point of view, it is not exciting at all but simply calling another coroutine.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;
&lt;br /&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Or for humans, coroutines are like global goto statements, that also preserve stack-state, and are exposed with a function pair : &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Setjmp.h"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;setjmp&lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and &lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;longjmp&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. The &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;setjmp&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; function saves a stack environment, which you can subsequently restore, using &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;longjmp&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. When used together, &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;setjmp&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; and &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;longjmp&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; provide a way to execute a non-local &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"&gt;goto&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;. They are typically used to pass execution control to error-handling or recovery code in a previously called routine without using the normal calling or return conventions.This process can be imagined to be a "jump" back to the point of program execution where setjmp saved the environment.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;
&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;&lt;span style="background-color: white; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;There’s plenty of documentation on how these APIs work, so I’ll ignore the description of walk-through here, and refer you to the resources section at the end of this article.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;
&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;h2 dir="ltr"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;Using coroutines to emulate blocking Pepper Calls&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;
&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Firstly, recall how Chrome interacts with Native Client; The PPAPIs are effectively plugin APIs that chrome calls back into, so execution control can either be owned by Chrome, or owned by your NaCl plugin; coprocessing is not an option. So, for us to simulate a blocking PPAPI call on the main thread, it must stop execution, store the state, and allow Chrome to regain execution control. Chrome can continue forward and process the pepper call, and in the resulting callback, we can process the result, and continue execution back where we left off. The diagram below shows this in more visual form:&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;&lt;a href="http://3.bp.blogspot.com/-k5NsFJnezyA/UG4Ejqn0tZI/AAAAAAAAALA/C2AuuDjBvAk/s1600/blocking.jpg" imageanchor="1" style="background-color: white; margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="255" src="http://3.bp.blogspot.com/-k5NsFJnezyA/UG4Ejqn0tZI/AAAAAAAAALA/C2AuuDjBvAk/s400/blocking.jpg" width="400" /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;
&lt;b style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/b&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;&lt;span style="background-color: white; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;When used correctly, the setjmp/longjmp pair allow us to save and restore executional state. Meaning we can exit the current program counter and stack, allow execution to occur at a different logic branch, and when the time is right, resume execution control back to where we wanted. This is perfect for what we want to accomplish with PPAPI. &lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;b id="internal-source-marker_0.9985584153328091" style="font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;h2 dir="ltr"&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;The source code&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;b id="internal-source-marker_0.9985584153328091" style="background-color: white; font-weight: normal;"&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;You can grab the &lt;/span&gt;&lt;a href="https://github.com/mainroach/nacl-examples/tree/master/co-routines"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;source code to a working example from my github repo&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;; which will utilize the new, fancy &lt;/span&gt;&lt;a href="http://mainroach.blogspot.com/2012/10/official-nacl-vs2010-add-in-available.html"&gt;&lt;span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Visual Studio 2010 add-in&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; for native client. &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The source code wraps up most of the heavy lifting of how co-routines can be utilized in NaCl; so for the sake of brevity, I’ll show you the expected workflow using the C APIs.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial;"&gt;&lt;span style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style="font-weight: normal;"&gt;&lt;/b&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;b style="font-weight: normal;"&gt;&lt;code style="background-color: white;"&gt;static PP_Bool Instance_DidCreate(PP_Instance instance,
                                  uint32_t argc,
                                  const char* argn[],
                                  const char* argv[]) {
 appInstance_ = instance;
 //called when the app boots. Allows user to own their control loop
 coroutine::Create(userUpdate);
 return PP_TRUE;
}
&lt;/code&gt;&lt;/b&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;b style="font-weight: normal;"&gt;
&lt;/b&gt;
&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;When the application is created, the first thing we do is allow the co-routine system to set up the execution slicing. Simply calling &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;coroutine::create&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; is sufficient. You pass in as a parameter a function which will be ran during execution slicing.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code style="background-color: white;"&gt;
void userUpdate(void) {
  for (;;) {
   
 //..some code goes here....
 
 //randomly kick off a file load call for whatever reason
 if(rand() %50 == 25)
  blockingURLRead();

 //some other code goes here....


 //IMPORTANT, at the end of the while-loop, 
 //we need to signal execution control back to chrome for processing 
 coroutine::Flush();
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;One of the nice things about using this coroutine setup is that you gain the ability to treat your app updating as though you were a native application: by owning your processing loop. &amp;nbsp;In the code above, we randomly kick off a call to load some file from the intertubes. At the end of the loop, we need to call &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;coroutine::flush&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; which will handle some of the time-slice execution that we’ll be using to make all this work.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code style="background-color: white;"&gt;
void blockingURLRead()
{

 //rather than actually calling readFileFromURL, 
 //we simulate some arbitrary Pepper API function by just calling 'callonmainthread'
 PP_CompletionCallback fileLoadedCB = PP_MakeCompletionCallback(onFileLoaded, 0);
 ppb_core_interface-&amp;gt;CallOnMainThread(0, fileLoadedCB, 0);

 //now that the async call has been kicked off to chrome, 
 //we yield execution control back to chrome so it can service it
 coroutine::Block();

 //once 'onFileLoaded' has been called, we resume control here.
 printf(&amp;amp;fileIOBuffer[0]);// AKA DO SOMETHING WITH THE FILE DATA YOU LOADED!
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;The blocking URL read will kick off the Async pepper call, which simply pushes a command into Chrome’s processing queue; Recall Chrome won’t process this event until it regains execution control sometime in the future.&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Once kicked off, &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;coroutine::Block&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt; is called, which will halt execution of the main thread at this location, yielding execution control back to Chrome to do processing.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir="ltr"&gt;
&lt;pre style="border: 1px dashed rgb(153, 153, 153); color: black; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code style="background-color: white;"&gt;
void onFileLoaded(void* pData, int32_t dataSize)
{
 // process data returned from file loading
 strcpy(&amp;amp;fileIOBuffer[0], "I AM A CHEESEBURGER");

 //once all the data has been read, we can regain execution control
 coroutine::Resume();
}

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Once chrome has time to process the command, it will issue the callback to your NaCl application with the results (onFileLoaded). For the sake of sanity, we move the data out of this callback system to a heap variable, and call &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;coroutine::Resume&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;, which will restore the stack state from where we last called &lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;coroutine:Block&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2 dir="ltr"&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 19px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;Caveats and limitations&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 19px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="background-color: white; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;There’s some nuances with getting this working correctly, most dominantly that we must manipulate the stack to allocate enough space such that when we resume our operations data on the stack didn’t get clobbered. For safety measures, I suggest increasing the stack size for your application (I’ve found 3MB to be sufficient for most apps) . &lt;/span&gt;&lt;/div&gt;
&lt;div dir="ltr" style="margin-bottom: 0pt; margin-top: 0pt; text-indent: 36pt;"&gt;
&lt;span style="background-color: white; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;Also note that some IDEs (VS included) may do weird things when deep in this level of stack manipulation; so be warned that there may be dragons in the future.&lt;/span&gt;&lt;/div&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial; vertical-align: baseline;"&gt;&lt;span style="background-color: white; font-size: 15px; white-space: pre-wrap;"&gt;But at least those dragons don’t require you to re-factor your code as much ;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;~Main&lt;/span&gt;&lt;br /&gt;
&lt;h3 dir="ltr"&gt;
&lt;span style="background-color: white; color: #666666; font-family: Arial; font-size: 16px; vertical-align: baseline; white-space: pre-wrap;"&gt;Resources:&lt;/span&gt;&lt;/h3&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Setjmp.h"&gt;http://en.wikipedia.org/wiki/Setjmp.h&lt;/a&gt;&lt;/span&gt;&lt;span style="color: #1155cc; font-family: Arial; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;a href="http://tia.mat.br/posts/async_io_with_coroutines/"&gt;http://tia.mat.br/posts/async_io_with_coroutines/&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.csl.mtu.edu/cs4411.ck/www/NOTES/non-local-goto/coroutine.html" style="background-color: white; font-family: Arial; white-space: pre-wrap;"&gt;http://www.csl.mtu.edu/cs4411.ck/www/NOTES/non-local-goto/coroutine.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mfichman.blogspot.com/2011/05/lua-style-coroutines-in-c.html" style="background-color: white; font-family: Arial; white-space: pre-wrap;"&gt;http://mfichman.blogspot.com/2011/05/lua-style-coroutines-in-c.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://web.eecs.utk.edu/~huangj/cs360/360/notes/Setjmp/lecture.html" style="background-color: white; font-family: Arial; white-space: pre-wrap;"&gt;http://web.eecs.utk.edu/~huangj/cs360/360/notes/Setjmp/lecture.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://libstream.sourceforge.net/coroutine.html" style="background-color: white; font-family: Arial; font-style: italic; white-space: pre-wrap;"&gt;http://libstream.sourceforge.net/coroutine.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Arial; font-size: 15px; font-style: italic; vertical-align: baseline; white-space: pre-wrap;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;span style="background-color: white;"&gt;&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;&lt;/span&gt;
&lt;/center&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/uUGPc4frSZk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/3852485381754704506/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=3852485381754704506" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/3852485381754704506?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/3852485381754704506?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/uUGPc4frSZk/simulating-blocking-ppapi-functions-in.html" title="Simulating Blocking PPAPI functions in Native Client" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-fWPB1KsvhWc/UG4IzsxWUOI/AAAAAAAAALU/FMcU53qwPsA/s72-c/dt.common.streams.StreamServer.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/10/simulating-blocking-ppapi-functions-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkINR387eip7ImA9WhJaEU8.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-8203203617335171221</id><published>2012-10-01T14:56:00.001-07:00</published><updated>2012-10-01T14:56:36.102-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-01T14:56:36.102-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><title>Official NaCl VS2010 add-in available</title><content type="html">&lt;br /&gt;
&lt;span style="background-color: white; font-family: Arial; font-size: 13px; vertical-align: baseline; white-space: pre-wrap;"&gt;I'd first discussed getting a&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual.html"&gt; visual studio build for Native Client&lt;/a&gt; working a while back. Afterwards, we decided a professional version was in need, and after &lt;a href="http://www.youtube.com/watch?v=1zvhs5FR0X8"&gt;talking about this at Google I/O&lt;/a&gt; this year, it's finally hit the streets. In contrast to my previous article, with the plugin, you'll no longer need to download chromium source code, or copy the header files. &lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" height="211" src="http://2.bp.blogspot.com/-EwItDxS8_uQ/UGoP2gzeQGI/AAAAAAAAAKs/K8wExYRLsZ0/s320/success.jpeg" width="320" /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Let's get started:&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;If you haven't yet, download the nacl sdk (say, to c:\nacl\)&lt;/li&gt;
&lt;li&gt;Install pepper-canary if you haven't yet&amp;nbsp;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;From a command line, run c:\nacl\naclsdk install pepper_canary&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;From a command line, run c:\nacl\naclsdk install vs_addin&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;which will grab the vs2010 package and bring it down onto your machine&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;Browse to c:\nacl\vs_addin&lt;/li&gt;
&lt;li&gt;Double click install.bat&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
Once installed, you can create a new PPAPI and NaCl platform, just like &lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual_30.html"&gt;we've discussed before&lt;/a&gt;!&lt;br /&gt;
&lt;br /&gt;
As always, send us feedback!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/aJ2PSeZlsg0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/8203203617335171221/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=8203203617335171221" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/8203203617335171221?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/8203203617335171221?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/aJ2PSeZlsg0/official-nacl-vs2010-add-in-available.html" title="Official NaCl VS2010 add-in available" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-EwItDxS8_uQ/UGoP2gzeQGI/AAAAAAAAAKs/K8wExYRLsZ0/s72-c/success.jpeg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/10/official-nacl-vs2010-add-in-available.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYHRX87cCp7ImA9WhJUE0U.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-4304679367335594861</id><published>2012-09-05T13:37:00.002-07:00</published><updated>2012-09-11T10:55:34.108-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-11T10:55:34.108-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>NaCl &amp; UDP Sockets</title><content type="html">One of the big pieces of feedback&amp;nbsp;we've&amp;nbsp;been getting from developers &amp;nbsp;is that Native Client needs better networking support (&lt;i&gt;read :sockets&lt;/i&gt;). Largely sockets have been one of the larger security issues for Native Client and the open web; Imagine if a web page could start sniffing any open packet communication on your computer :(&amp;nbsp;Thankfully though, that’s all changing. With the new&lt;a href="https://developer.chrome.com/trunk/apps/about_apps.html"&gt; Platform Apps&lt;/a&gt; technology on the horizon, we now have the ability to play with UDP inside of Native Client, and this post will show you how to play with the early preview of the technology.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="239" src="http://1.bp.blogspot.com/-sH-emuTVmGA/UEeekCcB8sI/AAAAAAAAAKY/EO2yFO1DKh4/s320/network_cables_02.jpg" width="320" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span style="text-align: start;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;According to legend, the internet is a series of tubes. As such, we should allow you to send data through those tubes using Native Client&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #ee5555;"&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;WARNING:&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
The future of this feature is in flux;&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
The steps below are valid as of 9.9.2012 and are subject to change as the future changes.&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
Please implement this functionality at your own risk.&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&amp;nbsp;Getting Started with the prototype UDP APIs:&lt;/h3&gt;
UDP APIs are currently in draft form, meaning they are not&amp;nbsp;available&amp;nbsp;in the &lt;i&gt;stable&lt;/i&gt;&amp;nbsp;version of Chrome; In order to play around with these features, you need to be running a &lt;a href="https://tools.google.com/dlpage/chromesxs"&gt;canary build of Chrome&lt;/a&gt;.&lt;br /&gt;
&lt;h4&gt;
&amp;nbsp;1. Getting the private headers&lt;/h4&gt;
Copy the private headers from the Chrome repo into the SDK repo&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;C:\..\chromium\src\ppapi\c\private&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;C:\nacl\pepper_canary\include\ppapi\c\private&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
Since these headers are currently private, you’ll need to pull them from the &lt;a href="http://code.google.com/p/chromium/wiki/UsingNewGit#Initial_checkout"&gt;Chrome source code&lt;/a&gt;. Once these APIs’ stabilize, and are moved out of the private repo, this step will no longer be required&lt;br /&gt;
&lt;br /&gt;
Once done, you can add the following includes to your NaCl app:&lt;br /&gt;
&lt;i&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;#include "ppapi/c/private/ppb_udp_socket_private.h"&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
2. Run as a packaged app&lt;/h4&gt;
UDP support in NaCl is ONLY provided as a &lt;a href="https://developer.chrome.com/trunk/apps/about_apps.html"&gt;Chrome extension / packaged app&lt;/a&gt;. You cannot develop as a pepper plugin; As such, you’ll need to create a manifest file that’s co-resident with your NaCl app, and launch chrome with &lt;i&gt;--load-extension=PathToYourFolder&lt;/i&gt;. This will add the app to your new tab page, that you can then click-on to load. For instance&lt;i&gt; --load-extention=C:/myapp/bin/&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;b&gt;NOTE : &lt;/b&gt;If the above gives you a 'could not load manifest' error for whatever reason, then you can load the application as an &lt;a href="http://developer.chrome.com/extensions/getstarted.html"&gt;unpacked&amp;nbsp;extension&lt;/a&gt;, and things will still work properly.&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;br /&gt;
&lt;h4&gt;
3. Enable the experimental UDP apis&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Go to about:flags and enable "NaCl Socket API"&lt;/li&gt;
&lt;li&gt;Make sure you launch chrome with &lt;i&gt;--allow-nacl-socket-api=IPAddy&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Make sure you launch chrome with &lt;i&gt;--enable-nacl&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
In the current state of things, you MUST define what IP address you're going to be connecting to (minus the port number) from native client. For instance &lt;i&gt;--allow-nacl-socket-api=127.0.0.1&lt;/i&gt;&amp;nbsp;will allow your UDP socket to properly connect to that IP address.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
4. Note the API differences&lt;/h4&gt;
Note that the UDP API is not the same as standard socket APIs, due to the restrictions of the&lt;a href="http://www.chromium.org/nativeclient/getting-started/getting-started-background-and-basics"&gt; Pepper API&lt;/a&gt;, the interfaces for UDP are:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Non blocking&lt;/li&gt;
&lt;li&gt;Required to be called from the main thread &lt;i&gt;&lt;u&gt;&lt;span style="color: red;"&gt;(a fix for this is in the works)&lt;/span&gt;&lt;/u&gt;&lt;/i&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
To get a feel for the differences, check out &lt;i&gt;ppapi/c/private/ppb_udp_socket_private.h&lt;/i&gt; which generally shows how to create a socket to communicate to; Because of the PPAPI restrictions, the usage of these APIs requires some jiggl’n.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
5. Some implementation notes&lt;/h4&gt;
1) You’ll notice that&lt;i&gt; Bind(..)&lt;/i&gt; will return -1, which is a correct, valid return, meaning ‘process pending’; see &lt;i&gt;pp_errors.h&lt;/i&gt; for the full list.&lt;br /&gt;
&lt;br /&gt;
2) Notice all the UDP functions take a callback, it’s worth noting that those callbacks will always be called, even if a function fails. If a failure occurs, the datasize param will have a value of -2&lt;br /&gt;
&lt;br /&gt;
3) The IP address that you use to bind your client to should be generated via calling &amp;nbsp;&lt;i&gt;NetAddressPrivate::GetAnyAddress&lt;/i&gt;;&amp;nbsp;Once done, you should call &lt;i&gt;NetAddressPrivate::ReplacePort&lt;/i&gt; to update the address with your desired port. Doing so you will bind the UDP port on all network interfaces for the system.&lt;br /&gt;
&lt;br /&gt;
4) To connect to your server, you should be using &lt;i&gt;CreateFromIPv4Address . &lt;/i&gt;For testing purpose you can &amp;nbsp;bind localhost (127.0.0.1) with some port.&lt;br /&gt;
&lt;br /&gt;
5) Note that the &lt;i&gt;RecvFrom&lt;/i&gt;&amp;nbsp;takes in a buffer parameter, but due to the async nature of the call, it is possible, but incorrect to make multiple RecvFrom calls on the same socket while a previous call is in flight. Chrome can write async to this buffer at any time, causing your data to get mangled&lt;span style="font-family: inherit;"&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: white; color: #222222;"&gt;&lt;span style="font-family: inherit;"&gt;IE. Simultaneous&amp;nbsp;outstanding reads are not possible. The same principal applies with &lt;i&gt;SendTo&lt;/i&gt;, you have to wait until previous data portion sent and buffer should stay valid&amp;nbsp;until&amp;nbsp;callback is called. You can, however, call &lt;i&gt;RecvFrom&amp;nbsp;&lt;/i&gt;and&amp;nbsp;&lt;i&gt;SendTo &lt;/i&gt;can be called in parallel on the same socket without any issues.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
6. get ready for the roll out&lt;/h4&gt;
&lt;a href="https://developer.chrome.com/trunk/apps/about_apps.html"&gt;Chrome Apps&lt;/a&gt; are still in early development phases, and when they release, will have full support for UDP sockets w/o needing flags or special params. There will be some minor hoops to jump through that are not yet documented, so stay tuned to Chrome for more!&lt;br /&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
Source Code&lt;/h3&gt;
You can grab source code to a simple win32 client communicating to a &lt;a href="https://github.com/mainroach/nacl-examples/tree/master/UDP_private"&gt;NaCl platform app via UDP on my github repo&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The example project works by allowing the client to send a message to the server. To use, launch the server first, then launch the client. The server will&amp;nbsp;receive&amp;nbsp;a message that it displays in the console window.&lt;br /&gt;
&lt;br /&gt;
For reference, I launch Chrome with&lt;br /&gt;
&lt;i&gt;--allow-nacl-socket-api=127.0.0.1 --no-sandbox --load-extension="C:\nacl_examples\src\UDP_private\client" &amp;nbsp;--enable-nacl&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-indent: 36pt;"&gt;~Main&lt;/span&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/4OIF3XeH_DM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/4304679367335594861/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=4304679367335594861" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/4304679367335594861?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/4304679367335594861?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/4OIF3XeH_DM/nacl-udp-sockets.html" title="NaCl &amp; UDP Sockets" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-sH-emuTVmGA/UEeekCcB8sI/AAAAAAAAAKY/EO2yFO1DKh4/s72-c/network_cables_02.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/09/nacl-udp-sockets.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcDSHs-eCp7ImA9WhJWGE4.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-6388677486416301979</id><published>2012-08-24T11:14:00.000-07:00</published><updated>2012-08-24T11:14:39.550-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-08-24T11:14:39.550-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="FileIO" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="graphics" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><title>NaCl &amp; Writing files outside the sandbox</title><content type="html">Wouldn't it be great if you could do some processing in NaCl and save the results to a file outside of the sandbox? Good news! This article shows you how.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="300" src="http://4.bp.blogspot.com/-B31OfUvQpNE/UDfBxaHEGxI/AAAAAAAAAKE/6DZHMe7I50Y/s400/Indoor-sandbox-toys.jpg" width="400" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;i&gt;Putting things in a sandbox is the easy part; Getting them out is often the difficult part;&amp;nbsp;Especially&amp;nbsp;when you don't want dirt all over the carpet..&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
In a &lt;a href="http://mainroach.blogspot.com/2012/07/native-client-and-loading-user-chosen.html"&gt;previous post&lt;/a&gt;, I talked about how you can load a file into NaCl from OUTSIDE the Chrome sandbox. Which is a great thing for those of you who want to create content-editors &amp;nbsp;or content-viewers inside of Native Client.This time, we'll talk about how to get those files from NaCl back out to the disk.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The bad news&lt;/b&gt; is that Native Client does not expose an API that allows you to write files outside of the sandbox.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The good news&lt;/b&gt; is that HTML5 does.&lt;br /&gt;
&lt;br /&gt;
This means that if you have data inside of NaCl that you want to write to disk, you first need to pass it over to Javascript using the &lt;i&gt;PostMessage&lt;/i&gt; API.&lt;br /&gt;
&lt;h3&gt;
1. Saving a file to disk in HTML5&lt;/h3&gt;
&lt;span style="font-family: inherit;"&gt;HTML5 exposes a&lt;/span&gt;&lt;a href="http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download" style="font-family: inherit;"&gt; download attribute&lt;/a&gt;&amp;nbsp;which does the process of writing a file to disk from Javascript. W&lt;span style="background-color: white; color: #222222; font-family: inherit;"&gt;hen used on an anchor, this attribute signifies that the resource it points to should be downloaded by the browser rather than navigating to it.&lt;/span&gt;&amp;nbsp;It&amp;nbsp;requires&amp;nbsp;a user click, but will allow the data to be streamed.&lt;br /&gt;
&lt;br /&gt;
Here's a Javascript example of how to&amp;nbsp;create a&amp;nbsp; BlobBuilder, and create a link that will let you download some&amp;nbsp;arbitrary&amp;nbsp;data&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;function downloadData function(fileData, outputName){

  var bb = new BlobBuilder();
  bb.append(fileData);


  const MIME_TYPE = 'text/plain';

  var a = document.createElement('a'); //create a new element for the user to click on.
  a.download =  outputName ;
  a.href = window.URL.createObjectURL(bb.getBlob(MIME_TYPE));
  a.textContent = 'Click Here';
  a.dataset.downloadurl = [MIME_TYPE, a.download, a.href].join(':');

  document.getElementById('buttonDiv').appendChild(a);
}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
You can set up this process in Javascript before needing to touch Native Client. That way you can get everything working at a functional level, and then just push the data from NaCl into it when ready.&lt;br /&gt;
&lt;h3&gt;
2. Getting binary data from NaCl to Javascript&lt;/h3&gt;
To get our binary data to Javascript from NaCl, &amp;nbsp;we need to do 2 things:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Create a varArrayBuffer to hold the binary data&lt;/li&gt;
&lt;li&gt;Push the binary data back to&amp;nbsp;java script&amp;nbsp;via PostMessage.&lt;/li&gt;
&lt;/ol&gt;
The example code below shows&amp;nbsp;this process, and is using the C Interfaces for PPAPI.&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;PP_Var v2 = ppb_varArrayBuffer_interface-&amp;gt;Create(dataSize);

//we map the array buffer and copy the input data into it.
void* pDst = ppb_varArrayBuffer_interface-&amp;gt;Map(v2);
memcpy(pDst,pData,dataSize);
ppb_varArrayBuffer_interface-&amp;gt;Unmap(v2);

//send the data to Javascript, using Postmessage
ppb_messaging_interface-&amp;gt;PostMessage(appInstance_,v2);
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
3. Source Code&lt;/h3&gt;
You can find a &lt;a href="https://github.com/mainroach/nacl-examples/tree/master/fileblob_load"&gt;working example&lt;/a&gt; on my &lt;a href="https://github.com/mainroach/"&gt;Github repo&lt;/a&gt;. This example will allow you to load data from disk, as well as write it back to disk.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Note&lt;/b&gt; that this uses the Visual Studio add in (which is not public yet), but you can by-pass that and compile the C files with the make data that comes inside the NaCl SDK.&lt;br /&gt;
&lt;br /&gt;
~Main


&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/au3tIioQMUI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/6388677486416301979/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=6388677486416301979" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/6388677486416301979?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/6388677486416301979?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/au3tIioQMUI/nacl-writing-files-outside-sandbox.html" title="NaCl &amp; Writing files outside the sandbox" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-B31OfUvQpNE/UDfBxaHEGxI/AAAAAAAAAKE/6DZHMe7I50Y/s72-c/Indoor-sandbox-toys.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/08/nacl-writing-files-outside-sandbox.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ANRXk6fSp7ImA9WhJQFE8.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-3493355664905054299</id><published>2012-07-27T13:38:00.004-07:00</published><updated>2012-07-27T13:43:14.715-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-27T13:43:14.715-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FileIO" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="debugging" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>Native Client and loading a user-chosen file from disk</title><content type="html">I get this question quite a bit: &lt;i&gt;How do I load a video/image/audio from the users' disk in Native Client&lt;/i&gt;? The answer is 'easily' if you follow these 3 simple steps.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-17tqQOyrVz4/UBL9DYyzDOI/AAAAAAAAAJw/A2ZRJHJo004/s1600/70+Land+Shark.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="228" src="http://1.bp.blogspot.com/-17tqQOyrVz4/UBL9DYyzDOI/AAAAAAAAAJw/A2ZRJHJo004/s320/70+Land+Shark.jpeg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The LandShark teaches us great principles about how to access the world outside your bounded environment. Much like loading files from outside the NaCl sandbox.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Recall that Native Client has&lt;a href="http://mainroach.blogspot.com/2012/01/nacl-best-practices-for-fileio.html"&gt; two primary ways&lt;/a&gt; to deal with files:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Fetching the data from a&amp;nbsp;web service, using &lt;a href="https://developers.google.com/native-client/devguide/coding/URLLoading"&gt;geturl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Reading/writing the data to the &lt;a href="https://developers.google.com/native-client/peppercpp/classpp_1_1_file_system"&gt;local filestore&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
These are the &lt;b&gt;safe &lt;/b&gt;ways allowed through the&amp;nbsp;sand boxing&amp;nbsp;process to read/write files. Of course, there's also the&lt;a href="http://mainroach.blogspot.com/2012/02/nacl-dangerous-file-io.html"&gt; &lt;i&gt;non safe&lt;/i&gt;&amp;nbsp;way&lt;/a&gt; of reading / writing files, and the way that &lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual_30.html"&gt;bypasses the sandbox&lt;/a&gt;; but that's dark magic.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.html5rocks.com/en/tutorials/file/dndfiles/"&gt;HTML5&amp;nbsp;recently&amp;nbsp;exposed&lt;/a&gt; a method for which a user can specify a file/files from their disk (using a file-picker) that HTML5 could then load into memory, and manipulate. It turns out, that using a bit of a trick, you can open these files directly with NaCl.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;






1. Prompt the user to pick a file&lt;/h3&gt;
In Javascript, allow the user to pick a file by adding this HTML to your page. (I cheated by copying some &lt;a href="http://www.html5rocks.com/en/tutorials/file/dndfiles/"&gt;code from Eric&lt;/a&gt; ;)&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;           
&amp;lt;input type="file" id="files" name="file" /&amp;gt;
&amp;lt;output id="list"&amp;gt;&amp;lt;/output&amp;gt;

&amp;lt;script&amp;gt;
  function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object

    var f = files[0]; // the first selected file    
//.....
  document.getElementById('files').addEventListener('change', handleFileSelect, false);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&amp;nbsp;This above block will add a nice little 'Choose File' button to your HTML page, that when clicked, will open a FileChooser dialog that the user can pick a file. (note, the code above is not safe, and doesn't check for the proper edge cases )&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;






2. Generate the BlobURL&lt;/h3&gt;
Once we have the file object, we can use a&lt;a href="https://developer.mozilla.org/en/DOM/window.URL.createObjectURL"&gt; specific API&lt;/a&gt; to generate a URL encoded path to the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt; function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object

    var f = files[0];
   &lt;b&gt; var objectURL = window.webkitURL.createObjectURL(f);
    var naclObj = document.getElementById('blob_load');
    naclObj.postMessage(objectURL);&lt;/b&gt;
    
  }
  document.getElementById('files').addEventListener('change', handleFileSelect, false);
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The &lt;i&gt;createObjectURL&lt;/i&gt; function will generate something like:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;blob:http%3A//localhost%3A5103/6c941740-dc7e-4ec7-98e7-876b81e943a0&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Which we can then pass directly to the NaCl module using the &lt;i&gt;postMessage&lt;/i&gt;&amp;nbsp;API.&lt;br /&gt;
&lt;h3&gt;






3. Load and process the file using Native Client&lt;/h3&gt;
On the NaCl side of the fence, we can&amp;nbsp;receive&amp;nbsp;the message from Javascript (via&amp;nbsp;&lt;i&gt;postMessage&lt;/i&gt;) by using the proper message handler function. The one secret here is properly converting the message from a PP_Var to a CString (check the NaCl examples on how to use &lt;i&gt;VarToUTF8&lt;/i&gt; properly).&amp;nbsp;&lt;span style="background-color: white;"&gt;Second, we call&lt;/span&gt;&lt;span style="background-color: white;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://developers.google.com/native-client/devguide/coding/URLLoading"&gt;getURL&amp;nbsp;&lt;/a&gt;&lt;span style="background-color: white;"&gt;on the object to load it (see the geturl example in the SDK for the proper source code to this).&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;//Main.cpp module, C++ code
static void Messaging_HandleMessage(PP_Instance instance, struct PP_Var message) 
{
    uint32_t len;
    const char* blobURL = VarToCStr ( message);
    //kick off loads from our files
    readFileFromURL(blobURL,onFileLoaded );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: white;"&gt;Note that&lt;/span&gt;&lt;span style="background-color: white;"&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;readFileFromURL&lt;/i&gt;&lt;span style="background-color: white;"&gt;&amp;nbsp;function above is mearly a wrapper to the larger getURL opeartaion; it&lt;/span&gt;&lt;span style="background-color: white;"&gt;&amp;nbsp;will properly kick off the&lt;/span&gt;&lt;span style="background-color: white;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://developers.google.com/native-client/devguide/coding/URLLoading"&gt;getURL&lt;/a&gt;&lt;span style="background-color: white;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: white;"&gt;command, and respond to multiple reads and responses of grabbing the file, and calling the proper callback (onFileLoaded) when complete.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And that's it! With this simple setup, you can easily load audio, video, and images from the user's disk to do processing in Native Client!&lt;br /&gt;
&lt;br /&gt;
Go forth and be &lt;i&gt;awesome&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
~Main


&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/uRSkbeJov1Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/3493355664905054299/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=3493355664905054299" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/3493355664905054299?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/3493355664905054299?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/uRSkbeJov1Q/native-client-and-loading-user-chosen.html" title="Native Client and loading a user-chosen file from disk" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-17tqQOyrVz4/UBL9DYyzDOI/AAAAAAAAAJw/A2ZRJHJo004/s72-c/70+Land+Shark.jpeg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/07/native-client-and-loading-user-chosen.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YFR3czcSp7ImA9WhJSGUk.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-7115370418794844815</id><published>2012-07-09T14:28:00.001-07:00</published><updated>2012-07-10T11:31:56.989-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-10T11:31:56.989-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome Web Store" /><title>Running NaCl on Facebook</title><content type="html">Native Client is an amazing technology that allows you to run C++ on the web. With the current Chrome Web Store restrictions, it limits some of the functionality of getting your NaCl apps to the masses. This post will talk about a nice little work-around to the CWS install process that will allow you run your NaCl apps on Facebook&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-TwksYmpJHng/T_tEI2-hwQI/AAAAAAAAAJY/RDGLO1Hrhwg/s1600/392.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="266" src="http://3.bp.blogspot.com/-TwksYmpJHng/T_tEI2-hwQI/AAAAAAAAAJY/RDGLO1Hrhwg/s400/392.jpeg" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Jumping through hoops is the basic working attribute of the web-programmer. For dolphins though, it's their way of saying 'I'm better than you.'&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style="background-color: #ea9999;"&gt;
&lt;br /&gt;
&lt;center&gt;&lt;b&gt;WARNING&lt;/b&gt;:&lt;br /&gt; The future of this feature is currently unknown; Please be warned that this functionality may be removed from Chrome in the future if it's deemed a security concern. &lt;br /&gt;&lt;u&gt;&lt;b&gt;Please implement this functionality at your own risk.&lt;/b&gt;&lt;/u&gt;&lt;/center&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;h3&gt;








&lt;b&gt;Understanding Chrome Web Store and Native Client&lt;/b&gt;&lt;/h3&gt;
Firstly, understand that the Chrome Web Store (CWS) restriction in running NaCl on the web is a multifaced problem; For our immediate needs, let's say that we use it as a safety measure, so that, through policy, we can remove any potential malicious code from the web, and also have a chance to reach out to developers when PNaCl comes out.&lt;br /&gt;
&lt;br /&gt;
As such, the main hurdle running NaCl on sites like Facebook has less to do with NaCl, and more to do with getting around CWS install issues.&lt;br /&gt;
&lt;br /&gt;
As a bit of background reading, I reccomend you read &lt;a href="https://developers.google.com/native-client/devguide/distributing"&gt;distributing your application&lt;/a&gt; on the NaCl developers page, which will highlight some terminology we'll be using.&lt;br /&gt;
&lt;br /&gt;
Currently, the user has two main ways to install a Hosted CWS application&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Browse to the chrome web-store, find your app, and hit 'install'&lt;/li&gt;
&lt;li&gt;Browse to your url (blah.url.com) and click the &lt;a href="https://developers.google.com/chrome/web-store/docs/inline_installation"&gt;inline install button&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
The inline install process is nice, because it allows the users to install right from your page, without having to leave it.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;








&lt;b&gt;Installing a CWS app from facebook&lt;/b&gt;&lt;/h3&gt;
A facebook game page, (much like a G+ games page) works by nesting an iframe on the desired page, which loads the game itself. One of the large issues with CWS inline install, is that it &lt;i&gt;doesn't work&lt;/i&gt;&amp;nbsp;when served from an iframe, because the origin calling the install is registered from the &lt;i&gt;outer frame's domain&lt;/i&gt;&amp;nbsp;not the inner one. As such, CWS install would fail, since we're trying to install an app from a different domain than what the app defines in the CWS dashboard.&lt;br /&gt;
&lt;br /&gt;
There is a nice work-around though, in that &lt;i&gt;you can open a popup and install from there&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
As such, here's what we hope to achieve as the best-case scenario:&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;The user will open your games-page on facebook&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;ie apps.facebook.com/mainroachgame&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;If the user has never installed the app,&amp;nbsp;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;then a popup window will appear allowing the user to inline-install your app&lt;/li&gt;
&lt;li&gt;The user will be able to play your NaCl game on facebook now.&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;If the user has the app installed&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;then it will&amp;nbsp;magically&amp;nbsp;load, and no one will know the crazy hoops you've had to jump through.&lt;/li&gt;
&lt;/ol&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;








&lt;b&gt;Inline installation from the inner-frame&lt;/b&gt;&lt;/h3&gt;
Although we can't do inline-install from the inner-frame, we can, however, do inline-install from a popup window.&lt;br /&gt;
&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;In the CWS dashboard, define the URL for the app to your domain&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;ie chrome.mainroach.net&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Create a page on your domain, which holds the&amp;nbsp;proper HTML for&amp;nbsp;&lt;a href="https://developers.google.com/chrome/web-store/docs/inline_installation"&gt;inline install&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;ie chrome.mainroach.net/app_install.html&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Create a page on your domain, which hosts the NaCl app.&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;ie chrome.mainroach.net/index.html&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Your NaCl page should first test if the app is already installed before adding the &lt;i&gt;embed&lt;/i&gt;&amp;nbsp;tag to the page&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;you should use the new API :&amp;nbsp;chrome.app.installState(callback), which will return "installed" "not_installed" or "disabled"&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;If the result is 'not_installed", then open a pop-up window pointing to your install url&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;ie chrome.mainroach.net/app_install.html&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;NOTE, that pop-up windows are normally blocked, unless initated from a user-action. So adding a nice 'Click here to enable this game' button works wonders&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;In the Facebook app dashboard, point the URL to your nacl page&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;ie chrome.mainroach.net/index.html&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;h3&gt;








&lt;b&gt;Here's some code!&lt;/b&gt;&lt;/h3&gt;
&lt;b&gt;file &lt;/b&gt;&lt;i&gt;: chrome.mainroach.net/index.html&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;b&gt; &lt;/b&gt;&amp;lt;script&amp;gt;
var installStateNode = document.getElementById('install-state');
    if (chrome.app.installState) { //this API is only available in chrome 20+
      chrome.app.installState(function(installState) {
  if(installState == "not_installed")
  {   //if the app isn't installed, show the 'install' button
   document.getElementById('not_installed_btn').show();
  }
  else
  {  //otherwise, append the NaCl embed tag to things, and get running!
   appendNaClEmbedToDOM(...);
  }
      });
    } else {
      alert("this requires chrome 20");
    }
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Later on, we need some control of a popup to show the user; so we define a div, containing a button which will launch our inline-install window.
&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;b&gt; &lt;/b&gt; function popupInstall()
    { //please refer to the inline-install documentation for what this page should contain.
     window.create("./inline_install.html",...);
    }
    
  
&amp;lt;/script&amp;gt;
  &amp;lt;!-- blah blah blah --&amp;gt;
  &amp;lt;div id="not_installed_btn"&amp;gt;
&amp;lt;a href="" onclick="popupInstall();"&amp;gt;Install some stuff&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;








&lt;b&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Notes:&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Please note that this is a pretty gnarly hack of the CWS install process in order to run NaCl on Facebook. Remember, Portable Native Client, or PNaCl (pronounced 'pinnacle') will allow you to run NaCl apps in the open web without the need to install from CWS. Expect more info on that, soon.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="background-color: white;"&gt;&lt;span style="font-family: Times, 'Times New Roman', serif;"&gt;Recall that this only works for &lt;i&gt;hosted&lt;/i&gt;&amp;nbsp;NaCl apps, which, depending on the size of your assets may not be ideal, when compared to a &lt;i&gt;package&lt;/i&gt;&amp;nbsp;app, which most NaCl devs are drawn too, since hosting is free.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style="color: #222222;"&gt;
&lt;br /&gt;
&lt;div style="color: black;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
~Main


&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/euMZSs-4EaQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/7115370418794844815/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=7115370418794844815" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/7115370418794844815?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/7115370418794844815?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/euMZSs-4EaQ/running-nacl-on-facebook.html" title="Running NaCl on Facebook" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-TwksYmpJHng/T_tEI2-hwQI/AAAAAAAAAJY/RDGLO1Hrhwg/s72-c/392.jpeg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/07/running-nacl-on-facebook.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cARX49fyp7ImA9WhJRFEs.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-2675446749470995062</id><published>2012-07-02T14:31:00.003-07:00</published><updated>2012-07-16T13:04:04.067-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-16T13:04:04.067-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="3D" /><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="opengles2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="industry" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="G+" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>Chrome Games review at Google I/O</title><content type="html">&lt;span style="background-color: white;"&gt;For those of you who missed it, &lt;/span&gt;&lt;a href="https://developers.google.com/events/io/" style="background-color: white;"&gt;Google I/O&lt;/a&gt;&lt;span style="background-color: white;"&gt; was last week, and boy was it a&amp;nbsp;tornado of awesome. This was the first IO (speaking at, or attending) so it a was a a rush of Google info, products, and announcements that we've been working so many months on. The&amp;nbsp;conference&amp;nbsp;was great, and it was an amazing time to talk with web developers in the wild doing amazing things.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-uICGALfYQDA/T-uIKXa7RBI/AAAAAAAAFnk/9wJmmS2FYkU/s655/27-13_08_20-01-_MG_0008.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="213" src="http://2.bp.blogspot.com/-uICGALfYQDA/T-uIKXa7RBI/AAAAAAAAFnk/9wJmmS2FYkU/s320/27-13_08_20-01-_MG_0008.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-Sy9fTICvjtE/T-zJT7_s0PI/AAAAAAAAJ5A/0tinwx4FLus/s655/IMG_7350.jpg" imageanchor="1" target="_blank"&gt;&lt;img border="0" height="133" src="http://1.bp.blogspot.com/-Sy9fTICvjtE/T-zJT7_s0PI/AAAAAAAAJ5A/0tinwx4FLus/s200/IMG_7350.jpg" width="200" /&gt;&lt;/a&gt;

&lt;a href="http://4.bp.blogspot.com/-HDcyEa95AZg/T-zJVH_ykyI/AAAAAAAAJ60/SLFaApTeLcE/s655/IMG_7364.jpg" imageanchor="1" style="background-color: white;"&gt;&lt;img border="0" height="133" src="http://4.bp.blogspot.com/-HDcyEa95AZg/T-zJVH_ykyI/AAAAAAAAJ60/SLFaApTeLcE/s200/IMG_7364.jpg" width="200" /&gt;&lt;/a&gt;

&lt;a href="http://4.bp.blogspot.com/-zPtkTyS1284/T-4dttPpm2I/AAAAAAAABtQ/9ZjRvp4vy38/s1600/io.jpg" imageanchor="1" style="background-color: white;" target="_blank"&gt;&lt;img border="0" height="133" src="http://4.bp.blogspot.com/-zPtkTyS1284/T-4dttPpm2I/AAAAAAAABtQ/9ZjRvp4vy38/s200/io.jpg" width="200" /&gt;&lt;/a&gt;

&lt;a href="http://2.bp.blogspot.com/-qV9tdjMCZgM/T-1Gn-iyWII/AAAAAAAAKBU/Q_bPtrEM48k/s655/IMG_7391.jpg" imageanchor="1" style="background-color: white;" target="_blank"&gt;&lt;img border="0" height="133" src="http://2.bp.blogspot.com/-qV9tdjMCZgM/T-1Gn-iyWII/AAAAAAAAKBU/Q_bPtrEM48k/s200/IMG_7391.jpg" width="200" /&gt;&lt;/a&gt;

&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;b&gt;New Games announced for HTML5 and Native Client:&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Square Enix announced &lt;a href="http://www.laracroftandtheguardianoflight.com/"&gt;Lara Croft&amp;nbsp;Guardian&amp;nbsp;of Light&lt;/a&gt; for Native Client&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://venturebeat.com/2012/06/28/lara-craft-will-invade-your-chrome-web-browser/"&gt;Venture Beat&lt;/a&gt; was a fan.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;a href="http://www.gaikai.com/"&gt;Gaikai&lt;/a&gt; showed off their Chrome build in the sandbox&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;And also during the &lt;a href="http://youtu.be/tPtJd6AzU8c"&gt;Keynote&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And with some &lt;a href="http://www.theverge.com/2012/6/30/3127602/gaikai-google-nacl-native-client"&gt;other press&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;a href="http://kleientertainment.com/"&gt;Klei Entertainment&lt;/a&gt; opened up &lt;a href="https://chrome.google.com/webstore/detail/hiledapehlkhdehbhppgmekfalnlfajc?utm_source=chrome-ntp-icon"&gt;Don't Starve&lt;/a&gt; for beta testing&lt;/li&gt;
&lt;li&gt;&lt;a href="http://disney.go.com/index"&gt;Disney &lt;/a&gt;was there, showing off their new HTML5 version of&amp;nbsp;&lt;a href="http://disney.go.com/games/#/games/play3/&amp;amp;content=1864911"&gt;AgentP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://halfbrick.com/"&gt;Halfbrick &lt;/a&gt;rocked the house showing off their new HTML5 game &lt;a href="https://chrome.google.com/webstore/detail/pheefoolfafhhpdkpdkjpganobgachop?utm_source=chrome-ntp-icon"&gt;BandStars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.spryfox.com/"&gt;Spryfox &lt;/a&gt;and crew were there with their new RPG game, &lt;a href="https://chrome.google.com/webstore/detail/fnnbpeligohmfjgcpoalibifoabcjaof?utm_source=chrome-ntp-icon"&gt;Sparrow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ea.com/"&gt;EA&lt;/a&gt; showed off a new HTML5 game &lt;a href="http://www.youtube.com/watch?v=5ghM03kErsI"&gt;Strike Fortress&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Which the NY Times thought was &lt;a href="http://bits.blogs.nytimes.com/2012/06/27/e-a-and-google-got-game/"&gt;pretty cool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;b&gt;Talks&lt;/b&gt;&lt;br /&gt;
Native Client Live - &lt;a href="http://www.youtube.com/watch?v=1zvhs5FR0X8"&gt;VIDEO&lt;/a&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="font-size: x-small;"&gt;In this talk, we will be porting an application to Native Client in 60 minutes, LIVE; showing the power of what Native Client can provide for traditional C++ developers looking to move to the web. In the porting process we'll cover specific tasks that a developer would need to perform during a port, and how to to address them with new tools and technologies including debugging integration with Visual Studio and a set of newly added utility libraries to the SDK.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
GRITS: PvP Gaming in HTML5 - &lt;a href="http://www.youtube.com/watch?v=Prkyd5n0P7k"&gt;VIDEO&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;i&gt;This session will present GRITS, a player vs. player shooter game, built entirely using Google technologies. In this talk, we'll walk through building an HTML5 canvas engine, serving the content, networking using Websockets, using NodeJS, social integration and more.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Gaming in the cloud - &lt;a href="http://www.youtube.com/watch?v=5lMcNPDR6uw"&gt;VIDEO&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style="font-size: x-small;"&gt;Many games developers are finding the easy development and deployment experience of Google App Engine ideal for&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;span style="font-size: x-small;"&gt;building cloud based state-storage, matching making services and collaborations services. When you have a hit game, the last thing you want to do is worry about your server provisioning. App Engine has an always-free tier to get you started and then scales seamlessly to any size of usage. Game developers also use Google Cloud Storage to easily store and quickly deliver media files to clients around the world.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: white;"&gt;~Main&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/OwYTWk0gUZ0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/2675446749470995062/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=2675446749470995062" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/2675446749470995062?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/2675446749470995062?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/OwYTWk0gUZ0/chrome-games-review-at-google-io.html" title="Chrome Games review at Google I/O" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-uICGALfYQDA/T-uIKXa7RBI/AAAAAAAAFnk/9wJmmS2FYkU/s72-c/27-13_08_20-01-_MG_0008.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/07/chrome-games-review-at-google-io.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8DQnsyfyp7ImA9WhVUF00.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-6089323464825454381</id><published>2012-05-22T09:24:00.000-07:00</published><updated>2012-05-22T09:24:33.597-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-22T09:24:33.597-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="industry" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="G+" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><title>Write once, run anywhere?</title><content type="html">For game developers these-days, one of the most important things is increasing the top of the user-funnel to reach more potential customers. 'Write once, run anywhere' they say. Is it a pipe-dream? Do developers have to throw-away their code investments for these new platforms?&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-xcLuWLKww5w/T7u6eOnLl7I/AAAAAAAAAJM/Ce1i_EYHqfo/s1600/Mud_Run_II_by_dale427.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-xcLuWLKww5w/T7u6eOnLl7I/AAAAAAAAAJM/Ce1i_EYHqfo/s320/Mud_Run_II_by_dale427.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Truth is, you can run your existing code almost anywhere.... if you're willing to get a little muddy..&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
Language&amp;nbsp;is important for development studios, often there's a great deal of investment in a given development language, starting at the training of the employees to it (ie, you have a team of C++&amp;nbsp;veterans) or an existing&amp;nbsp;code base&amp;nbsp;("&lt;i&gt;We've shipped 8 games in C++, and have shared libraries!&lt;/i&gt;").&lt;br /&gt;
One consistent theme I find when talking to developers is that it's not well understood what options are available to them to get their existing product out in the wild.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So I put together a nice little table that talks about it. Below you will find languages plotted against popular distributions / markets, and if that language runs there.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-YjRVXvl4lTs/T7u372C-PbI/AAAAAAAAAJA/nZ27Oky8vYc/s1600/runit.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="151" src="http://2.bp.blogspot.com/-YjRVXvl4lTs/T7u372C-PbI/AAAAAAAAAJA/nZ27Oky8vYc/s320/runit.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;When you graph your desired language against a given distribution platform, you realize that your options as a game developer are much larger than you would expect them to be.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Some notes:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;HTML5&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;iOS - You can run HTML5 games in &lt;a href="http://phonegap.com/"&gt;PhoneGap&lt;/a&gt;, or Safari&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;Android - You can run HTML5 games in &lt;a href="http://phonegap.com/"&gt;PhoneGap&lt;/a&gt;, or Chrome&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;Steam - You can run HTML5 games with&lt;a href="http://code.google.com/p/chromiumembedded/"&gt; Chromium Embedded&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;C++&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;It's worth noting that C++ for mobile comes with some restrictions (like UI access)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;C++ can run on G+ w/o the need for a plugin (With &lt;a href="http://www.gonacl.com/"&gt;Chrome/NaCl&lt;/a&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;If not using Chrome, can run with a plugin&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;C++ can run on Facebook&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;If you're running chrome, then you need to jump through some inline-install hoops&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;If you're not, then you can run with a plugin&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;You can run C++ in FF/IE, but requires a plugin :(&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;Java&lt;/span&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;Java mostly runs everywhere as a plugin, except iOS :(&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;Steam/Desktop needs java installed,&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;Android has the SDK which is focused on java&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/ol&gt;
&amp;nbsp;The results are quite encouraging; the key take-away here is that multiple&amp;nbsp;languages&amp;nbsp;give you write-once-run-anywhere support, if you don't mind jumping through some hoops. With this type of realization, Game developers should&amp;nbsp;breathe&amp;nbsp;a bit easier:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;i&gt;Your technology isn't going to become out-dated any time soon&lt;/i&gt;.
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
~Main


&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find Colt McAnlis here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/8urGLy257nA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/6089323464825454381/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=6089323464825454381" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/6089323464825454381?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/6089323464825454381?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/8urGLy257nA/write-once-run-anywhere.html" title="Write once, run anywhere?" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-xcLuWLKww5w/T7u6eOnLl7I/AAAAAAAAAJM/Ce1i_EYHqfo/s72-c/Mud_Run_II_by_dale427.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/05/write-once-run-anywhere.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcGSXo4fCp7ImA9WhVUEko.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-7043492095503948289</id><published>2012-05-17T09:17:00.000-07:00</published><updated>2012-05-17T09:27:08.434-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-17T09:27:08.434-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="G+" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>How to auto populate the G+ Sharebox with custom event data</title><content type="html">I've been looking for this functionality in G+ for a long time: How do i generate a unique URL with unique data and allow a user to share that to their stream? Fellow Developer Advocate&amp;nbsp;&lt;a href="http://paul.kinlan.me/"&gt;Paul Kinlan&lt;/a&gt;&amp;nbsp;clued me onto some cool things he was doing with auto-share functionality, so I decided to scrape a demo together. This is pretty small code, So I'm going to let it speak for itself, rather than blabber on about this ;)
&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="205" src="http://4.bp.blogspot.com/-7C6-2PTXPD0/T7UjL0SpA3I/AAAAAAAAAIs/oHHsZL9N7os/s320/sharing-guinea-pigs.jpg" width="320" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Sharing. It's the cornerstone of the social web. Web games can't survive without it.&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Here's the gist:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;On your server (App engine in my case) create a directory path that will render a page when accessed&lt;/li&gt;
&lt;li&gt;The server-rendering of that page will include the proper &lt;a href="http://stackoverflow.com/questions/6536213/are-there-tags-to-specify-the-google-1-story-format-in-google-like-og-meta-for"&gt;G+ story metadata&lt;/a&gt;&amp;nbsp;so that you can control what goes into the stream&lt;/li&gt;
&lt;li&gt;On the client, we use the&amp;nbsp;explicit&amp;nbsp;parse mode for the &lt;a href="https://developers.google.com/+/plugins/share/#target-url"&gt;G+ Share button&lt;/a&gt;&amp;nbsp;to&amp;nbsp;dynamically&amp;nbsp;generate a url to the server location (with params)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;





See it &lt;a href="http://mainroach.appspot.com/share_test/" target="_blank"&gt;live!&lt;/a&gt;&lt;/h3&gt;
&lt;br /&gt;
&lt;h2&gt;






Client Side&lt;/h2&gt;
&lt;br /&gt;
&lt;b&gt;Add this snippet inside of your HEAD tag:&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&amp;lt;script src="https://apis.google.com/js/plusone.js" type="text/javascript"&amp;gt;
   {parsetags: 'explicit'}
&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Add this where you want your share button to be located:&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;&amp;lt;div class="g-plus" data-action="share" data-height="24" id="sharebut"&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;And here's the javascript to generate the 'achievement' url and assign it to the share button&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;
   //generate some random string data
   var url = "http://mainroach.appspot.com/sharetest";
   url += "?type=" + Math.floor(Math.random() * 2.999);
   url += "&amp;amp;userID=ABCDEFGHIJ";
   url += "&amp;amp;custom_data=Now I am going to google-land!";
   
   //add our share button
   var divshare = document.getElementById("sharebut");
   divshare.dataset["href"] = url;

   //this will call the G+ api to raster the share button with the right data  
   gapi.plus.go();

&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;













Server side&lt;/h2&gt;
&lt;div&gt;
Server side, when a request comes in, we use the data to dynamically generate a server page that fills out the &lt;a href="http://stackoverflow.com/questions/6536213/are-there-tags-to-specify-the-google-1-story-format-in-google-like-og-meta-for"&gt;meta data&lt;/a&gt; that G+ will use to scrape for the story. Since the client passed in the type of achievement, as well as some achievement data, the server responds by displaying separate images for each achievement type. &lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;On Google App Engine with Python:&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;class ShareHandler(webapp.RequestHandler):
 def get(self):
  achvtype = self.request.get('type')
  userID = self.request.get('userID')
  eventData = self.request.get('custom_data')
  self.response.headers['Access-Control-Allow-Origin'] = '*'
  self.response.out.write("&amp;lt;html&amp;gt;")
  self.response.out.write("&amp;lt;h1 itemprop='name'&amp;gt;Achievement Unlocked!&amp;lt;/h1&amp;gt;")
  self.response.out.write("&amp;lt;img itemprop='image' src='share_test/shareimg" + achvtype + ".jpg'&amp;gt;&amp;lt;/img&amp;gt;")
  self.response.out.write("&amp;lt;p itemprop='description'&amp;gt;My Level 5 pet rock just unlocked a new mount thanks to &amp;lt;a href='http://mainroach.blogspot.com'&amp;gt;mainroach.blogspot.com&amp;lt;/a&amp;gt;. " + eventData + "&amp;lt;/p&amp;gt;")
  self.response.out.write("&amp;lt;meta http-equiv='refresh' content='0; url=http://mainroach.blogspot.com/'&amp;gt;");
  self.response.out.write("&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;")
&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Note that the final line in this snippet adds a refresh tag to the page. My intent is that the shared URL isn't important enough for the user to visit, and is just a story harness, so when the page loads, I redirect you to my blog.&lt;br /&gt;
&lt;br /&gt;
Once the user shares, it will appear in the G+ stream just like any other proper stream post:&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-ncTQZBl55B0/T7Uj4FO664I/AAAAAAAAAI0/mBwfxLDVuo8/s1600/boom.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="210" src="http://1.bp.blogspot.com/-ncTQZBl55B0/T7Uj4FO664I/AAAAAAAAAI0/mBwfxLDVuo8/s320/boom.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Once we got this working, I was excited!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
And that's it! Go web-game developers. Be awesome and share!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
~Main

&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find me here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" target="_blank" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/Z9t61sqscRQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/7043492095503948289/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=7043492095503948289" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/7043492095503948289?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/7043492095503948289?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/Z9t61sqscRQ/post-game-achievements-to-your-g-stream.html" title="How to auto populate the G+ Sharebox with custom event data" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-7C6-2PTXPD0/T7UjL0SpA3I/AAAAAAAAAIs/oHHsZL9N7os/s72-c/sharing-guinea-pigs.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/05/post-game-achievements-to-your-g-stream.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8AR3czfSp7ImA9WhJaEU8.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-6475143671037042448</id><published>2012-05-07T07:55:00.000-07:00</published><updated>2012-10-01T15:00:46.985-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-01T15:00:46.985-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="3D" /><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="opengles2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="FileIO" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="graphics" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="debugging" /><title>Porting to Native Client with Visual Studio pt.4</title><content type="html">&lt;b style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;This article series shows you how to port to N&lt;/b&gt;&lt;b style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;ative Client via a Chrome Trusted Plugin. This will allow you port your platform code over to Chrome's Pepper APIs while using Visual Studio for debugging.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;div style="background-color: #ee5555;"&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;WARNING:&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
As of 10.1.2012, there's an official version of a &lt;a href="http://mainroach.blogspot.com/2012/10/official-nacl-vs2010-add-in-available.html"&gt;Visual Studio 2010 plugin&lt;/a&gt;. Only some subset of this article series is accurate, please see the official documentation at &lt;a href="http://www.blogger.com/www.gonacl.com"&gt;gonacl.com&lt;/a&gt; for more.&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;b style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;&lt;br /&gt;&lt;/b&gt;
&lt;span style="font-size: large;"&gt;Episode 4:&amp;nbsp;imma chargin mah nacl!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The 4th, and final installment of this series will fill in the last piece of the Native Client developent puzzle : Actually compiling to native client. Until now, we've done lots of work to develop and target Chrome's Pepper APIs by developing as a trusted plugin. This process has allowed us to use Visual Studio's compiler and debugging process to develop on, but alas, this is not the same for Native Client.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-8lD4sWjusxU/T6GoOHqoT6I/AAAAAAAAAIY/raYkrtOdNcA/s1600/hunter_choice.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-8lD4sWjusxU/T6GoOHqoT6I/AAAAAAAAAIY/raYkrtOdNcA/s320/hunter_choice.jpg" width="285" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Some enterprising young soul hacked this bottle of Rum to be awesome. &amp;nbsp;If you've been following this series, you too have hacked awesome to make even more awesome; by running C++ code on the web.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
NaCl provides a&amp;nbsp;separate&amp;nbsp;command-line GCC compiler that produces safe executable files to be used for the Native Client Plugin. So, in order to continue to develop inside of visual studio, we're going to have to make some modifications so that we can send our build arguments to NaCl's GCC&amp;nbsp;compiler, rather than VS's.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: white; font-size: large;"&gt;Unofficial Hack-tastic Visual Studio Plugin&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;As expected, there's already some work in this area; Where&lt;a href="https://github.com/kayru/vs-nacl"&gt; this guy&lt;/a&gt; modified a version of an Android Visual studio plugin to support Native Client. That version hasn't been updated in a while, and as Developer Advocate for NaCl, I feel it's my responsibility to copy that version, make some changes, and keep it up-to-date ;)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;So, as a first step, close your visual studio, and grab the native client vs2010 plugin from my &lt;a href="https://github.com/mainroach/nacl-examples"&gt;github repo&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;Download it to a safe, secure location, and then:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Copy the 'addin-vs2010/NaCl' folder &lt;u&gt;and &lt;/u&gt;the&amp;nbsp;&lt;/b&gt;&lt;b&gt;'addin-vs2010/PPAPI' folder&lt;/b&gt;&lt;b&gt;&amp;nbsp;to your ms build folder:&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms
//so you now have
&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\NaCl
&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\PPAPI&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Now, load up Visual Studio, and let's get started!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: white; font-size: large;"&gt;Using the plugin&lt;/span&gt;&lt;br /&gt;
What the plugin does, is allow for you to define a seperate platform to build against; As such, you'll need to create a new platform in the build-&amp;gt;configuration manager&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-bAm6iuhUcLE/T6GPPYv88-I/AAAAAAAAAIE/WQhNilF_JvY/s1600/newconfig.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="195" src="http://2.bp.blogspot.com/-bAm6iuhUcLE/T6GPPYv88-I/AAAAAAAAAIE/WQhNilF_JvY/s320/newconfig.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;You can add a new "NaCl" platform that your project can target.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
Depending on your project layout, how you configure your project, solution, and platform build layouts is up to you. I suggest taking a bit of time to do that now. In reality, we should be providing both a PPAPI and NACL platform targets, (so that you can choose debug/release for your build config, and win32/ppapi/nacl for your platform) but that is a bit besides the point ;)&lt;br /&gt;
&lt;br /&gt;
Once you've got everything set-up, it's time to set some of the properties on the project. Opening the properties tab, you'll notice a few things are different from a standard windows build.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-uQgf-4A5MJg/T6GPamABYNI/AAAAAAAAAIM/M0dT0wFReSs/s1600/base_settings.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="121" src="http://4.bp.blogspot.com/-uQgf-4A5MJg/T6GPamABYNI/AAAAAAAAAIM/M0dT0wFReSs/s320/base_settings.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Set the nacl compiler to these settings. Most of them should be set up for you by the plugin, but just to be sure, I list the important ones here :&lt;br /&gt;
&lt;ul&gt;
&lt;li style="font-weight: bold;"&gt;&lt;b&gt;General&amp;gt; Configuration Type:&lt;/b&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;&lt;span style="background-color: white;"&gt;&lt;i&gt;Application(.nexe)&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;General&amp;gt; Target Architecture:&lt;/b&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;&lt;i&gt;x86 64-bit&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;General&amp;gt; Target Platform&lt;/b&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;&lt;i&gt;pepper_18&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Note, as more pepper versions are released, you'll need to manually change this string&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;Debugging &amp;gt; Command Arguments:&lt;/b&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;&lt;i&gt;--incognito "localhost:5103"&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;Reminder&amp;nbsp;&lt;i&gt;-incognito&lt;/i&gt;&amp;nbsp;turns off caching so we're sure to get the latest changes each time we launch the debugging process.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;C/C++ &amp;gt;&amp;nbsp;
&lt;b&gt;Preprocessor&amp;nbsp;&lt;/b&gt;&amp;nbsp;&amp;gt;Preprocessor Definitions :&lt;/b&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;&lt;i&gt;PPAPI;NACL;.....&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;Linker &amp;gt; General &amp;gt;Output File :&lt;/b&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;&lt;i&gt;$(ProjectDir)$(TargetName)_x86_64$(TargetExt)&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Eventually you'll need 32 bit and 64 bit build targets, but I'll leave you to handle that ;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;Linker &amp;gt; General &amp;gt;Output File :&lt;/b&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="background-color: white; font-size: 12px;"&gt;&lt;i&gt;$(ToolchainDir)\x86_64-nacl\lib&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;Linker &amp;gt; Input &amp;gt;Native Client System Libraries :&lt;/b&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;&lt;i&gt;ppapi_gles2;ppapi_cpp;ppapi&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;span style="background-color: white; font-size: large;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style="background-color: white; font-size: large;"&gt;&lt;span style="background-color: white; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style="background-color: white; font-size: large;"&gt;
Removing platform-specific code&lt;/span&gt;&lt;br /&gt;
If recalled, the PPAPI define allows you to run both pepper and windows calls. Especially when getting errors, (like loading shaders and what not.) We'd like to keep this functionality so we can swap between the builds for easier debugging, so we add a new preprocessor define NACL, which should encompass any differences between PPAPI and Native Client.&lt;br /&gt;
&lt;br /&gt;
The bulk of this work was directly changing the &lt;i&gt;MessageBox&lt;/i&gt;&amp;nbsp;usage in the program, and forcing it instead to target our &lt;i&gt;PostMessage &lt;/i&gt;function.&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;#ifdef NACL  
     PP_Var v = CStrToVar(&amp;amp;str[0]);
     ppb_messaging_interface-&amp;gt;PostMessage(appInstance_,v);
#else
     MessageBox( NULL, &amp;nbsp;&amp;amp;str[0],"GLERR",MB_OK | MB_ICONEXCLAMATION );
#endif&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br class="Apple-interchange-newline" /&gt;&lt;/div&gt;
&lt;div&gt;
One specific instance of where the NaCl instance derived from the PPAPI instance is wrt a location of the gl2ext_ppapi.h header:&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;#ifdef PPAPI
. . .
#ifdef NACL
     #include "ppapi/gles2/gl2ext_ppapi.h"
#else
     #include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
#endif //NACL
. . .
#endif //PPAPI&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style="background-color: white; font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="background-color: white; font-size: large;"&gt;Creating the .nmf file&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Native client requires you to define a manifest file (served alongside the html file) which points to what executable to use / load for each processor type. There's some nice tools in the SDK that will auto-generate these, but for&amp;nbsp;clarity&amp;nbsp;sake, here is the one provided for this application. Note that the VS Plugin will NOT generate these for you!&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;{
  "program": {
    "x86-64": {"url": "plugin-port3_x86_64.nexe"},
    "x86-32": {"url": "plugin-port3_i386.nexe"}
  }
}&lt;/span&gt;&lt;span style="font-size: 12px;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style="background-color: transparent;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style="font-size: x-large;"&gt;
&lt;span style="background-color: white;"&gt;Debugging&lt;/span&gt;&lt;/div&gt;
It's worth noting that once you're running your NaCl application from visual studio, you &lt;u&gt;loose Visual studio Debugging abilities.&lt;/u&gt;&amp;nbsp;You can fix this by following the &lt;a href="https://developers.google.com/native-client/beta-docs/debugging"&gt;debugging steps to get WinGDB working&lt;/a&gt;; but hopefully you can debug everything as a trusted plugin, and don't have to worry about it. There is a Debugger for NaCl, but the integration process with visual studio still needs quite a bit of work. As such, I suggest you avoid it at most costs ;)&lt;br /&gt;
&lt;div style="font-size: x-large;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style="background-color: white; font-size: large;"&gt;Notes about provided code&lt;/span&gt;&lt;/div&gt;
Please note that the Visual Studio plugin I provide is without&amp;nbsp;warranty. It is not an official&amp;nbsp;Google&amp;nbsp;product and holds no expectations of being such. Please hack on it at your will, and if you have problems with it, toss them back at me. Also note that I've added a PPAPI platform as well, this should make it easier for your configurations, where you can keep your debug/release/testing builds against and target PPAPI and NACL as&amp;nbsp;separate&amp;nbsp;platforms.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note-&lt;/b&gt;&amp;nbsp;you can download the source code for this series @ my&amp;nbsp;&lt;a href="https://github.com/mainroach/nacl-examples"&gt;github repo.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The rest of the series -&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual.html"&gt;Part 1 : Setting up visual studio&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual_30.html"&gt;Part 2 : Using platform-specific code&amp;nbsp;&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual.html"&gt;Part 3 : Porting to Pepper&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual_07.html"&gt;Part 4 : Compile to NaCl&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: white; font-size: large;"&gt;Article Conclusions:&lt;/span&gt;&lt;br /&gt;
This article series has been a great chance to go through the trenches of NaCl development from the standpoint and POV of a random windows developer. Hopefully, this series has made it easier for windows developers to understand Native Client and successfully port over their projects. There's been lots of feedback in this process to the NaCl SDK team, and there's already planned changes on the&amp;nbsp;horizon&amp;nbsp;that will make some points of my articles obsolete. (for example, including the PPAPIs inside of the NaCl SDK, so you don't have to grab chromium!) When those changes land, I'll be sure to update this article series with the relevant warnings.&lt;br /&gt;
Thanks for reading. Feel free to send me feedback on my &lt;a href="https://plus.google.com/u/0/105062545746290691206/posts"&gt;G+ page&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find me here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;i style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;~Main&lt;/i&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/vn--7vgORro" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/6475143671037042448/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=6475143671037042448" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/6475143671037042448?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/6475143671037042448?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/vn--7vgORro/porting-to-native-client-with-visual_07.html" title="Porting to Native Client with Visual Studio pt.4" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-8lD4sWjusxU/T6GoOHqoT6I/AAAAAAAAAIY/raYkrtOdNcA/s72-c/hunter_choice.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual_07.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8HRHo4fCp7ImA9WhJaEU8.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-381855797801852461</id><published>2012-05-03T07:26:00.001-07:00</published><updated>2012-10-01T15:00:35.434-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-01T15:00:35.434-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="3D" /><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="opengles2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="FileIO" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="graphics" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="debugging" /><title>Porting to Native Client with Visual Studio pt.3</title><content type="html">&lt;b&gt;&lt;br class="Apple-interchange-newline" /&gt;This article series shows you how to port to N&lt;/b&gt;&lt;b&gt;ative Client via a Chrome Trusted Plugin. This will allow you port your platform code over to Chrome's Pepper APIs while using Visual Studio for debugging.&amp;nbsp;&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #ee5555;"&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;WARNING:&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
As of 10.1.2012, there's an official version of a &lt;a href="http://mainroach.blogspot.com/2012/10/official-nacl-vs2010-add-in-available.html"&gt;Visual Studio 2010 plugin&lt;/a&gt;. Only some subset of this article series is accurate, please see the official documentation at &lt;a href="http://www.blogger.com/www.gonacl.com"&gt;gonacl.com&lt;/a&gt; for more.&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;&lt;br /&gt;&lt;/b&gt;
&lt;span style="font-size: large;"&gt;Episode 3: Tigers Love Pepper&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
In the 3rd installment we're going to take the dive and port from a hybrid application &amp;nbsp;to getting OpenGL rendering inside of the webpage! As we mentioned in the first article, Pepper is an API that allows plugins to communicate with resources in Chrome, so for us to get our OpenGL win32 app rendering in the Chrome webpage, we need to port all of our Platform code, and rendering code to Pepper.&lt;br /&gt;
&lt;insert here="" picture="" specific=""&gt;&lt;/insert&gt;&lt;br /&gt;
&lt;br /&gt;
The article this time is pretty code specific that's a combination of GL and FileIO, so I'm going to only highlight the important points, and assume that you're a sane programmer, who is reading code alongside my rambling ;)&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="272" src="http://4.bp.blogspot.com/-z0PtGALu5dE/T58UECUxwwI/AAAAAAAAAHk/-den2Fb8UoE/s400/white+tiger+swimming.jpg" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="http://www.imdb.com/title/tt1119646/quotes"&gt;Tigers love Pepper&lt;/a&gt;. This is well known. The Tiger above thought there was pepper under water, and decided to swim to get it. This article seeks to make your code more &lt;i&gt;tiger friendly&amp;nbsp;&lt;/i&gt;by merging it with the Pepper APIs. This will make your code less lion friendly though, as they prefer to snack on &lt;a href="http://www.youtube.com/watch?v=jT7_CtjEVFU"&gt;small zoo-going children&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-size: large;"&gt;We are going to avoid compiling Chromium&lt;/span&gt;&lt;br /&gt;
I realized I hadn't been verbose about this just yet, but my intent in this series is to &lt;i&gt;avoid compiling chromium at all costs&lt;/i&gt;. Chrome is a massive&amp;nbsp;code base&amp;nbsp;with lots of&amp;nbsp;tendrils, and taking time to compile them in order to develop your plugin is great deal of overhead that isn't worth dealing with.&lt;br /&gt;
&lt;br /&gt;
One of the things we're doing to help with this is by using &lt;i&gt;the C version of the Pepper headers&lt;/i&gt;. These headers won't require you to compile against a static lib in order to compile your application (for the most part) which keeps you from compiling Chrome, and helps improve iteration time.&lt;br /&gt;
&lt;br /&gt;
That being said, there's some&amp;nbsp;nuances&amp;nbsp;with the process that we're going to highlight in this article that will require your code to behave a &lt;i&gt;specific way&lt;/i&gt;&amp;nbsp;that is unique to the PPAPI plugin process, that DOES NOT match a shipping NaCl product. Specifically how OpenGLES2 behaves &lt;i&gt;differently&lt;/i&gt;&amp;nbsp;as a Trusted Plugin than it does as a NaCl app.&amp;nbsp;So make sure you weigh the code changes you'll have to make against compiling Chrome.&amp;nbsp;Note that if you&amp;nbsp;&lt;i&gt;choose&lt;/i&gt;&amp;nbsp;to compile Chrome, I offer no&amp;nbsp;warranties&amp;nbsp;on that process ;)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Laying the groundwork&lt;/span&gt;&lt;br /&gt;
Firstly, the code wraps some PPAPI specific merges in a&amp;nbsp;&lt;i&gt;#define PPAPI&lt;/i&gt;&amp;nbsp;at the top of the file. Most of the windows-specific items, like creating the win32 window, is compiled out while this flag is defined to reduce&amp;nbsp;craziness; My intent is to keep the windows functionality for this program so that we can create&amp;nbsp;separate&amp;nbsp;targets correctly.&lt;br /&gt;
&lt;br /&gt;
It's also worth noting that we are intentionally allowing this project to be&amp;nbsp;&lt;i&gt;single threaded&lt;/i&gt;. As I noted in my &lt;a href="http://www.youtube.com/watch?v=R281PhQufHo"&gt;GDC talk&lt;/a&gt;, it's much easier to spin up a&amp;nbsp;separate&amp;nbsp;thread and communicate back to the Pepper thread, but the extra code for multithreaded communication I felt was a bit outside the scope of this article.&lt;br /&gt;
&lt;br /&gt;
There are a few things that I will cover however, which are specific to the Pepper API&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Pepper can only be called from the main thread (I call this the 'Pepper thread')&lt;/li&gt;
&lt;li&gt;Pepper APIs are required to be non-blocking&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Note there are some NaCl calls (like dlopen) that are blocking so you have to manage them with care&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;There is no 'main loop' in Pepper. Pepper module functions are triggered from javascript pulses.&lt;/li&gt;
&lt;ul&gt;&lt;br /&gt;&lt;/ul&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Loading Files with Pepper&lt;/span&gt;&lt;br /&gt;
First, we're going to replace the file-loading code. Up till now, we were defining explicit locations of files, and taking advantage of the --no-sandbox flag. Since this isn't going to be available in a shipping product, we need to migrate our fileIO calls to PPAPI. Note, that I've talked about how &lt;a href="http://mainroach.blogspot.com/2012/01/nacl-best-practices-for-fileio.html"&gt;the file-system(s) in Native Client work&lt;/a&gt;&amp;nbsp;I've also talked about how the Pepper APIs need to come from the main&amp;nbsp;thread, &lt;a href="http://www.youtube.com/watch?v=R281PhQufHo"&gt;and why fileIO is so difficult in this process&lt;/a&gt;. So make sure you check up with those before moving forward.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;NOTE &lt;/b&gt;&lt;i&gt;:Although the example code includes a solution on how to load files from disk, it by no-means should be considered best practices. In short, I'm going to discuss some of the changes I made, but skip over the larger discussion of how the APIs work.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
As discussed in &lt;a href="http://mainroach.blogspot.com/2012/01/nacl-best-practices-for-fileio.html"&gt;my article&lt;/a&gt; on NaCl and File systems, file data is firstly hosted from a server, and as such, we need to kick of an HTTP Get request to fetch the&amp;nbsp;byte stream&amp;nbsp;so that's&amp;nbsp;usable&amp;nbsp;for us in the code. For the specifics of this, I refer you to documentation on &lt;a href="http://ppb_url_loader.h/"&gt;ppb_url_loader.h&lt;/a&gt;, which describes how to properly use the interfaces provided by Pepper. I will note, however, that using the API's is a 4 step dance:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;You must 'open' the file, passing some sort of struct to hold request data.&lt;/li&gt;
&lt;li&gt;Once the file is 'opened' you get a callback, and must then issue a 'read' command to it&lt;/li&gt;
&lt;li&gt;Once you've read some data, you get another callback&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;You must check if the data has been read entirely.&lt;/li&gt;
&lt;li&gt;If not, then you need to re-issue the 'read' command again.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;When you're done, clear the buffers and close the file&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Preloading our assets&lt;/span&gt;&lt;br /&gt;
The fact that the file APIs &lt;i&gt;must&lt;/i&gt;&amp;nbsp;come from the main thread, and that they are &lt;i&gt;nonblocking&lt;/i&gt;&amp;nbsp;presents a problem for us, as our existing code expects &lt;i&gt;fread&lt;/i&gt;&amp;nbsp;to block. There's many solutions to this problem; the one I will present, for simplicity's sake, is to preload the files before creating any objects needing the file data.&lt;br /&gt;
&lt;br /&gt;
To do this, I first create a new callback loop function, called &lt;i&gt;loadloop&lt;/i&gt;. This function will poll if the files have been loaded by checking a file-loaded counter, and re-issuing a callback if we're still waiting for files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;void loadLoop(void* pData, int32_t dataSize)
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;{
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;   //if the resources aren't loaded yet, then kick off another callback
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    if(g_ResourceLoadedCounter != 3)
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    {
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;       PP_CompletionCallback cc = PP_MakeCompletionCallback(loadLoop, 0);
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;       ppb_g3d_interface-&amp;gt;SwapBuffers(graphicsContext_, cc);
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;       return;
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    }
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt; ...
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br class="Apple-interchange-newline" /&gt;&lt;/div&gt;
&lt;br /&gt;
Because file IO needs a callback system, I provide a very hack-tastic solution that each of the files has a&amp;nbsp;separate&amp;nbsp;callback function to load it, which will copy the response data from the server into some global objects, and increase the file-load counter.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;pre class="prettyprint" style="max-width: 70em; overflow: auto; padding: 0.5em;"&gt;//glboally define the data; a file manager is outside the scope of this..
&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;char* textureData;
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;unsigned char* pVSData;
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;unsigned char* pPSData;
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;
//this function loads the vertex shader data
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;void load_vsCB(void* pData, int32_t dataSize)
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;{
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;   &lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;if(dataSize &amp;lt;=0)
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    return;
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;
    //note that the shader compiler expects this to be a null-terminated string
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;   pVSData = new unsigned char[dataSize+1];
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;   memcpy(pVSData,pData,dataSize);
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;   pVSData[dataSize]=0; //null terminate this string
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;   g_ResourceLoadedCounter++;
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br class="Apple-interchange-newline" /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Once all the data is loaded, &lt;i&gt;g_ResourceLoadedCounter &lt;/i&gt;will be set to the number of loaded files, and thus &lt;i&gt;loadLoop&lt;/i&gt; will call&lt;i&gt; init()&lt;/i&gt;, creating the GL context, shaders, and textures, and then kicking off our first render function loop&lt;/div&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;
void loadLoop(void* pData, int32_t dataSize)
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;{
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    //if the resources aren't loaded yet, then kick off another callback
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    if(g_ResourceLoadedCounter != 3)
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    {
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;      ...
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    }
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;
    //if everything's loaded, then init
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    init();

&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    //kick off rendering loop here
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    //now that everything's loaded, kick off our first render frame
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    PP_CompletionCallback cc = PP_MakeCompletionCallback(render, 0);
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;    ppb_g3d_interface-&amp;gt;SwapBuffers(graphicsContext_, cc);
&lt;/span&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Again, note that there are many solutions to this problem. Where the more advanced ones require you to modify your code less. For example, spinning up your loop to a worker thread, and then emulating fread by blocking your calling thread until all the execution on the Pepper thread finishes; this could be hidden by a nice modular interface, and not require any of the ugly hacks I've&amp;nbsp;presented&amp;nbsp;here.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Converting the Rendering API&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Sadly, we can't 'slowly' convert from GL to GLES2, we kinda have to jump all-in;&amp;nbsp;I am going to avoid as much of the conversation of GL-&amp;gt;GLES2 as I can as this has little to do with&amp;nbsp;nuances&amp;nbsp;of Pepper directly, and more to do with graphics API&amp;nbsp;weirdness. &amp;nbsp;As such, I'm going to focus directly on the parts that are relevant to PPAPI.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Adding the right files&lt;/span&gt;&lt;br /&gt;
Although we're using the C version of the Pepper APIs, some of the GLES2 APIs that are Pepper Specific still fall through the cracks. The bad news is we need to modify our paths and add some files, the good news is that we don't have to include all of chrome ;)&lt;br /&gt;
&lt;br /&gt;
Add these two files to your project:&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;(Some Path)\chromium\src\ppapi\lib\gl\gles2\gles2.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;(Some Path)\chromium\src\ppapi\lib\gl\gles2\gl2ext_ppapi.c&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In addition, you'll need to add a new include path for the pepper GL headers, make sure you add the following path to your include directories&lt;/div&gt;
&lt;div&gt;
&lt;b style="background-color: #fafafa; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;b style="text-align: -webkit-auto;"&gt;C/C++ &amp;gt; General &amp;gt;Additional Include Directories :&lt;/b&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;(Some Path)\chromium\src\ppapi\lib\gl\include&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Note, you DO NOT need to link to the GL libraries (opengl32.lib,glu32.lib) any longer. Please remove thier linkage from this configuration&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Creating a rendering callback loop&lt;/span&gt;&lt;br /&gt;
As mentioned, there is no 'main' loop with PPAPI. It's a callback driven process that is initiated from the external code into your Pepper Plugin.&amp;nbsp;Luckily, the GL APIs come with a callback function that allows you to chain these render commands together using callbacks.&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;//was void render() 
void render(void* pData, int32_t dataSize) 
{
    ...
&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;   //here be code that renders Dragons.
&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;   ...
&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;
  //call a swap-buffer, and when it's done, call render again
&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;  &lt;/span&gt;&lt;b style="background-color: transparent;"&gt;PP_CompletionCallback cc = PP_MakeCompletionCallback(render, 0);
&lt;/b&gt;&lt;b style="background-color: transparent;"&gt;  ppb_g3d_interface-&amp;gt;SwapBuffers(graphicsContext_, cc);
&lt;/b&gt;&lt;span style="background-color: transparent;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
What the above code will do, is that the render loop, when finished, will kick off a SwapBuffers command to openGL, and when it's done, submit a callback &lt;i&gt;back&lt;/i&gt;&amp;nbsp;to the render function, which will&amp;nbsp;subsequently&amp;nbsp;render, and callback again. This is as close to a &lt;i&gt;while&lt;/i&gt;&amp;nbsp;loop that we get when using PPAPI in a single threaded mode. Note that &lt;i&gt;loadLoop&lt;/i&gt;&amp;nbsp;kicks off the very first call to &lt;i&gt;render()&lt;/i&gt;&amp;nbsp;once all the&amp;nbsp;initialization&amp;nbsp;is completed.&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Warning: No Client Array Support - trusted plugins only&lt;/span&gt;&lt;br /&gt;
There's some crazy nuances with Trusted Plugin development using Chrome.&lt;br /&gt;
Looking at the source code, there's a defined flag in &lt;a href="http://gles2_implementation.cc/"&gt;gles2_implementation.cc&lt;/a&gt; called GLES2_SUPPORT_CLIENT_SIDE_ARRAYS which defines a certain behavior for plugins. Mainly when defined, it allows OpenGL ES2.0 to use client-side arrays; the type of arrays that allow you to call&amp;nbsp;&lt;i&gt;glVertexAttribPointer &lt;/i&gt;without having a Vertex Buffer Object bound first.&lt;br /&gt;
&lt;br /&gt;
Normally, most high-performance applications use VBOs for the bulk of their rendering anyway, having dynamic rendering only used for debugging, or some UI specific code.&lt;br /&gt;
&lt;br /&gt;
One way around this, which adds this functionality back into your plugin, involves compiling the portions of chrome effected by GLES2_SUPPORT_CLIENT_SIDE_ARRAYS &lt;i&gt;into&lt;/i&gt;&amp;nbsp;the plugin itself, so that it's allowed to define how the communication pattern works to the GPU command buffer. So this is a bit worse than compiling chrome, it requires you to compile a &lt;i&gt;subset&lt;/i&gt;&amp;nbsp;of chrome, and use that in your plugin. Which, hopefully, doesn't pull in all of chrome along with it.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="color: red;"&gt;This behavior is not the same for Native Client&lt;/span&gt;&lt;/div&gt;
The NaCl plugin properly compiles in the needed assemblies with the above flag, and thus allows client-side arrays to be used for Native Client development.&amp;nbsp;&amp;nbsp;Again, you should carefully weigh the pros/cons of your development&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Warning: Chrome has it's own GL errors :(&lt;/span&gt;&lt;br /&gt;
Chrome, in an attempt to increase security, has a federation of checks and testing that occur on your GL calls before they make their way to the GL APIs, and report errors back to the&amp;nbsp;java script&amp;nbsp;console. These custom errors will throw a valid GL error, alongside some Chrome-specific debugging information. Note that if you Google for the exact phrase output in the error window, the only hits you'll get will link you directly to the chrome source code :(&lt;/div&gt;
&lt;div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-0kmgBkpkzqw/T5_oX-3NNOI/AAAAAAAAAHw/VSG8zNaV10E/s1600/errors.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="122" src="http://2.bp.blogspot.com/-0kmgBkpkzqw/T5_oX-3NNOI/AAAAAAAAAHw/VSG8zNaV10E/s320/errors.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Some common errors you get in the application if you don't call glBindBuffer before doing a draw call&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;span style="font-size: large; text-align: -webkit-auto;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;span style="font-size: large; text-align: -webkit-auto;"&gt;Booyah&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: -webkit-auto;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-rYNhPO837rU/T5_oqrNIZDI/AAAAAAAAAH4/rAlvR-UiCx8/s1600/success.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" height="315" src="http://2.bp.blogspot.com/-rYNhPO837rU/T5_oqrNIZDI/AAAAAAAAAH4/rAlvR-UiCx8/s320/success.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;After porting your fileIO and Rendering code to Pepper, you should be able to see the quad rendering on the page.&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;
This was one hell of an amount of heavy code to lift. Porting to Pepper accounts for a large amount of your time and energy, and shouldn't be taken lightly. In reality, you should approach Pepper APIs with the proper set of abstraction layers and code buffers to reduce the amount of in-line code that you have to change in your codebase.&lt;br /&gt;
&lt;br /&gt;
It's worth noting that this article series has done quite a bit to illuminate the plight of the average NaCl developer to the teams here @ Google. As automated fixes come into the SDK for these things, I'll update this documentation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: white; margin: 0px; outline: none; padding: 0px; text-align: justify;"&gt;
&lt;div style="text-align: -webkit-auto;"&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Notes about the provided code&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;span style="font-family: inherit;"&gt;I've added two build configurations to the project to help toggle-swap your port efforts&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;debug-ppapi&lt;/li&gt;
&lt;li&gt;debug-win32&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Swapping your config between the two will either launch a win32 window, or a Chrome using PPAPI&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Note&lt;/b&gt;- Sane,&amp;nbsp;deity&amp;nbsp;fearing developers would never port in the manner that I have in the provided code. They would write proper wrappers, abstraction interfaces etc. My goal is to provide as few source code files as possible to show off the intended techniques for porting to NaCl. My goal is not to show off good programming techniques, ethics, or best practices. YMMV ;)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note&lt;/b&gt;- DISABLE YOUR CACHE. While you're developing, Chrome will pull in the cached shader and texture data, and sometimes even nexe files. As such, you should disable your cache while developing, or run in incognito mode (you can specify this with a command line string --incognito)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note-&amp;nbsp;&lt;/b&gt;that the debug-ppapi build config does not handle input to rotate the quad; I leave all 'input handling' in this article as an exercise for the reader ;)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;b&gt;Note-&lt;/b&gt;&amp;nbsp;you can download the source code for this series @ my&amp;nbsp;&lt;a href="https://github.com/mainroach/nacl-examples"&gt;github repo.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The rest of the series -&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual.html"&gt;Part 1 : Setting up visual studio&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual_30.html"&gt;Part 2 : Using platform-specific code&amp;nbsp;&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual.html"&gt;Part 3 : Porting to Pepper&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual_07.html"&gt;Part 4 : Compile to NaCl&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find me here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;i style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;~Main&lt;/i&gt;&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/WyT5qciejqU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/381855797801852461/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=381855797801852461" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/381855797801852461?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/381855797801852461?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/WyT5qciejqU/porting-to-native-client-with-visual.html" title="Porting to Native Client with Visual Studio pt.3" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-z0PtGALu5dE/T58UECUxwwI/AAAAAAAAAHk/-den2Fb8UoE/s72-c/white+tiger+swimming.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8GQHk9eSp7ImA9WhJaEU8.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-4546158369853198306</id><published>2012-04-30T07:02:00.000-07:00</published><updated>2012-10-01T15:00:21.761-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-01T15:00:21.761-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FileIO" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="debugging" /><title>Porting to Native Client with Visual Studio pt.2</title><content type="html">&lt;b style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;This article series shows you how to port to N&lt;/b&gt;&lt;b style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;ative Client via a Chrome Trusted Plugin. This will allow you port your platform code over to Chrome's Pepper APIs while using Visual Studio for debugging.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #ee5555;"&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;WARNING:&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
As of 10.1.2012, there's an official version of a &lt;a href="http://mainroach.blogspot.com/2012/10/official-nacl-vs2010-add-in-available.html"&gt;Visual Studio 2010 plugin&lt;/a&gt;. Only some subset of this article series is accurate, please see the official documentation at &lt;a href="http://www.blogger.com/www.gonacl.com"&gt;gonacl.com&lt;/a&gt; for more.&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;b style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;&lt;br /&gt;&lt;/b&gt;
&lt;span style="font-size: large;"&gt;Episode 2: The platform-specific hope&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
In the 2nd installment of my &lt;a href="http://www.colbertnation.com/the-colbert-report-videos/411771/april-04-2012/peabody-award-for-colbert-super-pac"&gt;soon-to-be-peabody-nominated-series&lt;/a&gt; I'll walk you through how to call platform-specific code from our trusted plugin, and get it running alongside our pepper api; This will be a setup for article 3, which will talk about how to port us from the platform specific API code to Pepper. Less pictures this time, more code ;)&lt;br /&gt;
&lt;insert here="" picture="" specific=""&gt;&lt;/insert&gt;&lt;br /&gt;
&lt;br /&gt;
I'm assuming that you've already grabbed the first article's code from github, and that you've properly read through the first article such that I don't need to repeat any of that.&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="221" src="http://1.bp.blogspot.com/-3R3De08gL-o/T5molqvjccI/AAAAAAAAAHM/QjaOk78sKGs/s320/waflbug.jpg" width="320" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The Waffle Burger. The Unholy&amp;nbsp;alliance&amp;nbsp;of breakfast and dinner that&amp;nbsp;fueled&amp;nbsp;the 200 year war. &lt;br /&gt;
It is from this brave delicacy&amp;nbsp;that we draw our&amp;nbsp;inspiration&amp;nbsp;in this article.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-size: large;"&gt;Getting some Platform-Specific code&lt;/span&gt;&lt;br /&gt;
Most of my work with Native Client developers includes game devs specifically, and their biggest pain points revolve around file IO and rendering; as such, it makes sense that we should target something difficult, yet easy to deal with.&lt;br /&gt;
&lt;br /&gt;
As such, go grab a&lt;a href="http://www.codesampler.com/source/ogl_glslang_simple_vs2ps.zip"&gt; nice openGL sample&lt;/a&gt;&amp;nbsp;which covers both OpenGL, and file IO&amp;nbsp;from &lt;a href="http://codesampler.com/"&gt;Codesampler.com&lt;/a&gt;, download it and unpack it somewhere.&lt;br /&gt;
&lt;br /&gt;
Once done, copy the entire contents of&amp;nbsp;&lt;i&gt;ogl_glslang_simple_vs2ps.cpp&lt;/i&gt; from the sample and paste it at the TOP of our existing plugin-port0\main.cpp file;&lt;br /&gt;
&lt;br /&gt;
In addition to the file contents, you'll also need to copy over the following additional files:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;glext.h - This is a file containing headers needed for this OpenGL example&lt;/li&gt;
&lt;li&gt;vertex_shader.vert&lt;/li&gt;
&lt;li&gt;fragment_shader.frag&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Place these files alongside your plugin-port0\index.html file&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Getting it compiling&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Assuming you've pasted the code starting at line 0, you can easily make the following changes:&lt;/div&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;line 29: //#include "gluax.h"
line 30: //#include "resource.h"&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Note &lt;/b&gt;you should set your characters from &lt;i&gt;unicode &lt;/i&gt;to &lt;i&gt;multibyte &lt;/i&gt;in the project settings, otherwise the first time you compile you'll get erros relating to LPCWSTR; Be aware that this isn't NaCl specific, it's just how this particular plugin is being handled.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Adding the GL libraries&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
OpenGL requires us to link to specific precompiled&amp;nbsp;libraries to render properly; Let's link to them, and celebrate our ability to use Visual Studio in the same breath by using some nice VS magic that keeps us from having to modify the properties pages. Add these lines after the includes of your file.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;#pragma comment(lib,"opengl32.lib")
&lt;/span&gt;&lt;span style="background-color: transparent; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;#pragma comment(lib,"glu32.lib")&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
It compiles! Let's get it doing something!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Updating the main function&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
What we're going to do here, is modify the source code we have to pop up the existing code window that we would expect to see and run it side-by-side with our Chrome window. As such, we need to change the function header for the window creation online&amp;nbsp;line 112:&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;
init WINAPI WinMain(HINSTANCE hInstance,HISNTANCE hPrevInstance, LPSTR lpCmdLine, int nCMDShow)&lt;/span&gt;&lt;/pre&gt;
&lt;br class="Apple-interchange-newline" /&gt;&lt;/div&gt;
&lt;div&gt;
with:&lt;/div&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;int initInstance()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;i&gt;"Simplicity&amp;nbsp;is a dish best served with nothing on it"&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Calling the main function&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Now that we've modified the main function, we need to call it from somewhere. Place a call to the window creation inside of &lt;i&gt;Instance_DidCreate&lt;/i&gt; in order to launch the window&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;static PP_Bool Instance_DidCreate(...){&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;   PP_Var v = CStrToVar("Hello a World (NEWLIB)");
   ppb_messaging_interface-&amp;gt;;PostMessage(instance,v);

   &lt;b&gt;initInstance();&lt;/b&gt;
   ..
}&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Reading files from disk&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This project reads in 3 files from disk, a texture and two shaders. There's a proper way to do this, via Pepper, but we're not to the point of caring about pepper just yet. Instead we're going to cheat here, and use a bit of &lt;i&gt;dark voodoo magic&lt;/i&gt;. Although we're serving our html content from a webserver, we can define this nice flag &lt;i&gt;--no-sandbox&lt;/i&gt; as a command line argument that will allow us to read files directly from the local disk, bypassing the sandbox security restrictions.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;b&gt;So in your project's settings set&lt;br class="Apple-interchange-newline" /&gt;Debugging &amp;gt; Command Arguments:&lt;/b&gt;&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;b&gt;--no-sandbox&lt;/b&gt; --single-process --register-pepper-plugins=$(TargetPath);application/x-nacl "localhost:5103/index.html"&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
From here, we can access the files directly on disk, but it's a bit of hand-wavy issue about &lt;i&gt;what directory&lt;/i&gt;&amp;nbsp;these files exist in to access them; If you run the project a few times, and move the files around, it's difficult to pin down the exact spot that a relative path reads from.So for the sake of simplicity for this tutorial we're going to prepend all the files paths with the absolute path of the location. Yes. This works.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;"&gt;&lt;span style="font-size: 12px;"&gt;
FILE* f = fopen("&lt;some dis="" location="" on="" your=""&gt;\\plugin-port1\\plugin-port1\\test.raw" ,"rb");&lt;/some&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
Note you'll need to do this for both the texture, and two shader files that are&amp;nbsp;explicitly&amp;nbsp;referenced in the code.&lt;/div&gt;
&lt;div&gt;
&lt;br class="Apple-interchange-newline" /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Booyah&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
From there, Run the Compile,&amp;nbsp;httpd.py server,&amp;nbsp;Run and see the awesome:&lt;/div&gt;
&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-sn23toU00eo/T5mH9vFuvfI/AAAAAAAAAHA/4BgEXuDbf6U/s1600/results.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="193" src="http://1.bp.blogspot.com/-sn23toU00eo/T5mH9vFuvfI/AAAAAAAAAHA/4BgEXuDbf6U/s320/results.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The fruits of our labor. An OpenGL window will launch alongside of our chrome module. It renders and responds to input quite well. We've done the Waffle Burger proud!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;
When you run, note that you webpage will not respond in parallel with your window being opened. This is because our main thread that the browser runs on is actually running a&amp;nbsp;spin loop&amp;nbsp;for servicing the window popup, and not allowing any events for the page to be serviced. To fix this, you can do all of the window logic on another thread, and communicate back to the main thread with a producer-consumer FIFO, but that's a bit beyond the scope of this article.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: large;"&gt;Notes about the provided code&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;The&amp;nbsp;original&amp;nbsp;source referenced gluax.h to decode the .bmp image has been removed, as the gluax library is depriciated at best, so rather than adding complexity, I instead converted the test.bmp file to a test.raw, and modified the texture loading code in the init(..) function to simply memcpy load the raw data. I figure that has little and less to do with Native Client, so I omitted the code discussion for the article ;)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note, you can download the source code for this series @ my&amp;nbsp;&lt;a href="https://github.com/mainroach/nacl-examples"&gt;github repo.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The rest of the series -&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual.html"&gt;Part 1 : Setting up visual studio&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual_30.html"&gt;Part 2 : Using platform-specific code&amp;nbsp;&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual.html"&gt;Part 3 : Porting to Pepper&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual_07.html"&gt;Part 4 : Compile to NaCl&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find me here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;i style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i style="background-color: white; color: #333333; font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 19px; text-align: justify;"&gt;~Main&lt;/i&gt;&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/YdFsw0xrOWc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/4546158369853198306/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=4546158369853198306" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/4546158369853198306?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/4546158369853198306?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/YdFsw0xrOWc/porting-to-native-client-with-visual_30.html" title="Porting to Native Client with Visual Studio pt.2" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-3R3De08gL-o/T5molqvjccI/AAAAAAAAAHM/QjaOk78sKGs/s72-c/waflbug.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual_30.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkADRn89cSp7ImA9WhJaEU8.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-8466185453868867157</id><published>2012-04-26T08:33:00.000-07:00</published><updated>2012-10-01T14:59:37.169-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-01T14:59:37.169-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="debugging" /><title>Porting to Native Client with Visual Studio pt.1</title><content type="html">&lt;br /&gt;
&lt;b&gt;This article series shows you how to port to N&lt;/b&gt;&lt;b&gt;ative Client via a Chrome Trusted Plugin. This will allow you port your platform code over to Chrome's Pepper APIs while using Visual Studio for debugging.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #ee5555;"&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: large;"&gt;WARNING:&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
As of 10.1.2012, there's an official version of a &lt;a href="http://mainroach.blogspot.com/2012/10/official-nacl-vs2010-add-in-available.html"&gt;Visual Studio 2010 plugin&lt;/a&gt;. Only some subset of this article series is accurate, please see the official documentation at &lt;a href="http://www.blogger.com/www.gonacl.com"&gt;gonacl.com&lt;/a&gt; for more.&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Thus far, if you were a Native Client developer, your development process would look something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Compile your app against NaCl's GCC&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;Curse at all the problems of using the GCC tools&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;Modify your APIs to target the Pepper APIs&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;Throw furniture across the room while trying to printf debug all the API issues,&amp;nbsp;while at the same time overhauling your codebase to deal with the&amp;nbsp;nuances&amp;nbsp;of Pepper's Async APIs&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;Debug any&amp;nbsp;run time&amp;nbsp;issues that come with running in a webpage&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;Take up&amp;nbsp;alcoholism&amp;nbsp;as a professional sport because it makes your printf logs look 'perty'&lt;/li&gt;
&lt;/ol&gt;
&lt;/ol&gt;
&lt;br /&gt;
But this stops today! Today we learn about using Visual Studio and Chrome Plugins to develop your Native Client application.&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-10HRohUZyms/T5ldKbPvqdI/AAAAAAAAAG0/kc7T2G-x5yM/s1600/Crazy_Harry.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-10HRohUZyms/T5ldKbPvqdI/AAAAAAAAAG0/kc7T2G-x5yM/s320/Crazy_Harry.jpg" width="291" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Crazy Harry, also known as the patron saint of plugin development.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Chrome, Plugins, and Native Client&lt;/span&gt;&lt;br /&gt;
Officially, you should read the &lt;a href="http://www.chromium.org/nativeclient/getting-started/getting-started-background-and-basics"&gt;Basics of Chrome&lt;/a&gt;, it's a great read that's eye-opening for non-web developers. If you don't have the time, here's a condensed version:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Chrome is a web-browser&lt;/li&gt;
&lt;li&gt;Chrome provides the ability for developers to create Plugins to extend functionality&lt;/li&gt;
&lt;li&gt;Chrome provides a safe, secure API for plugins called Pepper (PPAPI).&amp;nbsp;Plugins target the PPAPI to interact with Chrome, and the sandbox safely&lt;/li&gt;
&lt;li&gt;Native Client is a plugin that's &lt;i&gt;built into&lt;/i&gt;&amp;nbsp;Chrome, which loads external assemblies and allows them to interact with the Pepper APIs in a safe, secure fashion.&lt;/li&gt;
&lt;/ol&gt;
The important take-away from the list above is that Native Client is a Chrome Plugin, meaning that they both target the Pepper APIs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What this article series talks about, is how to port to native client by first developing as a Chrome Plugin, so that you can gradually migrate over to the Pepper APIs.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;b&gt;&lt;u&gt;Oh, and did I mention you get the full power of visual studio?&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
You can read the&amp;nbsp;&lt;a href="http://www.chromium.org/developers/design-documents/pepper-plugin-implementation"&gt;official documentation&lt;/a&gt;&amp;nbsp;on developing trusted plugins, which, honestly, melts my brain; so I've condensed the process into the steps below.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Grab the chromium source code&lt;/span&gt;&lt;br /&gt;
Before you can compile your plugin, you'll need to get the latest source code of Chrome (called chromium) to compile against. The source code includes the specific header files that your plugin will need to link against in order to operate correctly.&amp;nbsp;Note that when you pull down chromium, the root folder is "src" so it's best if you create a parent folder "chromium" to pull it into.&lt;br /&gt;
&lt;br /&gt;
Using &lt;a href="http://git-scm.com/"&gt;GIT &lt;/a&gt;you can grab the top of the tree here:&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span class="pln"&gt;git clone http&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;:&lt;/span&gt;&lt;span class="com" style="color: #880000;"&gt;//git.chromium.org/chromium/src.git&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
If you're new to using GIT as your source control solution, I highly recommend using &lt;a href="http://code.google.com/p/tortoisegit/"&gt;TortiseGit&lt;/a&gt;, it fits really well into the Windows IDE, and is free.&lt;br /&gt;
&lt;br /&gt;
This is going to take &lt;i&gt;a while&lt;/i&gt;, so you while that's working, continue forward with the next steps ;)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Grab the latest build of Chromium&lt;/span&gt;&lt;br /&gt;
To properly debug, you'll need a build of Chromium that matches the headers from the source repo. You can choose to &lt;a href="http://www.chromium.org/developers/how-tos/build-instructions-windows"&gt;build it yourself&lt;/a&gt;, if you've got a few hours and a high tolerance for pain.&lt;br /&gt;
&lt;br /&gt;
If you'd like to skip that step (which I recommend), you can download the nighly builds from the &lt;a href="http://chromium-build.appspot.com/p/chromium/console"&gt;chromium build repository&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Clicking on "builds:&amp;nbsp;continuous" and choosing "win" as a sub-folder lists all the archived builds of chromium that you can use directly. (or you could click &lt;a href="http://commondatastorage.googleapis.com/chromium-browser-continuous/index.html?path=Win/"&gt;here &lt;/a&gt;for simplicity ;) Scrolling to the bottom of the page gives you the latest successful build folder, contained within is the&amp;nbsp;binaries&amp;nbsp;and symbols for that build.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-NEl31OLC0Z4/T5lLIh3_7LI/AAAAAAAAAF8/u5V1d2hniXY/s1600/files.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="189" src="http://1.bp.blogspot.com/-NEl31OLC0Z4/T5lLIh3_7LI/AAAAAAAAAF8/u5V1d2hniXY/s320/files.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;You only need the chrome-win32-syms.zip (symbols) and chrome-32.zip (binaries) from this directory&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
I unzip the contents of these files in a folder named "chrome_build" so that it's easy for me to remember which build i'm running ;)&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;aside&lt;/i&gt;&amp;nbsp;- Yes, for Windows, there's only a 32 bit version. That's a&amp;nbsp;separate&amp;nbsp;discussion; just download it, use it, and move on.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Grabbing the Native Client SDK&lt;/span&gt;&lt;br /&gt;
Visit &lt;a href="http://gonacl.com/"&gt;gonacl.com&lt;/a&gt; and click on the 'sdk' link on the left hand side of the page. Follow the instructions to download and install the latest version of the sdk, and update to the latest version of pepper_*&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Creating the windows project&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Start a new Visual Studio project&lt;/li&gt;
&lt;li&gt;Select Win32 Project&lt;/li&gt;
&lt;li&gt;When the win32 application wizard starts up, select "Application settings" and choose "DLL" with "Empty Project"&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-hkt0VWqsmng/T5lUf_GRruI/AAAAAAAAAGo/XwoneYLNI9I/s1600/newproj.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="190" src="http://1.bp.blogspot.com/-hkt0VWqsmng/T5lUf_GRruI/AAAAAAAAAGo/XwoneYLNI9I/s320/newproj.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Continue on to create the project.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Adding the source files&lt;/b&gt;&lt;br /&gt;
Add a new "main.cpp" file to your solution, in this file, we'll write the base code for our Pepper plugin that will interact with Chrome. But rather than typing all that out by hand, we're going to cheat, and use some existing code from the Native Client SDK.&amp;nbsp;Once it's downloaded and installed, copy-paste the contents of this example NaCl file into your new main.cpp&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;(NaCl_SDK_root)\pepper_18\examples\hello_world_newlib\hello_world.c&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
In addition, you'll also need an html file to host your NaCl module from.&lt;br /&gt;
Continue on and add a new "index.html" file to your solution. &lt;i&gt;Note&lt;/i&gt;,&amp;nbsp;depending on what version of visual studio you have, creating an html file will be under the 'web'&amp;nbsp;subcategory&amp;nbsp;of the 'add new item' dialog.&lt;br /&gt;
Copy-paste the contents of this example NaCl file into your new index.html&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;(NaCl_SDK_root)\pepper_18\examples\hello_world_newlib\hello_world.html&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
NOTE - For you advanced users out there, you most likely have noticed that you could have simply added the hello_world files to the project as remote references, rather than copy-pasting and all that jazz; I've presented the above method for the sake of conciseness; This makes it easier to hack on the files w/o ruining the files in your examples folder.&lt;br /&gt;
&lt;span style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; white-space: pre;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-size: large;"&gt;Setting the visual studio project properties&lt;/span&gt;&lt;br /&gt;
This is where the dark magic comes in. Right clicking on your project, select&amp;nbsp;Properties, and fill in the following line-items.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;

C/C++ &amp;gt; General &amp;gt;Additional Include Directories :&lt;/b&gt;&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;(Some Path)\chromium\src\&lt;/span&gt;&lt;/pre&gt;
This is the path where you downloaded your chromium source code to.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;

Debugging &amp;gt; Command:&lt;/b&gt;&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;(Some other Path)\chrome_build\chrome-win32\chrome.exe&lt;/span&gt;&lt;/pre&gt;
This is the path to your downloaded build of Chromium.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;

Debugging &amp;gt; Command Arguments:&lt;/b&gt;&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;--single-process --register-pepper-plugins=$(TargetPath);application/x-nacl "localhost:5103/index.html"&lt;/span&gt;&lt;/pre&gt;
this... requires some&amp;nbsp;explanation...&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;--single-process&lt;/b&gt; - tells chrome to run the tabs in a single process. As the background document states, chrome is a multi-process browser, and each tab is opened in a&amp;nbsp;separate&amp;nbsp;process. Since our goal is to debug the open tab w/o going insane, we specify this command line argument so that we can properly attach to the running instance of Chromium to debug it. In addition, it's worth pointing out that this turns off the&amp;nbsp;sand boxing&amp;nbsp;in chrome. As such, I don't recommend running your main chrome.exe with this flag due to potential security issues.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;--register-pepper-plugins=$(TargetPath);application/x-nacl -&lt;/b&gt;&amp;nbsp;This is a debug flag that tells Chrome to load the specific plugin automatically. Normally a plugin would have to be distributed and installed through the Chrome&amp;nbsp;Extensions&amp;nbsp;UI, which would generally kill your productivity turnaround. In addition the &lt;b&gt;application/x-nacl&lt;/b&gt;&amp;nbsp;flag tells chrome to associate the usage of this plugin with any Mime type matching "application/x-nacl". So once the webpage find a mime object matching that string, it will&amp;nbsp;invoke&amp;nbsp;our plugin properly&lt;/li&gt;
&lt;li&gt;&lt;b&gt;localhost:5103/index.html&lt;/b&gt;&amp;nbsp;- This ending parameter tells Chrome what URL to load when it launches. Why are we pointing it to localhost? let's chat about that a bit more.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;











&lt;b&gt;The HTML and&amp;nbsp;Web-service.&lt;/b&gt;&lt;/h3&gt;
As noted before, we're working with a web-technology; that is, native client modules must be&amp;nbsp;served&amp;nbsp;from a&amp;nbsp;web-server&amp;nbsp;to operate correctly. This is generally a 'pick your&amp;nbsp;poison' setup with tons of options to create&amp;nbsp;web-servers&amp;nbsp;on your windows desktop.&amp;nbsp;For&amp;nbsp;simplicity's&amp;nbsp;sake, the Native Client SDK comes with some easy uses for this and provides a single-file python based&amp;nbsp;web-server to use for showing off the examples. You can find this&amp;nbsp;web-server&amp;nbsp;here:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow: auto; padding: 0.5em;"&gt;&lt;span style="background-color: transparent;"&gt;(NaCl_SDK_root)\pepper_18\examples\httpd.py&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
The httpd.py script will launch a webserver who's root is the directory it's launched from. As such, we need to copy the file to the same location as the index.html file you created above (or the location of your vcxproj, which should be the same)&lt;br /&gt;
&lt;i&gt;Note, make sure python is&amp;nbsp;properly&amp;nbsp;added to your path, otherwise running httpd.py could be problematic.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
Once placed, feel free to launch the webserver and minimize the window.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;caveat&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
At the time of this writing, this python script contains a check to ensure that the webserver is running from the examples folder. This makes the script useless for our purposes, so I suggest that you remove this check by simply adding a 'return' at the beginning of the 'SanityCheckDirectory()' function.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-4zGsJA5DFyY/T5lNaXRnoCI/AAAAAAAAAGE/T6ekezUbbnc/s1600/return.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="84" src="http://1.bp.blogspot.com/-4zGsJA5DFyY/T5lNaXRnoCI/AAAAAAAAAGE/T6ekezUbbnc/s320/return.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Simply add a 'return' to this function, and you can use the httpd.py module anywhere as a quick, easy local&amp;nbsp;web-server. Note, that if you're new to Python, make sure that you've indented 'return' in the proper tabs as the rest of the function.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Compiling and debugging.&lt;/span&gt;
&lt;br /&gt;
In visual studio, Choose "Debug &amp;gt; Start Debugging" (or just hit F5). If all went well, Visual studio should fire up an instance of chromium; load the page, and pop up an alert.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-GnQorg2cFtw/T5lRdxm-eAI/AAAAAAAAAGQ/dIsA7LDy0j0/s1600/hw_nlib.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="137" src="http://4.bp.blogspot.com/-GnQorg2cFtw/T5lRdxm-eAI/AAAAAAAAAGQ/dIsA7LDy0j0/s320/hw_nlib.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
Now, this is where the magic happens; If you place a&amp;nbsp;break point&amp;nbsp;inside visual studio in the &lt;i&gt;Instance_DidCreate&lt;/i&gt;&amp;nbsp;function (line 46ish) then it'll fire before the window pops up the alert box. &amp;nbsp;This function will send a message from the plugin to the HTML page to alert. Continue past the&amp;nbsp;break-point&amp;nbsp;to see the HTML page pope up the alert.&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-nNGYBKdg_U0/T5lR_ssx7ZI/AAAAAAAAAGY/kgrtz6Hizgw/s1600/breakpoint.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="176" src="http://2.bp.blogspot.com/-nNGYBKdg_U0/T5lR_ssx7ZI/AAAAAAAAAGY/kgrtz6Hizgw/s320/breakpoint.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;YES! A&amp;nbsp;break point! My IDE color scheme is &lt;a href="http://www.codinghorror.com/blog/files/exported-font-and-colors-zenburn.zip"&gt;Zenburn&lt;/a&gt;, thanks to&amp;nbsp;&lt;a href="http://www.codinghorror.com/blog/2006/09/is-your-ide-hot-or-not.html"&gt;Jeff Atwood&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Want to go deeper? If you pop open the Debugging Tools inside of chrome, you can set a&amp;nbsp;break point&amp;nbsp;in the HTML's &lt;i&gt;handleMessage &lt;/i&gt;function (line 24ish) which is responsible for popping up the alert. If you haven't stopped visual studio yet, then simply hit "RELOAD" in the webpage and you'll hit the javascript&amp;nbsp;break point.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-sIQBu13H2iw/T5lTEt0ciII/AAAAAAAAAGg/Smour8VuLtE/s1600/bkpt2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="145" src="http://4.bp.blogspot.com/-sIQBu13H2iw/T5lTEt0ciII/AAAAAAAAAGg/Smour8VuLtE/s320/bkpt2.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;
AND that's all for now! You can now create a trusted plugin for chrome, and have it communicate back and forth with the html in the page.&amp;nbsp;Note that what we haven't done here is talk about NaCl; All we've done is create a trusted plugin that targets the Pepper APIs&lt;br /&gt;
&lt;br /&gt;
Also Mad props to NaCl SDK Lead &lt;a href="https://plus.google.com/u/0/112865137669945827064/posts"&gt;Noel Allen&lt;/a&gt; for helping plot all the tricky bits out.&lt;br /&gt;
&lt;br /&gt;
Note, you can download the source code for this series @ my &lt;a href="https://github.com/mainroach/nacl-examples"&gt;github repo.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The rest of the series -&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual.html"&gt;Part 1 : Setting up visual studio&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual_30.html"&gt;Part 2 : Using platform-specific code&amp;nbsp;&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual.html"&gt;Part 3 : Porting to Pepper&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;a href="http://mainroach.blogspot.com/2012/05/porting-to-native-client-with-visual_07.html"&gt;Part 4 : Compile to NaCl&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;
&lt;small style="text-align: -webkit-center;"&gt;&lt;i&gt;&lt;br class="Apple-interchange-newline" /&gt;You can find me here:&lt;/i&gt;&lt;/small&gt;&lt;br style="text-align: -webkit-center;" /&gt;&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.linkedin.com/in/duhroach" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" /&gt;&lt;/a&gt;&lt;span style="text-align: -webkit-center;"&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://twitter.com/#!/duhroach" style="text-align: -webkit-center;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;br /&gt;
~Main&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/uGIkYmm_WcI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/8466185453868867157/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=8466185453868867157" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/8466185453868867157?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/8466185453868867157?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/uGIkYmm_WcI/porting-to-native-client-with-visual.html" title="Porting to Native Client with Visual Studio pt.1" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-10HRohUZyms/T5ldKbPvqdI/AAAAAAAAAG0/kc7T2G-x5yM/s72-c/Crazy_Harry.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/04/porting-to-native-client-with-visual.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YHQnc4eCp7ImA9WhVWEko.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-5035697024982718678</id><published>2012-04-24T07:52:00.000-07:00</published><updated>2012-04-24T07:52:13.930-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-24T07:52:13.930-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opengles2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><category scheme="http://www.blogger.com/atom/ns#" term="graphics" /><category scheme="http://www.blogger.com/atom/ns#" term="NaCl" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="debugging" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome Web Store" /><title>NaCl and Blacklisted GPU Drivers</title><content type="html">With the new flood of Native Client games coming out, 3D is hitting the web more, and more. One of the biggest issues with 3D on the web is the limiting nature of &lt;i&gt;blacklisted drivers&lt;/i&gt;. Looking at the crash logs that come through, incorrectly handling blacklisting crashes accounts for the #1 crash report from NaCl applications lately. As such, let's take a look at how to properly respond to this issue.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-NA6-3uFW8GQ/T5YMeCCbodI/AAAAAAAAAF0/h9X8pIbXPq0/s1600/to-do-list-nothing.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-NA6-3uFW8GQ/T5YMeCCbodI/AAAAAAAAAF0/h9X8pIbXPq0/s320/to-do-list-nothing.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Why do we have GPU Driver Blacklisting&lt;/b&gt;&lt;br /&gt;
GPU API can be malicious; more specifically, adding GPU APIs to a web browser opens a door to the drive-by-web that we never had access to before,&amp;nbsp;specifically, we're talking to &lt;i&gt;hardware;&lt;/i&gt;&amp;nbsp;And if you've ever delt with hardware before, you know there's edge-cases all over the place that could be exploited incorrectly.&amp;nbsp;Web needs to walk the line between&amp;nbsp;functionality&amp;nbsp;and safety, we need a modern web with advanced, deep interaction, and there's a massive majority of hardware out there that can handle it. The goal then, is to find a line that provides the advanced featuresets of the modern web, and the safety of it as well.&lt;br /&gt;
&lt;br /&gt;
This is where we introduce the concept of a &lt;b&gt;GPU Driver Blacklist.&lt;/b&gt;&amp;nbsp;Some drivers have&amp;nbsp;vulnerabilities, or direct stability issues that result in bad end-user experiences, while most of the time, we can work with the hardware vendors to fix the issues, sometimes is not that easy, and as such, we have to restrict that specific driver from running inside of the browser.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;NOTE&lt;/b&gt;&amp;nbsp;that we restrict the driver, not the GPU ! The GPU, like other hardware, is usually a straightforward device, which bends to the will of it's driver based overload. The device is the one we need to worry about.&lt;br /&gt;
&lt;br /&gt;
Now, it's very important to understand that &lt;a href="http://www.khronos.org/webgl/"&gt;WebGL &lt;/a&gt;(via javascript) and OpenGL ES2 (via Native Client) both use the same back-end inside of chrome; As such, when discussing black-listing, you can use the terms pretty&amp;nbsp;interchangeably.&lt;br /&gt;
&lt;br /&gt;
Khronos keeps a general description of&lt;a href="http://www.khronos.org/webgl/wiki/BlacklistsAndWhitelists"&gt; blacklisted devices&lt;/a&gt;, which is good to know. (The&amp;nbsp;&lt;a href="http://src.chromium.org/viewvc/chrome/trunk/deps/gpu/software_rendering_list/software_rendering_list.json"&gt;chrome list&lt;/a&gt; is a bit more&amp;nbsp;informative)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Restricting via the chrome web store&lt;/b&gt;&lt;br /&gt;
Currently, Native Client applications must be installed through the &lt;a href="https://chrome.google.com/webstore/category/home"&gt;Chrome Web Store&lt;/a&gt; to work properly.&lt;br /&gt;
CWS provides a barrier flag, which will restrict users from installing your NaCl application if their device is blacklisted.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px;"&gt;"requirements": {
  "3D": {
    "features": [&lt;b&gt;"webgl"&lt;/b&gt;]
  }
}
&lt;/pre&gt;
&lt;br /&gt;
Note that there is some&amp;nbsp;nuances&amp;nbsp;here that CWS still needs to fix; If the device is blacklisted, and the app defines the above flag:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The app won't show up on the puzzle wall&lt;/li&gt;
&lt;li&gt;The app WILL show up in a direct search&lt;/li&gt;
&lt;li&gt;The app WILL show up if you link to it directly&lt;/li&gt;
&lt;li&gt;When you reach the install page, user will see "This application is not supported on this computer. Installation has been disabled"&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
The intent is that CWS should filter out games that users can't play so that they don't leave bad feedback to the developer.
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Detecting Blacklist via WebGL&lt;/b&gt;&lt;br /&gt;
If the user can install from CWS (or if you're a hosted app, just browse to your URL), you'll need to catch their issues directly at your webpage. Since WebGL and NaCl share the same rendering path; you can detect for a blacklisted device in javascript before even loading the NaCl module:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px;"&gt;function initGLTest(size) {
  var canvas = document.createElement('canvas');
  var gl = canvas.getContext('webgl') ||
           canvas.getContext('experimental-webgl');

  if (gl) {
    return true;
  }

  return false;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
You should be doing this test before you load your nacl module; More specifically, you should add the EMBED tag to the DOM only after the above test as been successful.&lt;br /&gt;
&lt;br /&gt;
Yes, that means that there should be some series of startup tests you need to perform before actually adding the nacl module to the webpage. You should check my previous post on&amp;nbsp;&lt;a href="http://mainroach.blogspot.com/2011/11/nacl-detecting-user-setup-problems.html"&gt;detecting user setup problems&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Detecting Blacklist via NaCl&lt;/b&gt;&lt;br /&gt;
If the above WebGL test has passed; chances are that your driver is OK, and you should be good-to-go with creating your NaCl OpenGLES2.0 GLContext. &amp;nbsp;If creating your context does fail, please try a simpler version of context create to ensure that you're not incorrectly asking for features that the hardware doesn't support. Chances are, you're asking for a resolution, or init feature which is causing the problem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Test your blacklist response&lt;/b&gt;&lt;br /&gt;
You can test your blacklist handling by running chrome with the following flags:

With these, you can run through all the above scenarios, and test how you handle things.&lt;br /&gt;
&lt;br /&gt;
&lt;ul style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;
&lt;li style="margin-left: 15px;"&gt;--disable-webgl&lt;/li&gt;
&lt;li style="margin-left: 15px;"&gt;--disable-pepper-3d-for-untrus&lt;wbr&gt;&lt;/wbr&gt;ted-use&lt;/li&gt;
&lt;li style="margin-left: 15px;"&gt;--disable-gl-multisampling&lt;/li&gt;
&lt;li style="margin-left: 15px;"&gt;--disable-accelerated-composit&lt;wbr&gt;&lt;/wbr&gt;ing&lt;/li&gt;
&lt;li style="margin-left: 15px;"&gt;--disable-accelerated-2d-canva&lt;wbr&gt;&lt;/wbr&gt;s&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;What to do when you've detected a blacklist response&lt;/b&gt;&lt;br /&gt;
Firstly, thank the user for using your application. &amp;nbsp;;)&lt;br /&gt;
Secondly, alert the user of the issue, and direct them to update their graphics drivers to a newer version.&lt;br /&gt;
Chrome provides a &lt;a href="http://support.google.com/chrome/bin/answer.py?hl=en&amp;amp;answer=1202946"&gt;simple page&lt;/a&gt; describing how to do updates, which you should most likely direct your users to in such a case that you've found a blacklist error.&lt;br /&gt;
Thirdly, if that doesn't work,&amp;nbsp;humbly&amp;nbsp;apologize to your user about the situation, and try best to explain the reason for the problem. The intent here is that users shouldn't respond to your application with bad ratings because they have blacklisted hardware; You'd be amazed how far an apology goes to help with this.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Other tricky things&lt;/b&gt;&lt;br /&gt;
-Blacklisted drivers on macs are especially tricky to work with; Apple owns distribution of those drivers, and often distributes them at a seperate frequency than the PC / Linux branches. So it's difficult (nay, impossible sometimes) to direct the user to update their drivers on these devices.&lt;br /&gt;
&lt;br /&gt;
-Make sure you detect feature sets as well; you need to properly test that the GPU supports the specific features your 3D app is using. For example, does this GPU support 4096 textures? Most of these tests can be done in webGL, before you even load your nacl module, but they are critical to test for, as hardware is&amp;nbsp;heterogeneous, and thus your application needs to respond properly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, armed with this information, there should be no reason to see any more blacklist crashes coming through Google's crash logs. Right? Good. Because otherwise, I have to send the&lt;a href="http://www.penny-arcade.com/comic/2006/04/10"&gt; fear engine&lt;/a&gt; after you, or if he's booked, &lt;a href="http://www.penny-arcade.com/comic/2008/03/21"&gt;Deep Crow&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
~Main&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/_lm9ltK2QMU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/5035697024982718678/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=5035697024982718678" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/5035697024982718678?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/5035697024982718678?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/_lm9ltK2QMU/nacl-and-blacklisted-gpu-drivers.html" title="NaCl and Blacklisted GPU Drivers" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-NA6-3uFW8GQ/T5YMeCCbodI/AAAAAAAAAF0/h9X8pIbXPq0/s72-c/to-do-list-nothing.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/04/nacl-and-blacklisted-gpu-drivers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UEQHo4fSp7ImA9WhVXEUg.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-8591988172542208885</id><published>2012-04-07T08:04:00.000-07:00</published><updated>2012-04-11T06:33:21.435-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-11T06:33:21.435-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="memory" /><category scheme="http://www.blogger.com/atom/ns#" term="compression" /><title>Your texture compression is not enough</title><content type="html">I've been pitching my DXT talk to GDC since 2010, having it getting into various forms of acceptance, and then having to drop out due to mandatory overtime, or a game shipping or whatever. So in 2012, I was super pumped to present some of my research to the masses.&lt;br /&gt;
&lt;br /&gt;
In general, the point of my talk was to get people thinking about texture compression in a &lt;i&gt;different &lt;/i&gt;way. Firstly to admit that with modern hardware and consoles, DXT is a bit dated if you're simply just coping it directly to the GPU. Secondly to publicize a different idea than the &lt;a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;ved=0CCcQFjAA&amp;url=http%3A%2F%2Fsoftware.intel.com%2Ffile%2F17248%2F&amp;ei=PFaAT_rzEaKjiQLBibm7Aw&amp;usg=AFQjCNFGHAJPUypa6QuqYT4EHadMqFnchQ&amp;sig2=dOdRhlFh6H_Z61szs-1q9Q"&gt;IDTech5 research&lt;/a&gt;, which is generally presented as the premier way to deal with texture streaming issues.&lt;br /&gt;
The gist of the talk is "Here's a bunch of interesting ways to molest your texture data for better compression footprint; but in reality, you should just use &lt;a href="http://code.google.com/p/crunch/"&gt;CRUNCH&lt;/a&gt;"&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-tvejXCI_Ea0/T4BSqfgExBI/AAAAAAAAAE4/e31TzAOab74/s1600/Lena.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="320" src="http://4.bp.blogspot.com/-tvejXCI_Ea0/T4BSqfgExBI/AAAAAAAAAE4/e31TzAOab74/s320/Lena.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;font size="2"&gt;&lt;i&gt;The famous &lt;a href="http://en.wikipedia.org/wiki/Lenna"&gt;LENA image&lt;/a&gt;; Generally regarded as the cornerstone of texture compression test images.&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As a general graphics programmer, you should be following &lt;a href="http://cbloomrants.blogspot.com/"&gt;Charles Bloom's blog&lt;/a&gt;; If you ignore the more rant driven things, there's a great set of technical knowledge there; For example, Charles has been working on texture compression for a while now, and has &lt;a href="http://cbloomrants.blogspot.com/2008/11/11-18-08-dxtc.html"&gt;some great articles on it&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After my GDC talk (&lt;a href="http://www.youtube.com/watch?v=7bJ-D1xXEeg"&gt;video &lt;/a&gt;| &lt;a href="http://mainroach.appspot.com/docs/DUEX_CLM_GDC2012.pdf"&gt;slides&lt;/a&gt;) enough people connected the dots, and brought it to Charles' attention:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"&lt;i&gt;I've been sent this GDC talk a few times now, so I will write some notes about it. (BTW thanks to all who sent it; I don't really follow game dev news much, so I rely on you all to tell me when there's something interesting I should know about).&lt;/i&gt;"&lt;/blockquote&gt;&lt;br /&gt;
Charles is a smart cat. He's a top tier programmer with a great analytical sense; and he's also the top 10% when it comes to texture compression, so most of the things I talked about were old-hat to him; Which was good, because it means I'm not crazy. For the rest of the 90% who aren't on the cutting edge, and for the most part, the games industry as a whole, compression is a dark and spooky art.  I was amazed when talking to developers on the show floor of GDC, how many people had no idea what LZMA was.&lt;br /&gt;
&lt;br /&gt;
CBloom brought up &lt;a href="http://cbloomrants.blogspot.com/2012/03/03-27-12-dxt-is-not-enough.html"&gt;some great points about my talk&lt;/a&gt; and I figured it would be worth sharing my thoughts on his thoughts in a recursive sort of way.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"&lt;i&gt;whenever you are doing these things you need to consider the memory use and processor use tradeoffs&lt;/i&gt;"&lt;/blockquote&gt;&lt;br /&gt;
I completely agree, and tried to frame the talk around this premise starting at slide 3. When evaluating any software for inclusion of a larger system, you should constantly &lt;a href="http://mainroach.blogspot.com/2009/10/think-triangles-not-circles.html"&gt;evaluate the full suite of tradeoffs&lt;/a&gt; that you're making. Especially with texture compression, which has so many separate vectors for success. &lt;br /&gt;
&lt;br /&gt;
A perfect example of this manifested itself right after my live GDC talk: some of the engineers from AMD came up and quickly pressed me about why I wasn't doing texture decoding on the GPU. My response was to avoid this type of work;  Most graphics intensive games keep their GPUs maxed out for high-performance, I'd hate to have to balance that against doing texture decompression as well  (and if you're not graphics intensive, you generally don't have enough texture assets to make this a problem anyhow...). &lt;br /&gt;
In addition, this is only available on higher end hardware; Most game developers care about reach as much as they do 'splash' so you can't ignore the fact that there's still a huge chunk of GPUs out there (laptops mostly) that can't do the fancy DX11 compute shaders. Decoding on the CPU allows a great reach of hardware. Of course, this is my use-case evaluation; On their end it makes loads of sense to use GPU decode. Again, you have to consider all the trade offs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;"&lt;i&gt; Zip is ancient and has a tiny window, there's no reason to use zip. If you just use a better back end, most of what he does next is irrelevant.&lt;/i&gt;"&lt;/blockquote&gt;&lt;br /&gt;
I agree..kinda! Firstly, there's still lots of studios using GZIP variants; Blizzard's &lt;a href="http://en.wikipedia.org/wiki/MPQ"&gt;MOPAQ &lt;/a&gt;format finally introduced LZMA with Starcraft 2. (Although IIRC, WoW hadn't made the switch yet?) It comes back down to lack of technical knowledge of the games developer; throwing things in a zip format 'just works' and most people call it a day. If you want confirmation of this, check out your games install data on your smartphone.. &lt;br /&gt;
&lt;br /&gt;
I wouldn't say that switching to a better archive compressor makes the rest of the talk irrelevant though; The hope is that you can keep your textures in memory, hyper compressed, and decompress on demand. And that this whole process would be a smaller footprint, with a faster decompression speed than if you were using an archive format directly.&lt;br /&gt;
&lt;br /&gt;
Slide 5 of my talk covers this: Most level archives include data that's only needed at load time, rather than at runtime; As such, keeping the full archive around, or having to parse to different sections of the disk to fetch just texture data is less than ideal. Switching to a compressor that has a better memory footprint doesn't mean you're going to get better decompression speeds.&lt;br /&gt;
&lt;br /&gt;
LZMA is a great algorithm for compression; Where LZMA fails though, is when you try to do run time decompression of texture assets for streaming; In 2008 a few groups at Microsoft Games were trying to make a runtime decompressor for LZMA, and couldn't get anywhere close to 256 megatexels/sec . Again, it comes out to evaluating your options to find the proper solution for your project; maybe the size of LZMA beats out the decompression speed for some projects? Or was it just how the decompressor was abusing the XBOX360's L2 Cache? Or maybe there's been great advances in LZMA decompression speeds lately? As always, YMMV!&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;i&gt;The only real idea in the talk is going to 8x8 blocks. That is in fact a valid thing to do, but here the rigor of the talk completely falls apart, and instead we get "look at this blurry slide in a terrible lighting environment, can you see the loss?"&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;
I agree, the lighting in that video was horrible. You can see close-ups of my side-by-side textures in my &lt;a href="http://mainroach.appspot.com/docs/DUEX_CLM_GDC2012.pdf"&gt;slides&lt;/a&gt;. Note  there's some introduced noise in a few of the source images from the process of converting the true side-by-side to JPG in order to put it in a talk. As such, you should focus on what the expanded blocks algorithm does, and note the blocking and quantization artifacts first. The parrot shows some good overal results; You start seeing bad quantization around the gradients, but the noise in the feathers goes mostly un-noticed; You can see more problems in the picture of the girl; Especially in the closeup. The game-texture has an interesting result, in that it's really difficult to see the overall compression artifacts. Most game textures have lots of noise, and are generally blurred out due to modern texture filtering in 3D scenes. In reality, this lets your texture compression algorithm cheat: Who cares about PSNR when you're getting chased by a guy with a sword?&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;i&gt;Any time you start introducing loss you have to ask : how does this loss I'm injecting compare to other ways I could reduce bitrate and increase loss?&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;
We have reached quorum! This is especially true when evaluating different texture compressors against different texture types. For example, the algorithm I presented didn't do as well with normal maps, but chewed through AO and specular maps like &lt;a href="http://simplyrecipes.com/recipes/baklava/"&gt;buttered bakliva&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Apparently enough people watched the video, and passed it along to cbloom for comment; which prompted him to write a larger blog post; and a followup post which presented &lt;a href="http://cbloomrants.blogspot.com/2012/04/04-05-12-dxt-is-not-enough-part-2.html"&gt;even more ideas&lt;/a&gt; about the future of custom texture compression.&lt;br /&gt;
&lt;br /&gt;
So it appears people are listening, and thinking, talking, and ranting about texture compression for games.&lt;br /&gt;
&lt;br /&gt;
Mission Accomplished.
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;center&gt;
&lt;small&gt;&lt;i&gt;You can find me here:&lt;/i&gt;&lt;/small&gt;&lt;br /&gt;
&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts"&gt;&lt;img border="0"  src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;
&lt;a href="http://www.linkedin.com/in/duhroach"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" /&gt;&lt;/a&gt;
&lt;a href="https://twitter.com/#!/duhroach"&gt;&lt;img border="0"  src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/yjYlmfNbAxE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/8591988172542208885/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=8591988172542208885" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/8591988172542208885?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/8591988172542208885?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/yjYlmfNbAxE/your-texture-compression-is-not-enough.html" title="Your texture compression is not enough" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-tvejXCI_Ea0/T4BSqfgExBI/AAAAAAAAAE4/e31TzAOab74/s72-c/Lena.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/04/your-texture-compression-is-not-enough.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MER386fip7ImA9WhVQGU0.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-3085750362789924098</id><published>2012-04-03T07:16:00.001-07:00</published><updated>2012-04-08T09:10:06.116-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-08T09:10:06.116-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Native Client" /><title>Dynamic loading of code libraries with Native Client</title><content type="html">As of Pepper 17 Native Client supports dynamic loading of code libraries (A windows-based analogy would be "You can load .DLLs"). The Pepper 18 SDK came with an example code set (dlopen) that showed how to properly load the libraries via a few specific posix style calls. Proper documentation on how to link with GLIBC is missing however, so I thought I'd throw up a quick tutorial.&lt;br /&gt;
&lt;br /&gt;
Native Client comes with two C run time libraries, Newlib and GLIBC; If you come from a windows / Visual studio back-ground, this may be a bit jarring to think of "Multiple C run times!?" But fear not, there's a reason for it.&lt;br /&gt;
&lt;br /&gt;
Native Client support for dynamic loading is requires linking with GLIBC.  &lt;a href="http://www.gnu.org/software/libc/index.html"&gt;GLIBC &lt;/a&gt;is the GNU implementation of the POSIX standard runtime library for the C programming language comprising of a set of interdependent libraries including libc, libpthreads, libdl, and others.&lt;br /&gt;
&lt;br /&gt;
As such, before you can start dynamically loading assemblies, you need to compile your project with glibc.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-8_aspghKyiU/T3sGEuAyXpI/AAAAAAAAAEs/3fa2HYXsSfw/s1600/library.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="224" width="299" src="http://2.bp.blogspot.com/-8_aspghKyiU/T3sGEuAyXpI/AAAAAAAAAEs/3fa2HYXsSfw/s400/library.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 1. Compile your NaCl App using GLIBC&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The Native Client SDK ships with both GLIBC and Newlib versions of the GCC toolchain. All code used by your application must be built with either one or the other toolchain. &lt;u&gt;Code from these toolchains cannot be mixed&lt;/u&gt;. You must choose the GLIBC toolchain to use GLIBC and dynamic linking. &lt;br /&gt;
&lt;br /&gt;
On windows, you can find these folders:&lt;br /&gt;
&lt;i&gt;SDKROOT/pepper_18/toolchain/win_x86_glibc&lt;br /&gt;
SDKROOT/pepper_18/toolchain/win_x86_newlib&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
For Mac and Linux, the appropriate three letter marker replaces the "win" section of those libs.&lt;br /&gt;
&lt;br /&gt;
As a simple example, suppose you are working on 64-bit Windows, and that your application is implemented as a single C++ source module, &lt;i&gt;test.cpp&lt;/i&gt;. &lt;br /&gt;
&lt;br /&gt;
In this case you might compile your application for 64-bit and GLIBC as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;..\x86_64-nacl-g++.exe -Wall -m64 -fPIC -o test-x86_64.nexe test.cpp -ldl -lppapi -lppapi_cpp &lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Note that you'll find the x86_64-nacl-g++ file in the /bin folder.&lt;br /&gt;
These compiler flags are described in the gcc documentation, summarized here for convenience:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;-l&lt;i&gt;library&lt;/i&gt;: use the indicated library, as per C library naming conventions. For example, -ldl causes the application to use libdl.so, or libdl.a if libdl.so is not available.&lt;/li&gt;
&lt;li&gt;-f&lt;i&gt;PIC&lt;/i&gt;: Generate position-independent-code, required for all 64-bit modules and for 32-bit shared libraries.&lt;/li&gt;
&lt;li&gt;-Wall: Enable an optional set of compiler warnings&lt;/li&gt;
&lt;li&gt;-m32, -m64: Specify generation of 32-bit or 64-bit code, respectively&lt;/li&gt;
&lt;li&gt;-o: Specify the output file, e.g. test-x86_64.nexe&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;Step 2. Building a shared object&lt;/b&gt;&lt;br /&gt;
Now that you're compiling with GLIBC, you need to generate your .SO objects (an analogous version of a "Windows DLL") which will be loaded dynamically at runtime. Much like generation of the nexe, you'll compile this with GLIBC as well; the main difference is adding the -shared flag:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;..\x86_64-nacl-g++.exe -fPIC -Wall -m64 -shared -o testlib-x86_64.so testlib.cpp&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
This will generate &lt;i&gt;testlib-x86_64.so&lt;/i&gt; which an analogous version of a "Windows DLL"&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 3. Generate a manifest file&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When a dynamically loaded desktop application is launched, the operating system’s program loader determines the set of libraries it requires, reading explicit inter-module dependencies from executable file headers, and loads the libraries into the address space of a new process. Typically these libraries will have been installed on the system as a part of installing the application. Often the desktop application developer doesn’t know or think about the libraries required by the application, as these details are taken care of by the operating system.&lt;br /&gt;
&lt;br /&gt;
In Native Client, dynamic linking support can’t rely in the same way on the operating system or the local file system. Instead, the application developer is responsible for understanding the set of libraries required by an application, listing them in a native client manifest file(.nmf), and delivering these libraries along with your application, either serving them from a web server (for hosted applications) or bundling them as a part of a packaged Chrome Web Store application (for packaged applications). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 3a. Determining required assemblies&lt;/b&gt;&lt;br /&gt;
Now that you've generated a proper .so, you'll need to explicitly list the .so files in the manifest in order for the security system to authorize the content. Before we list the exact ones that you've compiled by hand (from step 2) we'll need to get a list of what runtime libraries are going to be required for this project to run.&lt;br /&gt;
&lt;br /&gt;
Given that you've produced the &lt;i&gt;test_64.nexe&lt;/i&gt; already; It's worth noting that this file also includes a bunch of headers that describe the contents of the file and additional information on how to use it. Using the Native Client version of the GCC&lt;i&gt;objdump&lt;/i&gt; command, we can use the -p option to examine the file’s headers, including the “Dynamic Section” that specifies dynamic library dependencies, as in this example output:&lt;br /&gt;
&lt;pre&gt;..\x86_64-nacl-objdump.exe -p test-x86_64.nexe 

test-x86_64.nexe:     file format elf64-nacl

Program Header:
  INTERP off    0x000008c0 vaddr 0x110008c0 paddr 0x110008c0 align 2**0
         filesz 0x00000019 memsz 0x00000019 flags r--
    LOAD off    0x00000140 vaddr 0x01000140 paddr 0x01000140 align 2**16
         filesz 0x00000780 memsz 0x00000780 flags r-x
    LOAD off    0x000008c0 vaddr 0x110008c0 paddr 0x110008c0 align 2**16
         filesz 0x00000314 memsz 0x00000314 flags r--
    ...

Dynamic Section:
 &lt;b&gt;&lt;u&gt; NEEDED               libdl.so.40b700e4&lt;/u&gt;&lt;/b&gt;
 &lt;b&gt;&lt;u&gt; NEEDED               libgcc_s.so.1&lt;/u&gt;&lt;/b&gt;
 &lt;b&gt;&lt;u&gt; NEEDED               libc.so.40b700e4&lt;/u&gt;&lt;/b&gt;
  INIT                 0x01000140
  FINI                 0x01000840
  HASH                 0x110008dc
    ...

Version References:
  required from libdl.so.40b700e4:
    0x0d696911 0x00 04 GLIBC_2.1
  required from libc.so.40b700e4:
    0x0d696910 0x00 03 GLIBC_2.0
  required from libgcc_s.so.1:
    0x0d696910 0x00 02 GLIBC_2.0
&lt;/pre&gt;&lt;br /&gt;
In the Dynamic Section we’ve highlighted three items marked NEEDED. These are three of the files you will need to include in your manifest file and distribute with your application. More specifically, this process will describe to you the proper runtime code that needs to be distributed with your application. To note, you'll also need to list your custom built .so files&lt;br /&gt;
&lt;br /&gt;
To get the full list of libraries, you need to compute the recursive closure of library dependencies, starting by using objdump on these files three files. &lt;br /&gt;
&lt;br /&gt;
To simplify things a little bit, the Native Client SDK includes a python script, create_nmf.py, that will attempt to generate a manifest file for you. Assuming you have python properly installed, and in your path, you can use create_nmf.py as follows:&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
python %(SDKROOT)/pepper_18/tools/create_nmf.py test-x86_32.nexe -L %&lt;br /&gt;
(SDKROOT)/pepper_18/toolchain/win_x86/x86_64-nacl/lib32/&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
will produce&lt;br /&gt;
&lt;pre&gt;{
  "files": {
    "libc.so.40b700e4": {
      "x86-32": {
        "url": "x86-32/libc.so.40b700e4"
      }
    },
    "libdl.so.40b700e4": {
      "x86-32": {
        "url": "x86-32/libdl.so.40b700e4"
      }
    },
    "libgcc_s.so.1": {
      "x86-32": {
        "url": "x86-32/libgcc_s.so.1"
      }
    },
    "main.nexe": {
      "x86-32": {
        "url": "test-x86_32.nexe"
      }
    }
  },
  "program": {
    "x86-32": {
      "url": "x86-32/runnable-ld.so"
    }
  }
}
&lt;/pre&gt;By default, create_nmf.py prints the NMF file contents to standard output. Notice we’ve passed it the -L option to specify a directory to search for dynamic libraries. Also note that create_nmf.py can only recognize explicit library dependencies, for example, those created with the -l option to GCC. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 3b. Adding custom assemblies&lt;/b&gt;&lt;br /&gt;
If your application uses dlopen() to load additional libraries, you must be sure these libraries are listed in your manifest file.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;"yourefilehere.so": {
      "x86-32": {
        "url": "x86-32/yourfilehere.so"
      }
    },
&lt;/pre&gt;The example manifest file above tells Native Client how to load a 32-bit “x86-32” version of your application, but it doesn’t say anything about x86-64 or ARM. &lt;b&gt;Make sure you build the proper 64 and 32 bit versions before deploying!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Note that one downside of using &lt;i&gt;create_nmf.py&lt;/i&gt; is that it blows away old changes you've made. So if you're using that app, and you have custom assemblies that need to be appended to your manifest, it may be worth forking the create_nmf.py script, and modify it to add in your custom assemblies at the end.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 4. Deploy your application for testing&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Your manifest file should now explicitly list all the executable code modules required by your application, including modules from your application, modules from the Native Client SDK or middleware systems used by your application. As a part of deploying your application, you must make all of these modules available for your application. &lt;br /&gt;
&lt;br /&gt;
You need to treat these .so files like any other resources. For instance, if you are a hosted application, you need them to be served off a web server; and for packaged apps, they need to be included in the .CRX file.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Opening shared libraries at runtime&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Native Client supports the a version of the POSIX standard dlopen() interface for opening libraries explicitly, after the application is already running. &lt;br /&gt;
&lt;br /&gt;
Note that dlopen() calls may cause a library download to occur, and will automatically load all libraries required by the named library. As dlopen() can potentially block, it must be called off the main thread. Calls from the main thread will always fail in current implementations of Native Client. &lt;br /&gt;
&lt;br /&gt;
We advise using a worker thread during initialization of your application to pre-load libraries asynchronously so they will be available when needed. As per the specification, subsequent calls to dlopen() will return the a handle to the previously loaded object. Note that calling dlclose() will close the library, and a following dlopen() call to the same path may cause another fetch to occur.&lt;br /&gt;
&lt;br /&gt;
Note that the DLOPEN example in the SDK properly shows how to do this process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
~Main
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;center&gt;
&lt;small&gt;&lt;i&gt;You can find me here:&lt;/i&gt;&lt;/small&gt;&lt;br /&gt;
&lt;a href="https://plus.google.com/u/0/105062545746290691206/posts"&gt;&lt;img border="0"  src="http://4.bp.blogspot.com/-WPhYnnk7k0w/T4G1SCZwbHI/AAAAAAAAAFE/qu8HNyDT51Q/s400/google_plus_32.png" /&gt;&lt;/a&gt;
&lt;a href="http://www.linkedin.com/in/duhroach"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-1gZ18X6ny0g/T4G1WOIPK6I/AAAAAAAAAFQ/L_qdrr1Xo9I/s400/linkedin_32.png" /&gt;&lt;/a&gt;
&lt;a href="https://twitter.com/#!/duhroach"&gt;&lt;img border="0"  src="http://1.bp.blogspot.com/-y9RzU7hTFR4/T4G1ZBf569I/AAAAAAAAAFc/NsGugxMph4g/s400/twitter_32.png" /&gt;&lt;/a&gt;
&lt;/center&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/XusALPytMP8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/3085750362789924098/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=3085750362789924098" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/3085750362789924098?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/3085750362789924098?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/XusALPytMP8/dynamic-loading-of-code-libraries-with.html" title="Dynamic loading of code libraries with Native Client" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-8_aspghKyiU/T3sGEuAyXpI/AAAAAAAAAEs/3fa2HYXsSfw/s72-c/library.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/04/dynamic-loading-of-code-libraries-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ECQXg-eyp7ImA9WhVQEUw.&quot;"><id>tag:blogger.com,1999:blog-1197137313991855034.post-681560619078589403</id><published>2012-03-30T06:54:00.000-07:00</published><updated>2012-03-30T06:54:20.653-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-30T06:54:20.653-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="debugging" /><title>Reporting errors from your web app</title><content type="html">One item that I got constant follow-up about from my&lt;a href="http://mainroach.blogspot.com/2012/03/native-client-gdc.html"&gt; GDC Talk&lt;/a&gt; on &lt;a href="http://www.youtube.com/watch?v=huXucPChX3g"&gt;Best Practices in Developing a Web Game&lt;/a&gt; was error reporting. So I thought I'd take a moment and talk a bit more about it.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-YEdMPbvnK9s/T3W6sCiKqEI/AAAAAAAAAEg/YZSRj2ZbC0w/s1600/279504720593749485_Hb6w6WP8_f.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="220" width="220" src="http://2.bp.blogspot.com/-YEdMPbvnK9s/T3W6sCiKqEI/AAAAAAAAAEg/YZSRj2ZbC0w/s400/279504720593749485_Hb6w6WP8_f.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Error Reporting from the field is a constant term of struggle for developers; It's a wierd mix of how to properly catch the problem, what data to collect, and then where to submit it back to so they can gather it and do something about it later. &lt;br /&gt;
&lt;br /&gt;
Once your application is out in the wild, errors will occur on users’ machines that you as a developer won’t have direct visibility to, and thus, have little or no chance of fixing. As such, it’s very useful to structure your JavaScript code to take advantage of various means to capture data when problems occur such that you can receive it and act accordingly. &lt;br /&gt;
&lt;br /&gt;
For more manual debugging, the Console API has &lt;a href="http://getfirebug.com/wiki/index.php/Console_API#console.trace.28.29"&gt;console.trace&lt;/a&gt; which will print out the presented content to the JavaScript console for viewing.&lt;br /&gt;
&lt;br /&gt;
For syntax and execution errors, standard JavaScript provides a hook for &lt;a href="https://developer.mozilla.org/en/DOM/window.onerror"&gt;window.onerror&lt;/a&gt; as a generic event for trapping all errors that happen on a page and provides the error string and line number of the error that happened. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://code.google.com/p/v8/"&gt;V8 &lt;/a&gt;is a JavaScript virtual machine powering most modern web browsers, and it provides a great API for capturing stack traces for you using &lt;a href="http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi"&gt;Error.captureStackTrace&lt;/a&gt;. For other browsers not using V8, you will have to manually capture your stack traces by inserting function tracking points and retrieving them during an event. &lt;a href="https://github.com/eriwen/javascript-stacktrace"&gt;Javascript Stack trace&lt;/a&gt; and &lt;a href="https://github.com/csnover/TraceKit"&gt;TraceKit &lt;/a&gt;are great utilities for manually creating and capturing a stack trace of function calls leading up to an error, or particular event.&lt;br /&gt;
&lt;br /&gt;
Besides direct JavaScript errors, there’s also a set of data you should be additionally concerned about, for instance another handy technique is to store important game-state information in a form such that when a crash, or other event occurs, the data is dumped out in a safe way for analysis. In addition other browser environment data like &lt;a href="http://www.html5rocks.com/en/tutorials/webperformance/basics/"&gt;window.performance&lt;/a&gt; might also be useful for getting app state information -- and &lt;a href="http://code.google.com/chrome/extensions/tabs.html#method-captureVisibleTab"&gt;chrome.tabs.captureVisibleTab()&lt;/a&gt; (for packaged applications) can give more detail about the problems at hand to help you debug a solution.&lt;br /&gt;
&lt;br /&gt;
Once you are able to catch and identify errors, the next step is to report them back to you, the developer, in some useful form to take action against. The two most popular versions of this are logging the error data to a database, and sending an e-mail to the developer.&lt;br /&gt;
&lt;a href="http://jserrlog.appspot.com/"&gt;jsErrLog &lt;/a&gt;is a great library that encapsulates error catching and automatic uploading to a database resource. Which is the exact service that  &lt;a href="http://jdrop.org/"&gt;jdrop &lt;/a&gt;provides, a place to store json data in the cloud environment.&lt;br /&gt;
&lt;br /&gt;
Some other points to consider:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Enable error reporting when your app is used offline, by storing error data locally then submitting a report once the app is back online.&lt;/li&gt;
&lt;li&gt;Take care that error reporting does not itself cause problems, for example by making repeated XMLHttpRequests, or failing because your app is offline.&lt;/li&gt;
&lt;li&gt;Ensure error messages displayed are appropriate to the user: be friendly, avoid technical language and never report API error codes directly.&lt;/li&gt;
&lt;li&gt;Whether or not you implement error reporting, it’s always good to provide feedback mechanisms so users can report bugs, suggest feature requests or make comments.&lt;/li&gt;
&lt;li&gt;Be unobtrusive.&lt;/li&gt;
&lt;li&gt;Respect your users’ privacy:&lt;/li&gt;
&lt;li&gt;Notify the user unobtrusively when your app reports errors.&lt;/li&gt;
&lt;li&gt;Ensure the user understands what data is reported – if possible, show them the actual data.&lt;/li&gt;
&lt;li&gt;Allow the user to opt out of error reporting – better still, ask them to opt in.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/TheWorkbench/~4/2ORQH1Z-6E8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mainroach.blogspot.com/feeds/681560619078589403/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1197137313991855034&amp;postID=681560619078589403" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/681560619078589403?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1197137313991855034/posts/default/681560619078589403?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheWorkbench/~3/2ORQH1Z-6E8/reporting-errors-from-your-web-app.html" title="Reporting errors from your web app" /><author><name>~Main</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-9WytnuV8qIc/T14NdaPd_9I/AAAAAAAAADk/mUZ0b7msJOA/s220/My%2BPics%2B%25281%2529.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-YEdMPbvnK9s/T3W6sCiKqEI/AAAAAAAAAEg/YZSRj2ZbC0w/s72-c/279504720593749485_Hb6w6WP8_f.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mainroach.blogspot.com/2012/03/reporting-errors-from-your-web-app.html</feedburner:origLink></entry></feed>
